@@ -8,8 +8,7 @@ use rustc_hir::{GenericArg, GenericParamKind, LifetimeName, Node};
8
8
use rustc_middle:: bug;
9
9
use rustc_middle:: hir:: nested_filter;
10
10
use rustc_middle:: middle:: resolve_lifetime:: * ;
11
- use rustc_middle:: ty:: { GenericParamDefKind , TyCtxt } ;
12
- use rustc_span:: def_id:: DefId ;
11
+ use rustc_middle:: ty:: { DefIdTree , GenericParamDefKind , TyCtxt } ;
13
12
use rustc_span:: symbol:: sym;
14
13
use std:: borrow:: Cow ;
15
14
@@ -447,15 +446,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
447
446
return ;
448
447
}
449
448
449
+ let tcx = self . tcx ;
450
+
450
451
// Figure out if this is a type/trait segment,
451
452
// which requires object lifetime defaults.
452
- let parent_def_id = |this : & mut Self , def_id : DefId | {
453
- let def_key = this. tcx . def_key ( def_id) ;
454
- DefId { krate : def_id. krate , index : def_key. parent . expect ( "missing parent" ) }
455
- } ;
456
453
let type_def_id = match res {
457
- Res :: Def ( DefKind :: AssocTy , def_id) if depth == 1 => Some ( parent_def_id ( self , def_id) ) ,
458
- Res :: Def ( DefKind :: Variant , def_id) if depth == 0 => Some ( parent_def_id ( self , def_id) ) ,
454
+ Res :: Def ( DefKind :: AssocTy , def_id) if depth == 1 => Some ( tcx . parent ( def_id) ) ,
455
+ Res :: Def ( DefKind :: Variant , def_id) if depth == 0 => Some ( tcx . parent ( def_id) ) ,
459
456
Res :: Def (
460
457
DefKind :: Struct
461
458
| DefKind :: Union
@@ -468,22 +465,24 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
468
465
} ;
469
466
debug ! ( ?type_def_id) ;
470
467
471
- // Compute a vector of defaults, one for each type parameter,
472
- // per the rules given in RFCs 599 and 1156. Example:
473
- //
474
- // ```rust
475
- // struct Foo<'a, T: 'a, U> { }
476
- // ```
477
- //
478
- // If you have `Foo<'x, dyn Bar, dyn Baz>`, we want to default
479
- // `dyn Bar` to `dyn Bar + 'x` (because of the `T: 'a` bound)
480
- // and `dyn Baz` to `dyn Baz + 'static` (because there is no
481
- // such bound).
482
- //
483
- // Therefore, we would compute `object_lifetime_defaults` to a
484
- // vector like `['x, 'static]`. Note that the vector only
485
- // includes type parameters.
486
- let object_lifetime_defaults = type_def_id. map_or_else ( Vec :: new, |def_id| {
468
+ if let Some ( type_def_id) = type_def_id {
469
+ // Compute a vector of defaults, one for each type parameter,
470
+ // per the rules given in RFCs 599 and 1156. Example:
471
+ //
472
+ // ```rust
473
+ // struct Foo<'a, T: 'a, U> { }
474
+ // ```
475
+ //
476
+ // If you have `Foo<'x, dyn Bar, dyn Baz>`, we want to default
477
+ // `dyn Bar` to `dyn Bar + 'x` (because of the `T: 'a` bound)
478
+ // and `dyn Baz` to `dyn Baz + 'static` (because there is no
479
+ // such bound).
480
+ //
481
+ // Therefore, we would compute `object_lifetime_defaults` to a
482
+ // vector like `['x, 'static]`. Note that the vector only
483
+ // includes type parameters.
484
+ let generics = self . tcx . generics_of ( type_def_id) ;
485
+
487
486
let in_body = {
488
487
let mut scope = self . scope ;
489
488
loop {
@@ -498,7 +497,16 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
498
497
}
499
498
}
500
499
} ;
501
- let generics = self . tcx . generics_of ( def_id) ;
500
+ let object_lifetime_default = |i : usize | {
501
+ let param = generics. params . get ( i) ?;
502
+ match param. kind {
503
+ GenericParamDefKind :: Type { object_lifetime_default, .. } => {
504
+ Some ( object_lifetime_default)
505
+ }
506
+ GenericParamDefKind :: Const { .. } => Some ( ObjectLifetimeDefault :: Empty ) ,
507
+ GenericParamDefKind :: Lifetime => return None ,
508
+ }
509
+ } ;
502
510
let set_to_region = |set : ObjectLifetimeDefault | match set {
503
511
ObjectLifetimeDefault :: Empty => {
504
512
if in_body {
@@ -509,51 +517,32 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
509
517
}
510
518
ObjectLifetimeDefault :: Static => Some ( Region :: Static ) ,
511
519
ObjectLifetimeDefault :: Param ( def_id) => {
512
- let index = generics. param_def_id_to_index [ & def_id] ;
520
+ let index = * generics. param_def_id_to_index . get ( & def_id) ? ;
513
521
generic_args. args . get ( index as usize ) . and_then ( |arg| match arg {
514
- GenericArg :: Lifetime ( lt) => self . tcx . named_region ( lt. hir_id ) ,
522
+ GenericArg :: Lifetime ( lt) => tcx. named_region ( lt. hir_id ) ,
515
523
_ => None ,
516
524
} )
517
525
}
518
526
ObjectLifetimeDefault :: Ambiguous => None ,
519
527
} ;
520
- generics
521
- . params
522
- . iter ( )
523
- . filter_map ( |param| match param. kind {
524
- GenericParamDefKind :: Type { object_lifetime_default, .. } => {
525
- Some ( object_lifetime_default)
526
- }
527
- GenericParamDefKind :: Const { .. } => Some ( ObjectLifetimeDefault :: Empty ) ,
528
- GenericParamDefKind :: Lifetime => None ,
529
- } )
530
- . map ( set_to_region)
531
- . collect ( )
532
- } ) ;
533
- debug ! ( ?object_lifetime_defaults) ;
534
-
535
- let mut i = 0 ;
536
- for arg in generic_args. args {
537
- match arg {
538
- GenericArg :: Lifetime ( _) => { }
539
- GenericArg :: Type ( ty) => {
540
- if let Some ( & lt) = object_lifetime_defaults. get ( i) {
541
- let scope = Scope :: ObjectLifetimeDefault { lifetime : lt, s : self . scope } ;
528
+
529
+ for ( i, arg) in generic_args. args . iter ( ) . enumerate ( ) {
530
+ if let GenericArg :: Type ( ty) = arg {
531
+ if let Some ( default) = object_lifetime_default ( i) {
532
+ let lifetime = set_to_region ( default) ;
533
+ let scope = Scope :: ObjectLifetimeDefault { lifetime, s : self . scope } ;
542
534
self . with ( scope, |this| this. visit_ty ( ty) ) ;
543
535
} else {
544
536
self . visit_ty ( ty) ;
545
537
}
546
- i += 1 ;
547
- }
548
- GenericArg :: Const ( ct) => {
549
- self . visit_anon_const ( & ct. value ) ;
550
- i += 1 ;
551
- }
552
- GenericArg :: Infer ( inf) => {
553
- self . visit_id ( inf. hir_id ) ;
554
- i += 1 ;
538
+ } else {
539
+ self . visit_generic_arg ( arg) ;
555
540
}
556
541
}
542
+ } else {
543
+ for arg in generic_args. args {
544
+ self . visit_generic_arg ( arg) ;
545
+ }
557
546
}
558
547
559
548
// Hack: when resolving the type `XX` in binding like `dyn
0 commit comments