rls icon indicating copy to clipboard operation
rls copied to clipboard

"Rename failed: RLS found nothing to rename" when attempting to rename a struct

Open norru opened this issue 6 years ago • 19 comments

I am unable to rename a struct and I get this in my RLS log:

LSP4E to org.eclipse.corrosion.rls:{"jsonrpc":"2.0","id":"727","method":"textDocument/rename","params":{"textDocument":{"uri":"file:///home/nico/Projects/itadinanta/ofx-rs/ofx/src/handle.rs"},"position":{"line":40,"character":18},"newName":"ImageEffectHandle"}}
org.eclipse.corrosion.rls to LSP4E:{"jsonrpc":"2.0","method":"window/showMessage","params":{"message":"Rename failed: RLS found nothing to rename - possibly due to multiple defs","type":2}}
org.eclipse.corrosion.rls to LSP4E:{"jsonrpc":"2.0","id":"727","result":{}}

how to reproduce:

git clone -btags/rls_1322_rename_failed https://github.com/itadinanta/ofx-rs.git
cd ofx-rs/ofx
rls --cli
rename src/handle.rs 40 18 ImageEffectHandle

Related to https://github.com/rust-lang/rls/issues/1233 but I get a different error.

+@mickaelistria

norru avatar Feb 23 '19 18:02 norru

Thank you reporting the problem. Do you have an example code which causes RLS to failed? That would be very helpful for pinning down the problem.

lijinpei avatar Feb 24 '19 01:02 lijinpei

I can't rename ANY struct. Is RLS refactoring being tested only with trivial cases? What does the test suite look like?

norru avatar Feb 24 '19 09:02 norru

Here you go. https://github.com/rust-lang/rls/blob/7ec19054394ee1ab29b106d1f2c3723a10e7ea6a/tests/tests_old.rs#L619

lijinpei avatar Feb 24 '19 12:02 lijinpei

Yes, it does appear that test only covers a trivial case. Feel free to correct me if I'm wrong.

norru avatar Feb 24 '19 12:02 norru

Hi @lijinpei Here's a non-trivial repro case for you:

git clone -btags/rls_1322_rename_failed https://github.com/itadinanta/ofx-rs.git
cd ofx-rs/ofx
rls --cli
rename src/handle.rs 40 18 ImageEffectHandle

Output:

{"jsonrpc":"2.0","method":"window/showMessage","params":{"message":"Rename failed: RLS found nothing to rename - possibly due to multiple defs","type":2}}
2: WorkspaceEdit {
    changes: None,
    document_changes: None
}
$rls --version
rls 1.34.0 (0d6f53e 2019-02-14)

norru avatar Feb 24 '19 13:02 norru

Hi @lijinpei. I am trying to run the RLS tests from source but this is what I get:

nico@devuan-3xS:~/Projects/3rdParty/rls$ cargo test

error[E0658]: use of unstable library feature 'str_escape': return type may change to be an iterator (see issue #27791)
   --> /home/nico/.cargo/registry/src/github.com-1ecc6299db9ec823/rustc-ap-graphviz-373.0.0/lib.rs:525:52
    |
525 |             LabelStr(ref s) => format!("\"{}\"", s.escape_default()),
    |                                                    ^^^^^^^^^^^^^^
    |
    = help: add #![feature(str_escape)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'str_escape': return type may change to be an iterator (see issue #27791)
   --> /home/nico/.cargo/registry/src/github.com-1ecc6299db9ec823/rustc-ap-graphviz-373.0.0/lib.rs:540:27
    |
540 |                     (&*s).escape_default().to_string().into()
    |                           ^^^^^^^^^^^^^^
    |
    = help: add #![feature(str_escape)] to the crate attributes to enable

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0658`.
error: Could not compile `rustc-ap-graphviz`.
warning: build failed, waiting for other jobs to finish...
error: build failed

EDIT: Never mind, it appears that building RLS requires nightly

norru avatar Feb 24 '19 13:02 norru

@norru building RLS do require nighlty, because only nighlty allows #[feature(rustc_private)]

lijinpei avatar Feb 24 '19 13:02 lijinpei

Hi, @norru . After a little bit of digging around, I think the symptom probably is you can't rename things you have used in object_property! macro, but renaming other variables probably works fine. The cause of the problem is RLS(or rls-analysis) has some mapping between source code location, reference, and definition. Surprisingly, one source code location can corresponds to multiple definitions, this is especially the case when a macro expands to some definitions, and all the expanded results are represented by the same location(where the macro use occurs). And when the same location corresponds to multiple definitions, rls-analysis/RLS doesn't know what to do, so renaming fails. In short, renaming maybe problematic with macros. BTW, I think macro in statement position can expand to nothing and perhaps your implementation of object_properties! can be simplified.

lijinpei avatar Feb 25 '19 03:02 lijinpei

So to summarize, renames don't work with macros? Kind of a bummer.

Any suggestion on how to simplify object_properties! without changing the macro usage? At the moment I am tidying the code of that library up, hence the need to rename.

I am also evaluating whether to replace macro_rules with procedural to make the implementation clearer.

On Mon, 25 Feb 2019, 03:30 lijinpei, [email protected] wrote:

Hi, @norru https://github.com/norru . After a little bit of digging around, I think the symptom probably is you can't rename things you have used in object_property! macro, but rename other variables probably works fine. The cause of the problem is RLS(or rls-analysis) has some mapping between source code location, reference, and definition. Surprisingly, one source code location can corresponds to multiple definitions, this is especially the case when a macro expands to some definitions, and all the expanded results are represented by the same location(where the macro use occurs). And when the same location corresponds to multiple definitions, rls-analysis/RLS doesn't know what to do, so renaming fails. BTW, I think macro in statement position can expand to nothing and perhaps your implementation of object_properties! can be simplified.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/rust-lang/rls/issues/1322#issuecomment-466860045, or mute the thread https://github.com/notifications/unsubscribe-auth/AA2Ry2l8-avDZ8UwVTFibW4VFUja0DmAks5vQ1jRgaJpZM4bOF_h .

norru avatar Feb 25 '19 09:02 norru

It's just some reduction base cases are unnecessary.

macro_rules! object_properties {
	(@tail $trait:ty =>) => {
        };

	(@tail $trait:ty => $property:ident read+write, $($tail:tt)*) => {
		impl $property::CanGet for $trait {}
		impl $property::CanSet for $trait {}
		object_properties!(@tail $trait => $($tail)*);
	};

	(@tail $trait:ty => $property:ident write, $($tail:tt)*) => {
		impl $property::CanSet for $trait {}
		object_properties!(@tail $trait => $($tail)*);
	};

	(@tail $trait:ty => $property:ident read, $($tail:tt)*) => {
		impl $property::CanGet for $trait {}
		object_properties!(@tail $trait => $($tail)*);
	};

	(@tail $trait:ty => $capability:ident inherit, $($tail:tt)*) => {
		impl $capability for $trait {}
		object_properties!(@tail $trait => $($tail)*);
	};

	($trait:ty { $($tail:tt)* }) => {
		object_properties!(@tail $trait => $($tail)*);
	};
}

I admit renaming can't work with macros is a big bummer. I need to look into whether rustc exposes enough information to fix this, if it does, then we can fix this problem on RLS side, if it doesn't, then I don't expect this to be fixed in a short time.

lijinpei avatar Feb 25 '19 11:02 lijinpei

Thanks for the reduction tip, I'll try it. I think I can live with the macro accepting an empty properties list :)

norru avatar Feb 25 '19 12:02 norru

Unfortunately we don't support the macro flow entirely when it comes to analyzing defs/refs for the identifiers :cry:

Xanewok avatar Mar 03 '19 16:03 Xanewok

Can't RLS do a best-effort thing here? Rename the uses outside macros, and provide a list of the places which RLS could not rename?

Diggsey avatar Apr 05 '19 11:04 Diggsey

Hi there, I'm a new Rust user. Here is a minimal case (without macros) where Rename fails using the RLS extension in Visual Studio Code, and a simple change which allows Rename to succeed. Hopefully this helps to track down this bug.

If you attempt to rename MyLoop to Loop using F2 or the right-click popup menu, RLS reports "RLS found nothing to rename - possibly due to multiple defs"

If you remove the body of main(), the Rename operation is successful. Obviously this is not a helpful workaround, but it might help diagnose the problem or create a better test case.

pub enum MyLoop {
    Continue,
    Quit,
}

pub struct MyResponse {
    pub loop_continue: MyLoop,
}


fn main() {
    let mut loop_continue = MyLoop::Continue;
    while let MyLoop::Continue = loop_continue {
        println!("Hello, world!");

        loop_continue = MyLoop::Quit;

    }
}

Version info. Running on Windows 10.

$ cargo --version
cargo 1.35.0 (6f3e9c367 2019-04-04)

$ rustc --version
rustc 1.35.0 (3c235d560 2019-05-20)

$ rls --version
rls 1.35.0 (49efc06 2019-04-06)

anticrisis avatar May 25 '19 01:05 anticrisis

@anticrisis's Test case is rather minimal and perfectly exemplifies the issues described, hoping we can get some one to pick this up as this has been a long standing issue with RLS that I've had but never reported :pray:

0X1A avatar Jul 20 '19 19:07 0X1A

Rename never works for me with structs that use derive, so this feature is mostly useless at this point. I can reliably rename only local vars inside function.

DzmitryFil avatar Nov 12 '19 10:11 DzmitryFil

@DzmitryFil As a workaround, I delete the derive attributes, rename, and then paste the derive attributes back in place. This works fine :)

iago-lito avatar Apr 07 '20 10:04 iago-lito

Any updates on this issue or plans for a proper patch? I'm still experiencing it with the VSCode extension. Issue also seems to apply to Enums.

wyhinton avatar Apr 16 '21 04:04 wyhinton

Found this issue, one year later...

Testare avatar May 22 '22 06:05 Testare