-
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
Add generic parameter assist #15510
Add generic parameter assist #15510
Conversation
☔ The latest upstream changes (presumably #15528) made this pull request unmergeable. Please resolve the merge conflicts. |
There are merge commits (commits with multiple parents) in your changes. We have a no merge policy so these commits will need to be removed for this pull request to be merged. You can start a rebase with the following commands:
The following commits are merge commits: |
09551c5
to
6f9de84
Compare
I'm not sure what I'm supposed to do to make this PR mergeable.
What should I do to make this pull request mergeable? |
Thanks for the PR! For fixing the merge commit problem, reset your branch to the original commit before the merge commit, then run
See tests in this file:
I think just omitting the assist if it is not applicable due some problem is fine. If the error indicates some bug in the implementation, you can use the
The idea is that assists provide a simple and atomic ability, and user can combine them by repeatedly invoking them. For example for "add multiple generic parameters, with bounds: <'a, T: Clone, const N: usize>" user can repeatedly invoke the "add generic parameter", and another imaginary assist "add bound to this generic parameter" to achieve this behavior.
I think it is fine, and it is used in other assists (for example "Extract to function" uses |
7f10358
to
0bf1cd5
Compare
Reply: multi file: powerful assists: error: placeholder names: struct A<T1>(); struct B<T1>(A<T1>);
^^ ^^----^^ these are independent symbols, so one would have to change A's and B's parameter (2 renames by the user). new: I had to modify code in search.rs to support adding generic parameters through aliases. Should this be in a different PR? |
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.
Sorry for not having looked at this for so long, I just dread reviewing PRs that have a massive diff like this (and I dread reviewing assists generally as well 😅). I still haven't given the assist code a review either yet, but the one thing that immediately stood out are the unrelated changes so it would be good to revert that first after which I'll take a look.
@@ -318,6 +318,7 @@ impl Definition { | |||
def: self, | |||
assoc_item_container: self.as_assoc_item(sema.db).map(|a| a.container(sema.db)), | |||
sema, | |||
override_name: None, |
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.
Let's revert all of the changes in search.rs
. import renames are in generally not yet supported and this PR should not attempt to fix that
I'll close this for now due to inactivity, if you get back to this feel free to re-open |
Closes #12531
Supported features
Add a generic type parameter to anything that can take one. This includes struct, enum, union, fn, trait, type alias, trait alias, use alias.
Note that this produces code that does not compile, as the generic parameter must be used, and the assist does not add a member to the struct/enum/etc.
All of these examples are listed in the tests section at the bottom of the assist file (crates/ide-assists/src/handlers/add_generic_parameter.rs), but are some duplicated here for exposition:
Basic nesting (works same for enums, unions, traits)
It works for cyclic structs/etc, and adds the parameter on impls.
For traits, it adds the generic to the trait, rather than the function. This seems to generally be the desired outcome
For impls, it uses the impl's generic, but if there is none, it adds to the innermost (likely a function)
Use aliases:
Type/trait aliases:
More complicated interaction through a trait:
I've tested this on toy AST's and it works fine, but I haven't tried larger scenarios. Larger things might try to modify things (e.g. traits) that aren't owned by the user, which could be problematic.
Showcase
Future
I'd like to have the user pick the generic parameter name. I just use
T1
right now.I haven't implemented solving name collisions, like the following, which would add a duplicate the
T1
parameter:I'd like to add support for bounds and more kinds of generics (const, lifetime), but it is unclear how to add it to the editor/lsp, read below.
test for edge cases since many different kinds of things can have generics and interact with each other.
Is there anything I'm not seeing that could be improved, changed?
I'd like some external direction in how to workflow, contribute better/easier, optimize, clean up, etc.
About the coding
I have a few difficulty/uncertainty points when making this:
rust-analyzer questions
general assist questions:
how are small details discussed?
T1
be a placeholder selected by the user after assist execution)specific to add_generic_parameter: