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
feature : assist delegate impl #14948
Conversation
#14957 has a valid point that we may need to fix as well. |
We can add a comment to that issue once this PR is merged. There are probably more assists that should look into that. |
// FIXME : We can omit already implemented impl_traits | ||
// But we don't know what the &[hir::Type] argument should look like. |
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.
For this I think we need to make use of TraitRef
s instead of plain Trait
s. TraitRef
s basically consist of a Trait
and it's arguments, given we expose TraitRef
s in hir now we might as well want to change Type::impls_trait
to take a TraitRef instead, or make a new method that accepts one. But let's leave that for a follow up
After the latest version the problem for which I left a GIF above has been solved. There are still a few other problems though. One problem was briefly mentioned above in GIF(2) , that in certain cases we generate trait implementation for |
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.
Okay, this mostly looks good but there is one thing that we should fix still, which can be seen in your second gif (im not talking about the unstable thing being proposed). We forget to account for the substituted generics. Example:
struct S { f: Foo<i32>$0 }
struct Foo<U>(U);
trait T<U> {
type Ty;
fn f(self) -> Self::Ty;
}
impl<U> T<U> for Foo<U> {
type Ty = U;
fn f(self) -> Self::Ty {
self.0
}
}
Current assist would generate the following which is invalid
impl<U> T<U> for S {
type Ty = <Foo<U> as T<U>>::Ty;
fn f(self) -> Self::Ty {
<Foo<U> as T<U>>::f(self.f) // type error, `<Foo<U> as T<U>>::f` expects a value of type `Foo<U>`, but here we give it a `Foo<i32>`
}
}
It should instead generate this:
impl T<i32> for S {
type Ty = <Foo<i32> as T<i32>>::Ty;
fn f(self) -> Self::Ty {
<Foo<i32> as T<i32>>::f(self.f)
}
}
Actually, fixing that seems pretty tricky so lets leave that out of this PR for a follow up. |
☀️ Test successful - checks-actions |
This PR ( fixes #14386 ) introduces a new IDE assist that generates a trait impl for a struct that delegates a field. This is a draft because the current
ide_db::path_transform::PathTransform
produces some unwanted results when it deals with extern crates, an example of which I attach as a GIF.GIFs :
A general case
A case where
ide_db::path_transform::PathTransform
fails to correctly resolve a property ( takeAllocator
as an example ) to its full path, thus causing an error to occur. ( Not to even mention that resolving this causes another erroruse of unstable library feature 'allocator_api'
to occur