@@ -621,140 +621,135 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
621621 } ;
622622 self . with ( scope, |_, this| this. visit_ty ( & mt. ty ) ) ;
623623 }
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) ;
649657
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 ( ) ) ;
685682 }
686683 }
687684 }
688685 }
686+ }
689687
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) ;
694692
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) ;
710705 } else {
711706 lifetimes. insert ( name, reg) ;
712707 }
713- }
714- GenericParamKind :: Type { .. } => {
715- type_count += 1 ;
708+ } else {
709+ lifetimes. insert ( name, reg) ;
716710 }
717711 }
712+ GenericParamKind :: Type { .. } => {
713+ type_count += 1 ;
714+ }
718715 }
719- let next_early_index = index + type_count;
716+ }
717+ let next_early_index = index + type_count;
720718
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| {
742725 let scope = Scope :: Binder {
743726 lifetimes,
744727 next_early_index,
745- s : self . scope ,
728+ s : this . scope ,
746729 track_lifetime_uses : true ,
747730 abstract_type_parent : false ,
748731 } ;
749- self . with ( scope, |_old_scope, this| {
732+ this . with ( scope, |_old_scope, this| {
750733 this. visit_generics ( generics) ;
751734 for bound in bounds {
752735 this. visit_param_bound ( bound) ;
753736 }
754737 } ) ;
755- }
738+ } ) ;
756739 } 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+ } ) ;
758753 }
759754 }
760755 _ => intravisit:: walk_ty ( self , ty) ,
0 commit comments