-
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
feat!: create alias when renaming an import. #16489
feat!: create alias when renaming an import. #16489
Conversation
7efc70e
to
2c2a7a1
Compare
👋 Thank you for this PR! I have also seen the your post in the related issue. I am not well acquainted with the inner workings of the renaming infra and honestly I have only taken a short glance at it but maybe you could enlighten me on sth: Why don't you have your aliasing implementation propagate all the way through
Ofc the editing that an alias would cause is very different to the import statement but on the other hand not so different for the defs affected by it, something we can leverage. And one more thing to keep in mind : We don't like |
That is a good question; it just seemed easier to implement at the
Not really; the way that I see it is that a rename is "absolute"; if an item gets renamed then all references needs to update their name too, because, no matter if the item path is qualified or not, they all need to point to the To the contrary, an alias is "relative"; you only change references that directly depend on that particular item name. A more "formal" way to express this would be to say that, if So, with the example of yesterday: pub mod foo { pub struct Foo; }
use foo::Foo$0;
fn main() {
let _: Foo; // Changes, because directly depends (uses) `Foo`.
let _: foo::Foo; // This doesn't get changed; points to same reference, but
// doesn't depend (use) the `Foo` that is in the module/scope.
} But lets make this "minimal" example a little more complicated: pub mod foo { pub struct Foo; }
pub mod foo2 { pub struct Foo; }
mod bar {
use super::Foo; // Changes, because directly depends (uses) `Foo`.
}
mod baz {
use crate::Foo; // Changes, because directly depends (uses) `Foo`.
}
use foo::Foo$0;
fn main() {
let _: Foo; // Changes, because directly depends (uses) `Foo`.
let _: self::Foo; // Changes, because directly depends (uses) `Foo`. (`self`
// == current scope/mod).
let _: foo::Foo; // This doesn't get changed; points to same reference, but
// doesn't use the `Foo` that is in the module/scope.
let _: foo2::Foo; // This doesn't get changed; points to different reference.
} Currently, all but
I think is the other way around; the editing part (editing/updating the ast) is the same, but what defs that are affected is different (like I explained above). I think the only place that we would need to change on rust-analyzer/crates/ide-db/src/rename.rs Line 340 in 2c2a7a1
If we are using alias as a fallback (the easiest way to check this is to just add a I have been thinking that we might be able to add a new "parameter" to the builder pattern of Sorry if I make this way more longer that it should have been; I just wanted to give a more detailed problem perspective, in the hopes that we can see if I'm missing something obvious 😅.
Yeah sure; I wasn't very sure how I should write "this option can't be /cc @Veykril You might have something to say about all this? |
crates/ide/src/rename.rs
Outdated
@@ -131,6 +160,46 @@ pub(crate) fn will_rename_file( | |||
Some(change) | |||
} | |||
|
|||
// FIXME: Allow usage with `extern crate`? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we should support that all the same
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that this is blocked on usages.all()
not being able to find references to extern crate
modules.
This I don't think we should do as that is a more invasive change in the end (splits the imports etc). |
The problem of usages relying on the "re-export" of an import is tricky indeed. I am not sure if we already have everything in place to do that properly yet (I don't think we do), as that requires keeping track of what import a usage refers to (this we have), and then resolving the imports step by step (this we are still missing I believe) such that we can check whether the renamed import affects the usage or not. Though we most likely want a new flag on the usage search for that. |
Ok that sounds unfortunate; I'm gonna try implement it on these next days. I gave a look at Thanks for the heads up though 👍. |
It's fine if we can't handle that case properly for now though,as long as we open an issue / fixme for that. Most people will use absolute paths for things, especially if they have the default rust-analyzer settings. |
@UserIsntAvailable this is mostly my fault, sorry! Whatever you can't/won't do I can do afterwards. |
2c2a7a1
to
cb678db
Compare
I'm fine with that; I just didn't want to leave this on a somewhat broken state.
Don't worry about it! I wasn't really sure if it was fine to merge this as is, then do the other necessary changes on another PR. If you want to do it I don't have any problem with it! |
@rustbot label -S-waiting-on-author +S-waiting-on-review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems good to me, as noted by the FIXME, this can be done more properly via ide_db::rename_reference
once we have #14079 fully done. I believe we can already implement the renaming for extern crate foo
correctly as we have that in the Definition
.
Is this considered ready from your PoV? (asking since its still a draft) |
☔ The latest upstream changes (presumably #16586) made this pull request unmergeable. Please resolve the merge conflicts. |
@Veykril Oops, I thought I marked it as ready. 👍 |
cb678db
to
7c477e2
Compare
123cd8a
to
6aa1e9b
Compare
test: include `rename_path_inside_use_tree`. Keeps tracks the progress of the changes. 3 other tests broke with the changes of this. feat: rename all other usages within the current file. feat: fix most of the implementation problems. test: `rename_path_inside_use_tree` tests a more complicated scenario.
6aa1e9b
to
bf0aee4
Compare
bf0aee4
to
6dd5dc1
Compare
Rebased it, thanks! |
☀️ Test successful - checks-actions |
Closes #15858
Implemented:
reserved
keywords (e.g self) and_
.Future possibilities:
extern crate <name>
syntax.self
when it is inside anUseTreeList
.3. If import path already has an alias, "rename" the alias.4. Create alias even if path is not the last path segment.