-
Notifications
You must be signed in to change notification settings - Fork 17
Description
#[auto_impl(&)]
trait Foo {
fn foo<T>();
fn bar<U>(&self);
}Is expanded into:
impl<'a, V: 'a + Foo> Foo for &'a V {
fn foo<T>() {
V::foo() // <-- cannot infer type for `T`
}
fn bar<U>(&self) {
(**self).bar() // <-- cannot infer type for `U`
}
}And results in two compiler errors. So we need to change the method body into an explicit call all of the time. In this case:
V::foo::<T>(), andV::bar::<T>(*self)
I can mentor anyone interested in tackling this issue :)
Just ping me (via email, this issue, or in any other way)
Instructions: code generation of methods is done in gen_method_item in gen.rs. The important part for this issue are the last two arms of the last match statement in the function (SelfType::Value and SelfType::Ref | SelfType::Mut). These generate incorrect code. You can see the generated code in the quote! {} macro.
The most difficult part is probably to generate the list of generic parameters to call the other method. In the example above it's simply <T>, but it could be more complicated. In gen_method_item(), we have the variable sig which is a syn::MethodSig. We are interested in sig.decl.generics which stores the generics of the method we are generating. Sadly, we can't just use that: e.g. fn foo<T: Clone, U>() would have <T: Clone, U> as generics and we can't call foo::<T: Clone, U>(), but need to call foo::<T, U>(). So we might have to remove all bounds. But with some luck, we can use syn::Generics::split_for_impl. The second element of the returned tuple should be what we want. But we need to test that!
Finally, one or more compile-pass tests should be added which test this exact code.
If anything is unclear, just go ahead and ask!