🐛 feat(lsp): filter type errors to only those originating from the current source#1445
🐛 feat(lsp): filter type errors to only those originating from the current source#1445
Conversation
harehare
commented
Mar 13, 2026
- Use FxHashSet to track symbol locations for the current source
- Only report type errors whose location matches the current file
- Update dependencies for rustc-hash
- Register unary 'range' for (number) -> [number] in mq-check
…ent source - Use FxHashSet to track symbol locations for the current source - Only report type errors whose location matches the current file - Update dependencies for rustc-hash - Register unary 'range' for (number) -> [number] in mq-check Closes #XXX (replace with actual issue if relevant)
There was a problem hiding this comment.
Pull request overview
This PR aims to improve the mq LSP diagnostics experience by ensuring type errors reported in the editor are attributed only to the currently edited source file, while also aligning mq-check’s builtin typing for range with the runtime’s supported unary form.
Changes:
- Filter LSP-reported type errors to those considered to originate from the current source.
- Add
rustc-hash(forFxHashSet) to mq-lsp dependencies. - Register a unary
range(number) -> [number]overload inmq-check.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
crates/mq-lsp/src/server.rs |
Builds a per-source location set and filters mq_check type errors before storing/publishing diagnostics. |
crates/mq-lsp/Cargo.toml |
Adds rustc-hash dependency and adjusts dependency ordering. |
crates/mq-check/src/builtin.rs |
Registers a unary range(number) overload in the type checker builtin registry. |
Cargo.lock |
Locks the new rustc-hash dependency for mq-lsp. |
| // range: (number) -> [number], (number, number) -> [number], (number, number, number) -> [number] | ||
| register_unary(ctx, "range", Type::Number, Type::array(Type::Number)); | ||
| register_binary(ctx, "range", Type::Number, Type::Number, Type::array(Type::Number)); |
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
There was a problem hiding this comment.
Pull request overview
This PR improves the mq-lsp diagnostics pipeline by reducing noise from type-checking across multiple loaded sources, aiming to surface only type errors attributable to the currently edited document. It also updates mq-check to type-check the unary numeric range(n) form and wires in rustc-hash for fast hashing.
Changes:
- Filter LSP-reported type errors to those matching the current source’s symbol locations.
- Add
range(number) -> [number]overload registration inmq-check. - Add
rustc-hashdependency usage (FxHashSet) and update lockfile accordingly.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
crates/mq-lsp/src/server.rs |
Builds a per-source location set and filters mq-check type errors before storing/publishing diagnostics. |
crates/mq-lsp/Cargo.toml |
Adds rustc-hash dependency and keeps workspace deps organized. |
crates/mq-check/src/builtin.rs |
Registers unary numeric range overload in the type checker builtins. |
Cargo.lock |
Records the new rustc-hash dependency resolution. |
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
There was a problem hiding this comment.
Pull request overview
This PR aims to improve mq-lsp diagnostics by ensuring type-checker errors are only reported for the currently edited document (rather than accidentally attributing errors from other sources/modules), and aligns mq-check’s builtin typing for range with the runtime behavior.
Changes:
- Filters LSP-reported type errors to those associated with the current source.
- Adds a unary
range(number) -> [number]overload to the type checker. - Adds
rustc-hashtomq-lspdependencies (workspace) and updatesCargo.lock.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
crates/mq-lsp/src/server.rs |
Adds logic intended to filter type errors to the current source_id; introduces rustc_hash::FxHashSet import. |
crates/mq-lsp/Cargo.toml |
Adds rustc-hash dependency (workspace) and reorders deps. |
crates/mq-check/src/builtin.rs |
Registers unary numeric range overload in the type checker. |
Cargo.lock |
Records rustc-hash as a dependency of mq-lsp. |
This reverts commit ab26ca1.
…esponse functions
There was a problem hiding this comment.
Pull request overview
This PR improves the mq language server (LSP) diagnostic signal by reducing cross-file noise from type-checking, while also making a few small concurrency/efficiency cleanups in LSP handlers and extending mq-check’s builtin range typing.
Changes:
- Filter LSP-reported type errors to those originating from the currently edited source.
- Reduce repeated HIR lock acquisitions in semantic tokens, hover, and completions.
- Add a unary
range(number) -> [number]overload inmq-checkand wire inrustc-hashforFxHashSet.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/mq-lsp/src/server.rs | Filters type errors to current source; refactors diagnostic filtering and minor allocations. |
| crates/mq-lsp/src/semantic_tokens.rs | Reuses a single HIR read-lock for the full token computation. |
| crates/mq-lsp/src/hover.rs | Uses a read-lock (instead of write-lock) to read source info. |
| crates/mq-lsp/src/completions.rs | Reuses a single HIR read-lock and simplifies symbol collection. |
| crates/mq-lsp/Cargo.toml | Adds rustc-hash and reorders deps. |
| crates/mq-check/src/builtin.rs | Registers unary range(number) overload. |
| Cargo.lock | Records the new rustc-hash dependency usage. |
| if errors.is_empty() && self.config.enable_type_checking { | ||
| let hir_guard = self.hir.read().unwrap(); | ||
| let mut checker = mq_check::TypeChecker::with_options(self.config.type_checker_options); | ||
| let type_errors = checker.check(&self.hir.read().unwrap()); | ||
| let type_errors = checker.check(&hir_guard); | ||
|
|
||
| // Build a set of (line, column) start positions from the current source's symbols | ||
| // so that type errors originating from other sources (e.g., pre-loaded modules) | ||
| // are not incorrectly attributed to this file. | ||
| let source_locations: FxHashSet<(u32, usize)> = hir_guard | ||
| .symbols_for_source(source_id) | ||
| .filter_map(|(_, symbol)| { | ||
| symbol | ||
| .source | ||
| .text_range | ||
| .as_ref() | ||
| .map(|r| (r.start.line, r.start.column)) | ||
| }) | ||
| .collect(); | ||
|
|
||
| self.type_env_map | ||
| .insert(uri_string.clone(), checker.symbol_types().clone()); | ||
| errors.extend(type_errors.into_iter().map(LspError::TypeError)); | ||
| errors.extend( | ||
| type_errors | ||
| .into_iter() | ||
| .filter(|e| { | ||
| e.location() | ||
| .map(|(line, col)| source_locations.contains(&(line, col))) | ||
| .unwrap_or(false) | ||
| }) | ||
| .map(LspError::TypeError), | ||
| ); |
| // range: (number) -> [number], (number, number) -> [number], (number, number, number) -> [number] | ||
| register_unary(ctx, "range", Type::Number, Type::array(Type::Number)); | ||
| register_binary(ctx, "range", Type::Number, Type::Number, Type::array(Type::Number)); |
| if self | ||
| .error_map | ||
| .get(¶ms.text_document.uri.to_string()) | ||
| .unwrap() | ||
| .iter() | ||
| .filter(|e| matches!(e, LspError::SyntaxError(_))) | ||
| .collect::<Vec<_>>() | ||
| .is_empty() | ||
| .any(|e| matches!(e, LspError::SyntaxError(_))) |
| .filter(|e| { | ||
| e.location() | ||
| .map(|(line, col)| source_locations.contains(&(line, col))) | ||
| .unwrap_or(false) |
| // Build a set of text_ranges for this file's symbols for O(1) lookup | ||
| let range_set: FxHashSet<mq_lang::Range> = hir_guard | ||
| .symbols() | ||
| .filter_map(|(_, symbol)| { | ||
| if symbol.source.source_id == Some(*source_id) { | ||
| symbol.source.text_range | ||
| } else { | ||
| None | ||
| } | ||
| }) |