diff --git a/src/gen.rs b/src/gen.rs index e768a90..f725b4e 100644 --- a/src/gen.rs +++ b/src/gen.rs @@ -2,16 +2,16 @@ use crate::proc_macro::Span; use proc_macro2::TokenStream as TokenStream2; use quote::{ToTokens, TokenStreamExt}; use syn::{ - FnArg, Ident, ItemTrait, Lifetime, MethodSig, Pat, PatIdent, TraitItem, TraitItemMethod, - TraitItemType, TraitItemConst, + FnArg, Ident, ItemTrait, Lifetime, MethodSig, Pat, PatIdent, TraitItem, TraitItemConst, + TraitItemMethod, TraitItemType, }; use crate::{ analyze::find_suitable_param_names, - attr::{OurAttr, is_our_attr, parse_our_attr}, + attr::{is_our_attr, parse_our_attr, OurAttr}, diag::{DiagnosticExt, SpanExt}, proxy::ProxyType, - spanned::Spanned + spanned::Spanned, }; @@ -430,6 +430,10 @@ fn gen_method_item( // Generate the list of argument used to call the method. let args = get_arg_list(sig.decl.inputs.iter())?; + // Builds turbofish with generic types + let (_, generic_types, _) = sig.decl.generics.split_for_impl(); + let generic_types = generic_types.as_turbofish(); + // Generate the body of the function. This mainly depends on the self type, // but also on the proxy type. let name = &sig.ident; @@ -442,20 +446,20 @@ fn gen_method_item( // No receiver SelfType::None => { // The proxy type is a reference, smartpointer or Box. - quote! { #proxy_ty_param::#name(#args) } + quote! { #proxy_ty_param::#name #generic_types(#args) } } // Receiver `self` (by value) SelfType::Value => { // The proxy type is a Box. - quote! { (*self).#name(#args) } + quote! { (*self).#name#generic_types(#args) } } // `&self` or `&mut self` receiver SelfType::Ref | SelfType::Mut => { // The proxy type could be anything in the `Ref` case, and `&mut` // or Box in the `Mut` case. - quote! { (**self).#name(#args) } + quote! { (*self).#name#generic_types(#args) } } }; diff --git a/tests/compile-pass/non_inferred_generic_types_for_all_refs.rs b/tests/compile-pass/non_inferred_generic_types_for_all_refs.rs new file mode 100644 index 0000000..0dcc0cc --- /dev/null +++ b/tests/compile-pass/non_inferred_generic_types_for_all_refs.rs @@ -0,0 +1,7 @@ +use auto_impl::auto_impl; + +#[auto_impl(&)] +trait Foo { + fn foo(); + fn bar(&self); +} diff --git a/tests/compile-pass/non_inferred_generic_types_for_box.rs b/tests/compile-pass/non_inferred_generic_types_for_box.rs new file mode 100644 index 0000000..00be69a --- /dev/null +++ b/tests/compile-pass/non_inferred_generic_types_for_box.rs @@ -0,0 +1,9 @@ +use auto_impl::auto_impl; + +#[auto_impl(Box)] +trait Foo { + fn foo(); + fn bar(&self); + fn baz(&mut self); + fn qux(self); +} diff --git a/tests/compile-pass/non_inferred_generic_types_with_lifetimes_for_all_refs.rs b/tests/compile-pass/non_inferred_generic_types_with_lifetimes_for_all_refs.rs new file mode 100644 index 0000000..5066e97 --- /dev/null +++ b/tests/compile-pass/non_inferred_generic_types_with_lifetimes_for_all_refs.rs @@ -0,0 +1,9 @@ +use auto_impl::auto_impl; + +#[auto_impl(&)] +trait Foo { + fn foo(); + fn bar(&self); + fn baz<'a, U>() -> &'a str; + fn qux<'a, 'b, 'c, U, V, T>(&self) -> (&'a str, &'b str, &'c str); +}