rust-lang / rust-lang/rust-analyzer

`convert_tuple_struct_to_named_struct` produces intersecting edits when a macro expands a field access twice

Open
#22,558 1 comment 0 reactions 1 assignee View on GitHub

@Albab-Hasan is already working on this.

Since Jun 10, 2026.

A-assists C-bug
Dominant language
Rust
Stars
16.9k
Forks
2.2k
Avg merge
1d 12h
Merged PRs (30d)
72

Description

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 T(i32);

fn main() {
    let u = T(1);
    m!(u.0);
}

reproduce:
cursor on T in struct T(i32);
Convert to named struct

expected:
struct T { field1: i32 } with the usage rewritten to m!(u.field1);, or the field reference inside the macro left alone. 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:  ReplaceWithMany(Token(INT_NUMBER@461..462 "0"), [Node(NAME@0..6)]) 0field1
equals
right change: ReplaceWithMany(Token(INT_NUMBER@461..462 "0"), [Node(NAME@0..6)]) 0field1
panicked at crates/syntax/src/syntax_editor/edit_algo.rs:478:5:
some replace change ranges intersect!

cause:
the macro expands $e twice, so the field-reference search returns two FileReferences for the single 0 token in the source. edit_field_references maps both back to the same source token and registers two identical ReplaceWithMany changes, tripping stdx::always!(false, "some replace change ranges intersect!") in edit_algo.rs — the whole edit is discarded.

note:
same root cause as the destructure_tuple_binding / destructure_struct_binding / convert_named_struct_to_tuple_struct issues. related but distinct from #22094 (that one hits the unimplemented! in the dependent-change resolver at edit_algo.rs:298; this one hits the disjointness check at :478).

env:

  • rustc: 1.97.0-nightly
  • rust-analyzer: 0.3.2929
  • OS: Ubuntu
  • Editor: VS Code

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.