@@ -621,140 +621,135 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
621
621
} ;
622
622
self . with ( scope, |_, this| this. visit_ty ( & mt. ty ) ) ;
623
623
}
624
- hir:: TyKind :: Path ( hir:: QPath :: Resolved ( None , ref path) ) => {
625
- if let Def :: Existential ( exist_ty_did) = path. def {
626
- let id = self . tcx . hir . as_local_node_id ( exist_ty_did) . unwrap ( ) ;
627
-
628
- // Resolve the lifetimes in the bounds to the lifetime defs in the generics.
629
- // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
630
- // `abstract type MyAnonTy<'b>: MyTrait<'b>;`
631
- // ^ ^ this gets resolved in the scope of
632
- // the exist_ty generics
633
- let ( generics, bounds) = match self . tcx . hir . expect_item ( id) . node {
634
- // named existential types don't need these hacks
635
- hir:: ItemKind :: Existential ( hir:: ExistTy { impl_trait_fn : None , .. } ) => {
636
- intravisit:: walk_ty ( self , ty) ;
637
- return ;
638
- } ,
639
- hir:: ItemKind :: Existential ( hir:: ExistTy {
640
- ref generics,
641
- ref bounds,
642
- ..
643
- } ) => (
644
- generics,
645
- bounds,
646
- ) ,
647
- ref i => bug ! ( "impl Trait pointed to non-existential type?? {:#?}" , i) ,
648
- } ;
624
+ hir:: TyKind :: Def ( item_id, ref lifetimes) => {
625
+ // Resolve the lifetimes in the bounds to the lifetime defs in the generics.
626
+ // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
627
+ // `abstract type MyAnonTy<'b>: MyTrait<'b>;`
628
+ // ^ ^ this gets resolved in the scope of
629
+ // the exist_ty generics
630
+ let ( generics, bounds) = match self . tcx . hir . expect_item ( item_id. id ) . node {
631
+ // named existential types are reached via TyKind::Path
632
+ // this arm is for `impl Trait` in the types of statics, constants and locals
633
+ hir:: ItemKind :: Existential ( hir:: ExistTy { impl_trait_fn : None , .. } ) => {
634
+ intravisit:: walk_ty ( self , ty) ;
635
+ return ;
636
+ } ,
637
+ // RPIT (return position impl trait)
638
+ hir:: ItemKind :: Existential ( hir:: ExistTy {
639
+ ref generics,
640
+ ref bounds,
641
+ ..
642
+ } ) => (
643
+ generics,
644
+ bounds,
645
+ ) ,
646
+ ref i => bug ! ( "impl Trait pointed to non-existential type?? {:#?}" , i) ,
647
+ } ;
648
+
649
+ // Resolve the lifetimes that are applied to the existential type.
650
+ // These are resolved in the current scope.
651
+ // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
652
+ // `fn foo<'a>() -> MyAnonTy<'a> { ... }`
653
+ // ^ ^this gets resolved in the current scope
654
+ for lifetime in lifetimes {
655
+ if let hir:: GenericArg :: Lifetime ( lifetime) = lifetime {
656
+ self . visit_lifetime ( lifetime) ;
649
657
650
- assert ! ( exist_ty_did. is_local( ) ) ;
651
- // Resolve the lifetimes that are applied to the existential type.
652
- // These are resolved in the current scope.
653
- // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
654
- // `fn foo<'a>() -> MyAnonTy<'a> { ... }`
655
- // ^ ^this gets resolved in the current scope
656
- for lifetime in & path. segments [ 0 ] . args . as_ref ( ) . unwrap ( ) . args {
657
- if let hir:: GenericArg :: Lifetime ( lifetime) = lifetime {
658
- self . visit_lifetime ( lifetime) ;
659
-
660
- // Check for predicates like `impl for<'a> Trait<impl OtherTrait<'a>>`
661
- // and ban them. Type variables instantiated inside binders aren't
662
- // well-supported at the moment, so this doesn't work.
663
- // In the future, this should be fixed and this error should be removed.
664
- let def = self . map . defs . get ( & lifetime. id ) . cloned ( ) ;
665
- if let Some ( Region :: LateBound ( _, def_id, _) ) = def {
666
- if let Some ( node_id) = self . tcx . hir . as_local_node_id ( def_id) {
667
- // Ensure that the parent of the def is an item, not HRTB
668
- let parent_id = self . tcx . hir . get_parent_node ( node_id) ;
669
- let parent_impl_id = hir:: ImplItemId { node_id : parent_id } ;
670
- let parent_trait_id = hir:: TraitItemId { node_id : parent_id } ;
671
- let krate = self . tcx . hir . forest . krate ( ) ;
672
- if !( krate. items . contains_key ( & parent_id)
673
- || krate. impl_items . contains_key ( & parent_impl_id)
674
- || krate. trait_items . contains_key ( & parent_trait_id) )
675
- {
676
- span_err ! (
677
- self . tcx. sess,
678
- lifetime. span,
679
- E0657 ,
680
- "`impl Trait` can only capture lifetimes \
681
- bound at the fn or impl level"
682
- ) ;
683
- self . uninsert_lifetime_on_error ( lifetime, def. unwrap ( ) ) ;
684
- }
658
+ // Check for predicates like `impl for<'a> Trait<impl OtherTrait<'a>>`
659
+ // and ban them. Type variables instantiated inside binders aren't
660
+ // well-supported at the moment, so this doesn't work.
661
+ // In the future, this should be fixed and this error should be removed.
662
+ let def = self . map . defs . get ( & lifetime. id ) . cloned ( ) ;
663
+ if let Some ( Region :: LateBound ( _, def_id, _) ) = def {
664
+ if let Some ( node_id) = self . tcx . hir . as_local_node_id ( def_id) {
665
+ // Ensure that the parent of the def is an item, not HRTB
666
+ let parent_id = self . tcx . hir . get_parent_node ( node_id) ;
667
+ let parent_impl_id = hir:: ImplItemId { node_id : parent_id } ;
668
+ let parent_trait_id = hir:: TraitItemId { node_id : parent_id } ;
669
+ let krate = self . tcx . hir . forest . krate ( ) ;
670
+ if !( krate. items . contains_key ( & parent_id)
671
+ || krate. impl_items . contains_key ( & parent_impl_id)
672
+ || krate. trait_items . contains_key ( & parent_trait_id) )
673
+ {
674
+ span_err ! (
675
+ self . tcx. sess,
676
+ lifetime. span,
677
+ E0657 ,
678
+ "`impl Trait` can only capture lifetimes \
679
+ bound at the fn or impl level"
680
+ ) ;
681
+ self . uninsert_lifetime_on_error ( lifetime, def. unwrap ( ) ) ;
685
682
}
686
683
}
687
684
}
688
685
}
686
+ }
689
687
690
- // We want to start our early-bound indices at the end of the parent scope,
691
- // not including any parent `impl Trait`s.
692
- let mut index = self . next_early_index_for_abstract_type ( ) ;
693
- debug ! ( "visit_ty: index = {}" , index) ;
688
+ // We want to start our early-bound indices at the end of the parent scope,
689
+ // not including any parent `impl Trait`s.
690
+ let mut index = self . next_early_index_for_abstract_type ( ) ;
691
+ debug ! ( "visit_ty: index = {}" , index) ;
694
692
695
- let mut elision = None ;
696
- let mut lifetimes = FxHashMap ( ) ;
697
- let mut type_count = 0 ;
698
- for param in & generics. params {
699
- match param. kind {
700
- GenericParamKind :: Lifetime { .. } => {
701
- let ( name, reg) = Region :: early ( & self . tcx . hir , & mut index, & param) ;
702
- if let hir:: ParamName :: Plain ( param_name) = name {
703
- if param_name. name == keywords:: UnderscoreLifetime . name ( ) {
704
- // Pick the elided lifetime "definition" if one exists
705
- // and use it to make an elision scope.
706
- elision = Some ( reg) ;
707
- } else {
708
- lifetimes. insert ( name, reg) ;
709
- }
693
+ let mut elision = None ;
694
+ let mut lifetimes = FxHashMap ( ) ;
695
+ let mut type_count = 0 ;
696
+ for param in & generics. params {
697
+ match param. kind {
698
+ GenericParamKind :: Lifetime { .. } => {
699
+ let ( name, reg) = Region :: early ( & self . tcx . hir , & mut index, & param) ;
700
+ if let hir:: ParamName :: Plain ( param_name) = name {
701
+ if param_name. name == keywords:: UnderscoreLifetime . name ( ) {
702
+ // Pick the elided lifetime "definition" if one exists
703
+ // and use it to make an elision scope.
704
+ elision = Some ( reg) ;
710
705
} else {
711
706
lifetimes. insert ( name, reg) ;
712
707
}
713
- }
714
- GenericParamKind :: Type { .. } => {
715
- type_count += 1 ;
708
+ } else {
709
+ lifetimes. insert ( name, reg) ;
716
710
}
717
711
}
712
+ GenericParamKind :: Type { .. } => {
713
+ type_count += 1 ;
714
+ }
718
715
}
719
- let next_early_index = index + type_count;
716
+ }
717
+ let next_early_index = index + type_count;
720
718
721
- if let Some ( elision_region) = elision {
722
- let scope = Scope :: Elision {
723
- elide : Elide :: Exact ( elision_region) ,
724
- s : self . scope ,
725
- } ;
726
- self . with ( scope, |_old_scope, this| {
727
- let scope = Scope :: Binder {
728
- lifetimes,
729
- next_early_index,
730
- s : this. scope ,
731
- track_lifetime_uses : true ,
732
- abstract_type_parent : false ,
733
- } ;
734
- this. with ( scope, |_old_scope, this| {
735
- this. visit_generics ( generics) ;
736
- for bound in bounds {
737
- this. visit_param_bound ( bound) ;
738
- }
739
- } ) ;
740
- } ) ;
741
- } else {
719
+ if let Some ( elision_region) = elision {
720
+ let scope = Scope :: Elision {
721
+ elide : Elide :: Exact ( elision_region) ,
722
+ s : self . scope ,
723
+ } ;
724
+ self . with ( scope, |_old_scope, this| {
742
725
let scope = Scope :: Binder {
743
726
lifetimes,
744
727
next_early_index,
745
- s : self . scope ,
728
+ s : this . scope ,
746
729
track_lifetime_uses : true ,
747
730
abstract_type_parent : false ,
748
731
} ;
749
- self . with ( scope, |_old_scope, this| {
732
+ this . with ( scope, |_old_scope, this| {
750
733
this. visit_generics ( generics) ;
751
734
for bound in bounds {
752
735
this. visit_param_bound ( bound) ;
753
736
}
754
737
} ) ;
755
- }
738
+ } ) ;
756
739
} else {
757
- intravisit:: walk_ty ( self , ty)
740
+ let scope = Scope :: Binder {
741
+ lifetimes,
742
+ next_early_index,
743
+ s : self . scope ,
744
+ track_lifetime_uses : true ,
745
+ abstract_type_parent : false ,
746
+ } ;
747
+ self . with ( scope, |_old_scope, this| {
748
+ this. visit_generics ( generics) ;
749
+ for bound in bounds {
750
+ this. visit_param_bound ( bound) ;
751
+ }
752
+ } ) ;
758
753
}
759
754
}
760
755
_ => intravisit:: walk_ty ( self , ty) ,
0 commit comments