@@ -430,9 +430,39 @@ fn gen_method_item(
430430    // Generate the list of argument used to call the method. 
431431    let  args = get_arg_list ( sig. decl . inputs . iter ( ) ) ?; 
432432
433-     // Builds turbofish with generic types 
434-     let  ( _,  generic_types,  _)  = sig. decl . generics . split_for_impl ( ) ; 
435-     let  generic_types = generic_types. as_turbofish ( ) ; 
433+     // Build the turbofish type parameters. We need to pass type parameters 
434+     // explicitly as they cannot be inferred in all cases (e.g. something like 
435+     // `mem::size_of`). However, we don't explicitly specify lifetime 
436+     // parameters. Most lifetime parameters are so called late-bound lifetimes 
437+     // (ones that stick to input parameters) and Rust prohibits us from 
438+     // specifying late-bound lifetimes explicitly (which is not a problem, 
439+     // because those can always be correctly inferred). It would be possible to 
440+     // explicitly specify early-bound lifetimes, but this is hardly useful. 
441+     // Early-bound lifetimes are lifetimes that are only attached to the return 
442+     // type. Something like: 
443+     // 
444+     //     fn foo<'a>() -> &'a i32 
445+     // 
446+     // It's hard to imagine how such a function would even work. So since those 
447+     // functions are really rare and special, we won't support them. In 
448+     // particular, for us to determine if a lifetime parameter is early- or 
449+     // late-bound would be *really* difficult. 
450+     // 
451+     // So we just specify type parameters. In the future, however, we need to 
452+     // add support for const parameters. But those are not remotely stable yet, 
453+     // so we can wait a bit still. 
454+     let  generic_types = sig. decl . generics 
455+         . type_params ( ) 
456+         . map ( |param| { 
457+             let  name = & param. ident ; 
458+             quote !  {  #name ,  } 
459+         } ) 
460+         . collect :: < TokenStream2 > ( ) ; 
461+     let  generic_types = if  generic_types. is_empty ( )  { 
462+         generic_types
463+     }  else  { 
464+         quote  !  {  :: <#generic_types> } 
465+     } ; 
436466
437467    // Generate the body of the function. This mainly depends on the self type, 
438468    // but also on the proxy type. 
@@ -452,14 +482,14 @@ fn gen_method_item(
452482        // Receiver `self` (by value) 
453483        SelfType :: Value  => { 
454484            // The proxy type is a Box. 
455-             quote !  {  ( * self ) . #name#generic_types( #args)  } 
485+             quote !  {  ( * self ) . #name  #generic_types( #args)  } 
456486        } 
457487
458488        // `&self` or `&mut self` receiver 
459489        SelfType :: Ref  | SelfType :: Mut  => { 
460490            // The proxy type could be anything in the `Ref` case, and `&mut` 
461491            // or Box in the `Mut` case. 
462-             quote !  {  ( * self ) . #name#generic_types( #args)  } 
492+             quote !  {  ( * self ) . #name  #generic_types( #args)  } 
463493        } 
464494    } ; 
465495
0 commit comments