@@ -430,9 +430,39 @@ fn gen_method_item(
430
430
// Generate the list of argument used to call the method.
431
431
let args = get_arg_list ( sig. decl . inputs . iter ( ) ) ?;
432
432
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
+ } ;
436
466
437
467
// Generate the body of the function. This mainly depends on the self type,
438
468
// but also on the proxy type.
@@ -452,14 +482,14 @@ fn gen_method_item(
452
482
// Receiver `self` (by value)
453
483
SelfType :: Value => {
454
484
// The proxy type is a Box.
455
- quote ! { ( * self ) . #name#generic_types( #args) }
485
+ quote ! { ( * self ) . #name #generic_types( #args) }
456
486
}
457
487
458
488
// `&self` or `&mut self` receiver
459
489
SelfType :: Ref | SelfType :: Mut => {
460
490
// The proxy type could be anything in the `Ref` case, and `&mut`
461
491
// or Box in the `Mut` case.
462
- quote ! { ( * self ) . #name#generic_types( #args) }
492
+ quote ! { ( * self ) . #name #generic_types( #args) }
463
493
}
464
494
} ;
465
495
0 commit comments