@@ -345,6 +345,48 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
345
345
}
346
346
}
347
347
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
+
348
390
fn visit_path ( & mut self , path : & ' tcx hir:: Path < ' tcx > , _: hir:: HirId ) {
349
391
for ( i, segment) in path. segments . iter ( ) . enumerate ( ) {
350
392
let depth = path. segments . len ( ) - i - 1 ;
@@ -423,11 +465,17 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
423
465
generic_args : & ' tcx hir:: GenericArgs < ' tcx > ,
424
466
) {
425
467
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
+ } ) ;
431
479
return ;
432
480
}
433
481
0 commit comments