@@ -3,6 +3,7 @@ use crate::infer::{GenericKind, VerifyBound};
33use rustc_data_structures:: captures:: Captures ;
44use rustc_hir:: def_id:: DefId ;
55use rustc_middle:: ty:: subst:: { GenericArg , GenericArgKind , Subst } ;
6+ use rustc_middle:: ty:: walk:: MiniSet ;
67use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
78
89/// The `TypeOutlives` struct has the job of "lowering" a `T: 'a`
@@ -31,16 +32,23 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
3132 /// Returns a "verify bound" that encodes what we know about
3233 /// `generic` and the regions it outlives.
3334 pub fn generic_bound ( & self , generic : GenericKind < ' tcx > ) -> VerifyBound < ' tcx > {
35+ let mut visited = MiniSet :: new ( ) ;
3436 match generic {
3537 GenericKind :: Param ( param_ty) => self . param_bound ( param_ty) ,
36- GenericKind :: Projection ( projection_ty) => self . projection_bound ( projection_ty) ,
38+ GenericKind :: Projection ( projection_ty) => {
39+ self . projection_bound ( projection_ty, & mut visited)
40+ }
3741 }
3842 }
3943
40- fn type_bound ( & self , ty : Ty < ' tcx > ) -> VerifyBound < ' tcx > {
44+ fn type_bound (
45+ & self ,
46+ ty : Ty < ' tcx > ,
47+ visited : & mut MiniSet < GenericArg < ' tcx > > ,
48+ ) -> VerifyBound < ' tcx > {
4149 match ty. kind {
4250 ty:: Param ( p) => self . param_bound ( p) ,
43- ty:: Projection ( data) => self . projection_bound ( data) ,
51+ ty:: Projection ( data) => self . projection_bound ( data, visited ) ,
4452 ty:: FnDef ( _, substs) => {
4553 // HACK(eddyb) ignore lifetimes found shallowly in `substs`.
4654 // This is inconsistent with `ty::Adt` (including all substs),
@@ -50,9 +58,9 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
5058 let mut bounds = substs
5159 . iter ( )
5260 . filter_map ( |child| match child. unpack ( ) {
53- GenericArgKind :: Type ( ty) => Some ( self . type_bound ( ty) ) ,
61+ GenericArgKind :: Type ( ty) => Some ( self . type_bound ( ty, visited ) ) ,
5462 GenericArgKind :: Lifetime ( _) => None ,
55- GenericArgKind :: Const ( _) => Some ( self . recursive_bound ( child) ) ,
63+ GenericArgKind :: Const ( _) => Some ( self . recursive_bound ( child, visited ) ) ,
5664 } )
5765 . filter ( |bound| {
5866 // Remove bounds that must hold, since they are not interesting.
@@ -66,7 +74,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
6674 ) ,
6775 }
6876 }
69- _ => self . recursive_bound ( ty. into ( ) ) ,
77+ _ => self . recursive_bound ( ty. into ( ) , visited ) ,
7078 }
7179 }
7280
@@ -137,7 +145,11 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
137145 self . declared_projection_bounds_from_trait ( projection_ty)
138146 }
139147
140- pub fn projection_bound ( & self , projection_ty : ty:: ProjectionTy < ' tcx > ) -> VerifyBound < ' tcx > {
148+ pub fn projection_bound (
149+ & self ,
150+ projection_ty : ty:: ProjectionTy < ' tcx > ,
151+ visited : & mut MiniSet < GenericArg < ' tcx > > ,
152+ ) -> VerifyBound < ' tcx > {
141153 debug ! ( "projection_bound(projection_ty={:?})" , projection_ty) ;
142154
143155 let projection_ty_as_ty =
@@ -166,21 +178,25 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
166178
167179 // see the extensive comment in projection_must_outlive
168180 let ty = self . tcx . mk_projection ( projection_ty. item_def_id , projection_ty. substs ) ;
169- let recursive_bound = self . recursive_bound ( ty. into ( ) ) ;
181+ let recursive_bound = self . recursive_bound ( ty. into ( ) , visited ) ;
170182
171183 VerifyBound :: AnyBound ( env_bounds. chain ( trait_bounds) . collect ( ) ) . or ( recursive_bound)
172184 }
173185
174- fn recursive_bound ( & self , parent : GenericArg < ' tcx > ) -> VerifyBound < ' tcx > {
186+ fn recursive_bound (
187+ & self ,
188+ parent : GenericArg < ' tcx > ,
189+ visited : & mut MiniSet < GenericArg < ' tcx > > ,
190+ ) -> VerifyBound < ' tcx > {
175191 let mut bounds = parent
176- . walk_shallow ( )
192+ . walk_shallow ( visited )
177193 . filter_map ( |child| match child. unpack ( ) {
178- GenericArgKind :: Type ( ty) => Some ( self . type_bound ( ty) ) ,
194+ GenericArgKind :: Type ( ty) => Some ( self . type_bound ( ty, visited ) ) ,
179195 GenericArgKind :: Lifetime ( lt) => {
180196 // Ignore late-bound regions.
181197 if !lt. is_late_bound ( ) { Some ( VerifyBound :: OutlivedBy ( lt) ) } else { None }
182198 }
183- GenericArgKind :: Const ( _) => Some ( self . recursive_bound ( child) ) ,
199+ GenericArgKind :: Const ( _) => Some ( self . recursive_bound ( child, visited ) ) ,
184200 } )
185201 . filter ( |bound| {
186202 // Remove bounds that must hold, since they are not interesting.
0 commit comments