rust-lang / rust-analyzer

A Rust compiler front-end for IDEs
https://rust-analyzer.github.io/
Apache License 2.0
14.24k stars 1.6k forks source link

Renaming local variables is confused by attributes #16422

Open Wilfred opened 9 months ago

Wilfred commented 9 months ago
struct MyStruct {
    foo: String, // rename me
}

#[tracing::instrument(skip_all)]
fn takes_mystruct(mystruct: MyStruct) {
    let MyStruct { foo } = mystruct;

    let value_of_foo = foo;
}

Renaming produces:

struct MyStruct {
    bar: String, // rename me
}

#[tracing::instrument(skip_all)]
fn takes_mystruct(mystruct: MyStruct) {
    let MyStruct { bar } = mystruct;

    let value_of_foo = foo;
}

rust-analyzer version: 2024-01-01

crazymerlyn commented 8 months ago

Tried to look into it but it seems it might be intentional: https://github.com/rust-lang/rust-analyzer/blob/39ad79bec5202fda903893034918cb5526bb834c/crates/ide-db/src/rename.rs#L376-L384

Without the proc-macro, the above code replaces "foo" with "bar: foo".

But with the proc-macro, the code just gives up since it doesn't know how a macro might react to switching between shorthand notation and normal notation.

Veykril commented 8 months ago

Hm, it is intentional not to do anything fancy when the rename happens in a macro, but this is certainly a bug wrt to attributes where we can upmap the syntax node out of the expansion. We should attempt that first and then try to the rename.

davidbarsky commented 4 months ago

(Copying from https://github.com/rust-lang/rust-analyzer/issues/17363)

I'm able to reproduce this:

#[tracing::instrument]
fn test() {
    let string = String::from("hello").replace("hello", "goodbye");
    let string = String::from("goodbye").replace("goodbye", "goodbye");
}

Cargo.toml:

[package]
name = "instrument-breaks-extract-repro"
version = "0.1.0"
edition = "2021"

[dependencies]
tracing = "0.1.40"

Highlighting let string = String::from("hello").replace("hello", "goodbye"); with #[tracing::instrument] provides the "extract into variable" and "replace let with if let" assists. If I comment out #[tracing::instrument], I get the "extract into variable", "extract into function", "replace with if let", and "insert explicit type String" assists.

The presence of #[instrument] also prevents the parameter name inlay hints on String::replace from rendering. With #[instrument], from: and to: are missing, but they reappear once I remove #[instrument]. Similarly, semantic highlighting was also degraded here.

Veykril commented 4 months ago

Those are all different issues that you listed FYI (as in the cause/problem)

davidbarsky commented 4 months ago

Fair enough. I assume that the proc macro isn't helping, but I can make separate issues for them?

Veykril commented 4 months ago

I mean the proc macro is the underlying cause for all of them, but the logic that is "failing" here is different for each of them presumably. Its fine to list them in one issue, though it'd be better to list them out as a bullet list or something then I think

davidbarsky commented 4 months ago

I'll change that. rust-analyzer has a lot of open issues already; I don't want to make it worse.