@@ -345,6 +345,48 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
345345 }
346346 }
347347
348+ fn visit_fn_decl ( & mut self , fd : & ' tcx hir:: FnDecl < ' tcx > ) {
349+ let output = match fd. output {
350+ hir:: FnRetTy :: DefaultReturn ( _) => None ,
351+ hir:: FnRetTy :: Return ( ref output) => {
352+ let parent = self . tcx . hir ( ) . get_parent_node ( output. hir_id ) ;
353+ let static_for_output = match self . tcx . hir ( ) . get ( parent) {
354+ // `fn` definitions and methods.
355+ Node :: Item ( _) | Node :: TraitItem ( _) | Node :: ImplItem ( _) => true ,
356+
357+ // Foreign functions, `fn(...) -> R` and `Trait(...) -> R` (both types and bounds).
358+ Node :: ForeignItem ( _) | Node :: Ty ( _) | Node :: TraitRef ( _) => true ,
359+
360+ Node :: TypeBinding ( _) => matches ! (
361+ self . tcx. hir( ) . get( self . tcx. hir( ) . get_parent_node( parent) ) ,
362+ Node :: TraitRef ( _)
363+ ) ,
364+
365+ // Everything else (only closures?) doesn't
366+ // actually enjoy elision in return types.
367+ _ => false ,
368+ } ;
369+ Some ( ( output, static_for_output) )
370+ }
371+ } ;
372+
373+ // Lifetime elision prescribes a `'static` default lifetime.
374+ let scope = Scope :: ObjectLifetimeDefault { lifetime : Some ( Region :: Static ) , s : self . scope } ;
375+ self . with ( scope, |this| {
376+ for ty in fd. inputs {
377+ this. visit_ty ( ty)
378+ }
379+
380+ if let Some ( ( output, static_for_output) ) = output && static_for_output {
381+ this. visit_ty ( output)
382+ }
383+ } ) ;
384+
385+ if let Some ( ( output, static_for_output) ) = output && !static_for_output {
386+ self . visit_ty ( output)
387+ }
388+ }
389+
348390 fn visit_path ( & mut self , path : & ' tcx hir:: Path < ' tcx > , _: hir:: HirId ) {
349391 for ( i, segment) in path. segments . iter ( ) . enumerate ( ) {
350392 let depth = path. segments . len ( ) - i - 1 ;
@@ -423,11 +465,17 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
423465 generic_args : & ' tcx hir:: GenericArgs < ' tcx > ,
424466 ) {
425467 if generic_args. parenthesized {
426- for input in generic_args. inputs ( ) {
427- self . visit_ty ( input) ;
428- }
429- let output = generic_args. bindings [ 0 ] . ty ( ) ;
430- self . visit_ty ( output) ;
468+ // Lifetime elision rules require us to use a `'static` default lifetime.
469+ let scope =
470+ Scope :: ObjectLifetimeDefault { lifetime : Some ( Region :: Static ) , s : self . scope } ;
471+ self . with ( scope, |this| {
472+ for input in generic_args. inputs ( ) {
473+ this. visit_ty ( input) ;
474+ }
475+
476+ let output = generic_args. bindings [ 0 ] . ty ( ) ;
477+ this. visit_ty ( output) ;
478+ } ) ;
431479 return ;
432480 }
433481
0 commit comments