-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Since 0.4.1658] Cannot rename a non-local definition. #15656
Comments
@rustbot claim |
We use a rust-analyzer/crates/base-db/src/input.rs Lines 143 to 152 in f19479a
is something else other flowchart TB
ProjectRoot -- CrateOrigin::Local --> Foo
ProjectRoot -- CrateOrigin::Local --> Bar
The trouble starts when flowchart TB
ProjectRoot -- CrateOrigin::Local --> Foo
ProjectRoot -- CrateOrigin::Local --> Bar
Foo -- CrateOrigin::Library --> BarAsLib
Or in simplified terms : flowchart TB
ProjectRoot -- CrateOrigin::Local --> Foo
ProjectRoot -- CrateOrigin::Local --> Bar
Foo -- CrateOrigin::Library --> Bar
So resolving this issue will entail changes in Here's a test case where you can find a minimal repro. |
Ah, that would explain that indeed. I think your merged crate graph in your examples is wrong though no? I would expect us to actually have two |
It is indeed wrong but the whole point was to show that |
I think we should instead take a look at Also, the duplicated crates only differ in the |
Ah, this issue might be why Rename Symbol no longer works on local variables in some rustc crates. |
I've confirmed that reverting to 0.3.1657 allows Rename Symbol to work in |
fixes rust-lang#15656 . With this commit we have a more relaxed way of comparing to crates for equality. If two crates are `almost_equal` then deduplication takes place.
Partially fixes rust-lang#15656 . When a crate graph is extended which is the case when new workspaces are added to the project the rules for deduplication were too strict. One problem that arises from this is that in certain conditions when we see the same crate having different `CrateOrigin`s the first form would be maintained. This approach however results in some unwanted results such as making renaming forbidden as this has been recently only made available for local crates. The given example in rust-lang#15656 can still not be resolved with this PR as that involves taking inconsistencies between dependencies into consideration. This will be addressed in a future PR.
So first of all sorry for taking so much time I was sick for a week. I have addressed the reasons behind this issue and my PR solves most of them. The project given as a repro however will still not be able use renaming. I will address this in a following PR. As I mentioned before we deal with multiple occurrences of the same crate and the dedup rules were until now too strict ( two crates must be equal to be merged into one but this is not possible in the given example, see comment above) . After I relaxed the conditions for merging I saw that there are inconsistencies in versions of one crate "hashbrown" in the given repro ( see metadata for both reloaded_hooks_{portable,x86_sys} @Sewer56 ). But I couldn't have relaxed the condition to say if one project has a dependency that has a different version than its other occurrence then merge them anyway. So this still needs to be addressed somehow but until then it wouldn't hurt to come up with a solution that solves this issue in most of cases. |
There is nothing to address in that case (aside from our PR relaxing things in regards to the origin), the root of the problem is that the crate that is being loaded in the linked projects while also being loaded as a dependency of another is subject to different The only thing that we should be looking into is recognizing this, and somehow inform the user that this kind of set up can cause IDE features like renaming to fail. Although I think there is a bug here in how we assign CrateOrigin's still / how we forbid renaming as well. The crates in question where renaming fails here are still inside the project folders (presumably via |
"The crates in question where renaming fails here are still inside the project folders (presumably via path dependencies) in which case we shouldn't forbid renames in the first place I think, since those are technically fine to modify." I've just recently run into this issue (using v0.3.1713) when using multi-root Workspaces and with submodules declared between them via |
👋 We use configurations to customize behavior, in your case your request is more of a workaround kind. Although practically this could work, we'd rather see a solution that resolves this issue once and for all. We still couldn't merge the PR upstream so until then ( merged version will probably be available in nightly between 13.11-17.11) you could do two things
Or rust-analyzer/crates/ide-db/src/rename.rs Lines 78 to 82 in c1c9e10
delete lines 79-82 and build the project using the command Sorry if you couldn't find the answer you were looking for. EDIT : If it is actually the case that there are some cases where we cannot really do anything to prevent from producing false positives, then something like the proposed configuration may be a consideration. So there is that. |
Thanks for the instructions! I went ahead and took a crack at a fix. I believe the correct course might be to relax the definition of impl CrateOrigin {
pub fn is_local(&self) -> bool {
match self {
Self::Local { .. } => true,
Self::Library { repo, .. } => repo.is_none(),
_ => false,
}
}
} This change fixes my project. I am able to rename things in the cross-referenced crates but it still fails if I try to rename a symbol inside I made a PR here ogapo#1. I wasn't sure enough about the change to want to PR against this repo (happy to do so if you recommend though). The change is small though, so might be better to be incorporated into PR #15754 |
Partially fixes rust-lang#15656 . When a crate graph is extended which is the case when new workspaces are added to the project the rules for deduplication were too strict. One problem that arises from this is that in certain conditions when we see the same crate having different `CrateOrigin`s the first form would be maintained. This approach however results in some unwanted results such as making renaming forbidden as this has been recently only made available for local crates. The given example in rust-lang#15656 can still not be resolved with this PR as that involves taking inconsistencies between dependencies into consideration. This will be addressed in a future PR.
👋 Thank you for your answer @ogapo . We were planning to make some changes to how we determine |
I have also recently started experiencing this issue in one of the recent updates.
|
… r=Veykril fix: Dedup duplicate crates with differing origins in CrateGraph construction Partially fixes #15656 . Until now the condition for deduplication in crate graphs were the strict equality of two crates. One problem that arises from this is that in certain conditions when we see the same crate having different `CrateOrigin`s the first occurrence would be kept. This approach however results in some unwanted results such as making renaming forbidden as this has been recently only made available for local crates. The given example in #15656 can still not be resolved with this PR as that involves taking inconsistencies between dependencies into consideration. This will be addressed in a future PR.
… r=Veykril fix: Dedup duplicate crates with differing origins in CrateGraph construction Partially fixes #15656 . Until now the condition for deduplication in crate graphs were the strict equality of two crates. One problem that arises from this is that in certain conditions when we see the same crate having different `CrateOrigin`s the first occurrence would be kept. This approach however results in some unwanted results such as making renaming forbidden as this has been recently only made available for local crates. The given example in #15656 can still not be resolved with this PR as that involves taking inconsistencies between dependencies into consideration. This will be addressed in a future PR.
… r=Veykril fix: Dedup duplicate crates with differing origins in CrateGraph construction Partially fixes #15656 . Until now the condition for deduplication in crate graphs were the strict equality of two crates. One problem that arises from this is that in certain conditions when we see the same crate having different `CrateOrigin`s the first occurrence would be kept. This approach however results in some unwanted results such as making renaming forbidden as this has been recently only made available for local crates. The given example in #15656 can still not be resolved with this PR as that involves taking inconsistencies between dependencies into consideration. This will be addressed in a future PR.
I can confirm that with 0.3.1748 I am now able to rename symbols in |
Unfortunately I may have celebrated too soon. Renaming does work in Perhaps that crate triggers one of the more complicated scenarios not fixed by #15754. |
Ugh, ye that is annoying... We can't really deduplicate these crates, since the out dirs should point into the respective target dirs here. Deduplicating might just work for one crate, but another might break because it now no longer finds its corresponding output. |
I think we might just wanna put the accidental library rename prevention behind a config and tell the user in the error message that they can disable it by setting "" to false. As I don't see a way to fix this concrete case here (though I am open for ideas), and I know that a bunch of people are annoyed by this issue. (Though at least we managed to push deduplication further thanks to this so thats a net win anyways) |
I don't really understand why this is related to duplication at all. Why isn't our logic just "if it's inside the LSP root directory, we can rename it"? |
The problem is that the LSP Root directory can be completely unrelated to the workspaces, you can open a workspace in |
One thing we should change still though is to treat |
What would be the problem with that though? I mean, we should allow renaming in all workspace folders of course. But to me it still seems like the VSCode workspace == the set of folders where the user wants to make changes. |
I'm saying that the the opened cargo workspaces may not lie inside the lsp workspace root, it technically is just an arbitrary path. But you raise a good point, maybe we need to change what we consider a local crate, that is currently the "CrateOrigin" is determined on a per cargo workspace basis, though really it should probably be set on a global LSP workspace basis? (That is consider everything local that is inside any cargo workspace member?) I think that is effectively what you are saying. |
I think that's what I'm saying, yes 😅 It just fundamentally doesn't make sense to me that we could consider only one version of a crate in a specific folder local and the other not, it should be purely a property of the folder they're in. |
Do you mean like At least that's how I interpreted that setting. |
Yes, all discovered and loaded projects, whether explicitly set via |
CrateGraph has been suffering from ignoring a unified definition of a Workspace : Cargo rightly assumes that each project has its own workspace but in RA this assumption does not hold and this has caused problems for renaming symbols ( rust-lang#15656 ). What I propose is to add a new variant to `CrateOrigin` called `Member` ( the name is open to discussion :D ). Member will be assigned to workspace members and this is easy to find out as cargo provides this information directly. `CrateOrigin::Local` will now be those crates that workspaces depend on and these crates need to be in the local filesystem and open to editing ( current state of things doesn't really reflect what I describe but anyway... ) and `CrateOrigin::Library` will be the *vendor* crates. By doing this we can now express things like "a symbol is renameable if it originates from a user defined crate ( meaning if `CrateOrigin` is `Local` or `Member`)". This follows in part @ogapo's findings so let's thank them too!
First of all, I would like to say that I am very grateful for this amazing project. I'm aware it has a very complex codebase. I don't remember a single occasion where I accidentally renamed an item that wasn't in my project. Now I can't rename anything anymore. This is affecting our workflow. While we don't have a bug fix, is it possible to create a configuration to not do this rename check? |
I agree with @vaniusrb. This has also been quite detrimental to our workflow. We find most of our refactoring now consists of "ctrl + f" and "replace" which is less than ideal and prone to errors. |
Adding a config was on my TODO list, let me work on it now and get back to you in a few hours. Sorry for the inconvenience! |
Thank you @alibektas! :) No sorries necessary! :) |
With rust-lang#15656 we started disallowing renaming of non-local items. Although this makes sense there are some false positives that impacted users' workflows. So this config aims to mitigate this by giving users the liberty to disable this feature.
With rust-lang#15656 we started disallowing renaming of non-local items. Although this makes sense there are some false positives that impacted users' workflows. So this config aims to mitigate this by giving users the liberty to disable this feature.
So if everything goes well 🤞 with today's nightly this config should be available. You will just need to set the following config to "true", we defaulted it to "false" to make the feature visible to users, as it works just fine for most of the time. Here is the related piece in the documentation [[rust-analyzer.rename.allowExternalItems]]rust-analyzer.rename.allowExternalItems (default: `false`)::
+
--
Allow renaming of items not belonging to the loaded workspaces.
-- |
…Veykril Add a new config to allow renaming of non-local defs With #15656 we started disallowing renaming of non-local items. Although this makes sense there are some false positives that impacted users' workflows. So this config aims to mitigate this by giving users the liberty to disable this feature. The reason why this is a draft is that I saw one of the tests fail and I am not sure if the "got" result even syntactically makes sense Test case is : ```rust check( "Baz", r#" //- /lib.rs crate:lib new_source_root:library pub struct S; //- /main.rs crate:main deps:lib new_source_root:local use lib::S$0; "#, "use lib::Baz;" ); ``` ``` Left: use lib::Baz; Right: use lib::Baz;Baz Diff: use lib::Baz;Baz ```
@alibektas will I be able to test it out in the vs code pre-release version? Or what is the best way to test it? |
Honestly I have always built from the source by running just And mind you that the feature will be available around 01:15 CET based on the most recent release time from yesterday. |
@alibektas first initial test seems to indicate that its working! :) I'm going to try it for a bit and see if I run into any issues with it! :) |
Hi, @alibektas! I just tried. It worked like a charm! I'm proud of you and this community. Thank you very much. |
System Details
rust-analyzer version: 0.3.1665-standalone (first broken stable version)
rustc version: rustc 1.72.1 (d5c2e9c34 2023-09-13)
Details
Since
v0.4.1658-standalone
it is not possible to rename any item inside one of my projects. More details in reproduction section.Regression
Broken since
v0.4.1658-standalone
(nightly). Earlier versions work as expected.1658 (first broken ver.):
Actions Run: https://github.com/rust-lang/rust-analyzer/actions/runs/6153193088
Commit: cc6c820
1655 (previous functional release):
Commit: 994df3d
I believe this was introduced in #15232 .
However probably not directly caused by said commit (the commit seems to restrict needed functionality), but an unexpected edge case where a local item is believed to be non-local.
Reproduction
I have tried to create a minimal reproduction, however did not succeed in creating a minimal repro (I even tried copying dependency structure and workspace code settings).
So I am forced to instead link to one of my real [WIP] projects.
Reproduction Steps:
https://github.com/Reloaded-Project/Reloaded.Hooks-rs.git
main
.vscode/settings.json
->rust-analyzer.linkedProjects
.reloaded-hooks-portable
such asprojects/reloaded-hooks-portable/src/api/wrapper_instruction_generator.rs
.It is not possible to rename any type or even local variable due to:
The text was updated successfully, but these errors were encountered: