Rust: Restore built-in derive macro expansion under rust-analyzer 0.0.328 - #22273
Merged
redsun82 merged 1 commit intoAug 3, 2026
Conversation
….328 rust-analyzer 0.0.317 re-modeled built-in derives (`Debug`, `PartialEq`, `Eq`, ...) as synthetic impls rather than syntactic macro expansions, so `Semantics::expand_derive_macro` returns nothing for them and the 0.0.328 upgrade silently dropped their extraction. This regressed queries that depend on the derived impls (e.g. `rust/insecure-cookie`). Reconstruct the expansions extractor-side by re-running the still-public built-in derive expander over the ADT and emitting the resulting `impl` items. Synthesized nodes are not in the semantics cache, so their source locations are resolved through the expansion span map instead of `Semantics::original_range`. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 86c6ce1d-a625-491a-94ea-eae08d3cc1be
redsun82
marked this pull request as ready for review
August 3, 2026 15:10
redsun82
merged commit Aug 3, 2026
bbd2102
into
tausbn/rust-upgrade-to-rust-analyzer-0.0.328
10 of 62 checks passed
Contributor
There was a problem hiding this comment.
Pull request overview
Restores extraction of rust-analyzer’s synthesized built-in derive implementations.
Changes:
- Reconstructs built-in derive expansions and maps synthesized locations.
- Adds the syntax-bridge dependency and Bazel wiring.
- Updates affected extraction, type-inference, and security expectations.
Show a summary per file
| File | Description |
|---|---|
rust/extractor/src/translate/base.rs |
Implements derive reconstruction and location mapping. |
rust/extractor/Cargo.toml |
Adds syntax-bridge dependency. |
Cargo.lock |
Locks the new dependency. |
MODULE.bazel |
Exposes the vendored dependency. |
misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl |
Wires the dependency into Bazel. |
misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel |
Adds dependency aliases. |
rust/ql/test/extractor-tests/macro-expansion/test.expected |
Verifies restored derive items. |
rust/ql/test/extractor-tests/macro-expansion/PrintAst.expected |
Records synthesized derive ASTs. |
rust/ql/test/extractor-tests/generated/MacroItems/MacroItems.expected |
Records derived macro items. |
rust/ql/test/extractor-tests/canonical_path/canonical_paths.expected |
Verifies canonical paths for derived impls. |
rust/ql/test/library-tests/type-inference/type-inference.expected |
Records improved type inference. |
rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected |
Restores insecure-cookie results. |
Review details
- Files reviewed: 10/12 changed files
- Comments generated: 1
- Review effort level: Balanced
Comment on lines
+747
to
+751
| let input = syntax_node_to_token_tree( | ||
| adt.syntax(), | ||
| span_map.as_ref(), | ||
| call_site, | ||
| DocCommentDesugarMode::ProcMacro, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #21714 (the rust-analyzer 0.0.328 upgrade).
That upgrade silently drops built-in derive macro expansion — something we'd already spotted as a team: the
implblocks synthesized by#[derive(Debug)],#[derive(PartialEq, Eq)], etc. are no longer extracted. rust-analyzer 0.0.317 re-modeled built-in derives as synthetic impls rather than syntactic macro expansions, soSemantics::expand_derive_macroreturnsNonefor them and our old.flatten().flatten()just dropped them on the floor.This regresses any query that leans on the derived impls (
rust/insecure-cookieis the one that first flagged it: it went from 1 result to 0).Approach
Rather than reverting the parts of the upgrade that fix the Rust 1.95 breakage, I reconstruct the expansions extractor-side:
ra_ap_hir_expand::builtin::BuiltinDeriveExpander) over the ADT and emit the resultingimplitems ourselves, reusing the existingemit_macro_itemspathSemantics::original_rangewould panic on them), so I route their locations through the expansion span map viamap_node_range_up_rootedfor the duration of the emissionresolve_derive_macrois used positionally alongsideexpand_derive_macroto tell the built-in derives apart from proc-macro ones and recover the right expanderThis needed one new direct dep on
ra_ap_syntax-bridge(already vendored transitively). The bazel 3rdparty wiring was regenerated withrust/update_cargo_deps.sh.Validation
macro-expansionextractor test now shows the built-in derive impls again (impl ...::Eq for MyDeriveEnumand friends)CWE-614/InsecureCookie.expectednow matches the pre-upgrademainbaseline exactly, so the regression is fully undonetype-inference.expectedpicks up a handful of newly-resolved::default()/constructor results (and loses the correspondingMissing result:markers), which is a nice side effect ofDefaultbeing backcanonical_path,MacroItems) are just the restored derive rows; 360+ other affected rust tests still pass locallyMarking as draft to let CI have a full go at the test suite. I couldn't reproduce the Rust 1.95 side locally (no 1.95 toolchain here), but that half of the upgrade is preserved by construction since the fix lives entirely inside the extractor's use of the 0.0.328 crates.