rust-analyzer version: 0.3.2929-standalone (panic message below is from a source build of master with force-always-assert; on the release build the assist silently does nothing and only logs the error)
rustc version: rustc 1.97.0-nightly (ca9a134e0 2026-04-26)
editor or extension: VSCode, rust-analyzer extension 0.3.2929
relevant settings: none
repository link (if public, optional): n/a
code snippet to reproduce:
macro_rules! m { ($e:expr) => { ($e, $e) }; }
struct S { a: i32 }
fn main() {
let s2 = S { a: 1 };
m!(s2.a);
}
reproduce:
cursor on s2 in let s2 = S { a: 1 };
Destructure struct binding
expected:
let S { a } = S { a: 1 }; and m!(a);, or the assist bails on the macro usage. either way no crash.
actual:
on the release build the assist is offered, applies nothing, and logs the error. on a build with debug assertions the request handler panics:
request handler panicked: some replace change ranges intersect!
left change: ReplaceAll(Token(IDENT@296..298 "s2")..=Token(IDENT@299..300 "a"), [Node(PATH_EXPR@0..1)]) (s2.aa)
equals
right change: ReplaceAll(Token(IDENT@296..298 "s2")..=Token(IDENT@299..300 "a"), [Node(PATH_EXPR@0..1)]) (s2.aa)
panicked at crates/syntax/src/syntax_editor/edit_algo.rs:478:5:
some replace change ranges intersect!
cause:
the macro expands $e twice, so FindUsages returns two FileReferences for the single s2 token in the source. update_usages maps each one back to the same source range and registers two identical ReplaceAll changes, tripping stdx::always!(false, "some replace change ranges intersect!") in edit_algo.rs — the whole edit is discarded. My fix in #21838 fixed this assist for a single usage inside a macro, but not for a macro that duplicates its argument.
note:
same root cause as the destructure_tuple_binding issue, also affects convert_named_struct_to_tuple_struct and convert_tuple_struct_to_named_struct.
env:
- rustc: 1.97.0-nightly
- rust-analyzer: 0.3.2929
- OS: Ubuntu
- Editor: VS Code
rust-analyzer version: 0.3.2929-standalone (panic message below is from a source build of master with
force-always-assert; on the release build the assist silently does nothing and only logs the error)rustc version: rustc 1.97.0-nightly (ca9a134e0 2026-04-26)
editor or extension: VSCode, rust-analyzer extension 0.3.2929
relevant settings: none
repository link (if public, optional): n/a
code snippet to reproduce:
reproduce:
cursor on
s2inlet s2 = S { a: 1 };Destructure struct binding
expected:
let S { a } = S { a: 1 };andm!(a);, or the assist bails on the macro usage. either way no crash.actual:
on the release build the assist is offered, applies nothing, and logs the error. on a build with debug assertions the request handler panics:
cause:
the macro expands
$etwice, soFindUsagesreturns twoFileReferences for the singles2token in the source.update_usagesmaps each one back to the same source range and registers two identicalReplaceAllchanges, trippingstdx::always!(false, "some replace change ranges intersect!")inedit_algo.rs— the whole edit is discarded. My fix in #21838 fixed this assist for a single usage inside a macro, but not for a macro that duplicates its argument.note:
same root cause as the
destructure_tuple_bindingissue, also affectsconvert_named_struct_to_tuple_structandconvert_tuple_struct_to_named_struct.env: