Skip to content

fix(suppressions): end lines at \n only, with the shared line index - #1072

Merged
psteinroe merged 10 commits into
mainfrom
fix/suppressions-shared-line-index
Nov 9, 2026
Merged

psteinroe merged 10 commits into
mainfrom
fix/suppressions-shared-line-index

Conversation

@psteinroe

Copy link
Copy Markdown
Collaborator

Stacked on #1063.

The suppressions parser numbers lines with str::lines, which ends lines at \n (and drops the \r of a \r\n), but looks up their offsets and the lines of diagnostics in its own line index, which also ended a line at a lone \r. After a lone \r, the two disagree, and a line suppression points at the wrong text and doesn't apply to the line below it:

select '\r';
-- pgls-ignore lint
select 1; -- still reported

The parser now uses pgls_line_index::LineIndex, which ends lines at \n only, like str::lines, the language server and the WASM bindings. Its own line_index.rs is gone. LineIndex gets a Default (the index of an empty text), since Suppressions derives it.

This changes behaviour only for files with a lone \r: lines after it are numbered one lower than before, which is what editors that end lines at \n show too. \r\n and \n files are numbered as before.

Tests: a_lone_carriage_return_does_not_end_a_line checks that the suppression above applies and covers the comment's text; it fails without this change. line_breaks_and_wide_characters in pgls_line_index (#1063) pins the index's line numbers for \r\n, a lone \r and multi-byte characters. cargo test -p pgls_suppressions -p pgls_line_index, cargo clippy --workspace --all-targets -- -D warnings.

Merging with #1008: that stack also edits crates/pgls_suppressions/src/line_index.rs (line_for_offset with partition_point). Whichever merges second gets a modify/delete conflict there; keep the deletion, since the shared index already looks lines up with partition_point. parser.rs merges cleanly, and the Suppressions::default() it returns early works with the new Default.

The language server's LineIndex converts offsets to line/column positions
in UTF-8, UTF-16 and UTF-32. It lives in pgls_lsp, which pulls in tokio and
tower-lsp, so the WASM bindings and pgls_suppressions couldn't use it and
have their own line handling. Move it, with LineCol, WideLineCol,
WideEncoding and WideChar, into a small crate that only depends on
pgls_text_size and rustc-hash. No behaviour change.
The suppressions parser numbers lines with str::lines, which ends lines at
\n, but its own line index also ended them at a lone \r. After a lone \r,
the two disagreed: a line suppression got the offset of the wrong line and
didn't apply to the line below it. Use pgls_line_index, which ends lines at
\n only, like the language server and the WASM bindings.
Keep the index in line_index.rs, nearly unchanged, with the position types
in lib.rs and the tests in tests.rs, so that git still follows the file
from pgls_lsp when merging branches that change it.
…-line-index

# Conflicts:
#	crates/pgls_line_index/src/lib.rs
# Conflicts:
#	crates/pgls_lsp/src/session.rs
@psteinroe
psteinroe changed the base branch from refactor/line-index-crate to main November 2, 2026 12:09
psteinroe added a commit that referenced this pull request Nov 2, 2026
…in OUT_DIR (#1106)

`build.rs` copied the vendored libpg_query tree into `OUT_DIR` and
compiled every `*.c` it found there. The copy overwrites files but never
removes any, so an `OUT_DIR` that a build of another libpg_query version
left behind still holds that version's files, and the glob compiles them
too. That's what broke Lint, Codegen and Test on #1072: CI restored the
`target/` that main saved after #1055, and the branch, still on
libpg_query 17, compiled the 18.1.0 `pg_query_is_utility_stmt.c` from it
(`unknown type name 'PgQueryIsUtilityResult'`). Switching branches
locally does the same.

### What changed

- The vendored layout now points at the submodule itself, so the C
sources, headers, `pg_query.proto` and the include paths all come from
`vendor/libpg_query`. Nothing is copied anymore. `OUT_DIR` only holds
the objects, `libpg_query.a` and `bindings.rs`. The copy wasn't needed:
nothing writes into the tree, and the system layout already reads its
prefix in place. `fs_extra` is no longer a build dependency.
- The build script now prints `rerun-if-changed` for the submodule's
headers, `src`, `protobuf` and `vendor`, plus `build.rs` and
`LIBPG_QUERY_PATH`. Before, cc's `rerun-if-env-changed` lines turned off
Cargo's default "rerun when any file of the package changes", so a
change to the submodule alone (e.g. `git submodule update` after
switching branches) didn't rebuild the C library at all.

The CI caches stay as they are. moonrepo/setup-rust restores by the
prefix `setup-rustcargo-v1-<os>`, so a key that includes the submodule
commit would still restore main's latest cache, and the tree-sitter
cache only holds the generated grammar. A branch that is still on
libpg_query 17 needs main merged in (it then gets #1055 and this fix),
because CI runs the branch's own `build.rs`.

### Tests

- Reproduced the CI failure: built `pgls_query` on main before this
change, then checked out the commit before #1055 (same `Cargo.lock`,
same `OUT_DIR`) and built again. It failed with the same
`pg_query_is_utility_stmt.c` errors as #1072.
- With this change: filled the `OUT_DIR` with the 18.1.0 copies plus a
`.c` file that only contains `#error`, then built the commit before
#1055 with this `build.rs` and switched back to this branch. Both builds
pass, and the archive built from the 17 sources has no
`pg_query_is_utility_stmt`.
- Touching a file under `vendor/libpg_query/src` now reruns the build
script; before, the crate stayed `Fresh`. Deleting one reruns it too.
- `cargo test -p pgls_query`, `cargo clippy -p pgls_query --all-targets
-- -D warnings`.
@psteinroe
psteinroe merged commit 8e3b489 into main Nov 9, 2026
12 checks passed
@psteinroe
psteinroe deleted the fix/suppressions-shared-line-index branch November 9, 2026 13:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant