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