33// RFC for reference.
44
55use crate :: ty:: subst:: { GenericArg , GenericArgKind } ;
6+ use crate :: ty:: walk:: MiniSet ;
67use crate :: ty:: { self , Ty , TyCtxt , TypeFoldable } ;
78use smallvec:: SmallVec ;
89
@@ -50,12 +51,18 @@ impl<'tcx> TyCtxt<'tcx> {
5051 /// Push onto `out` all the things that must outlive `'a` for the condition
5152 /// `ty0: 'a` to hold. Note that `ty0` must be a **fully resolved type**.
5253 pub fn push_outlives_components ( self , ty0 : Ty < ' tcx > , out : & mut SmallVec < [ Component < ' tcx > ; 4 ] > ) {
53- compute_components ( self , ty0, out) ;
54+ let mut visited = MiniSet :: new ( ) ;
55+ compute_components ( self , ty0, out, & mut visited) ;
5456 debug ! ( "components({:?}) = {:?}" , ty0, out) ;
5557 }
5658}
5759
58- fn compute_components ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > , out : & mut SmallVec < [ Component < ' tcx > ; 4 ] > ) {
60+ fn compute_components (
61+ tcx : TyCtxt < ' tcx > ,
62+ ty : Ty < ' tcx > ,
63+ out : & mut SmallVec < [ Component < ' tcx > ; 4 ] > ,
64+ visited : & mut MiniSet < GenericArg < ' tcx > > ,
65+ ) {
5966 // Descend through the types, looking for the various "base"
6067 // components and collecting them into `out`. This is not written
6168 // with `collect()` because of the need to sometimes skip subtrees
@@ -73,31 +80,31 @@ fn compute_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, out: &mut SmallVec<[Compo
7380 for child in substs {
7481 match child. unpack ( ) {
7582 GenericArgKind :: Type ( ty) => {
76- compute_components ( tcx, ty, out) ;
83+ compute_components ( tcx, ty, out, visited ) ;
7784 }
7885 GenericArgKind :: Lifetime ( _) => { }
7986 GenericArgKind :: Const ( _) => {
80- compute_components_recursive ( tcx, child, out) ;
87+ compute_components_recursive ( tcx, child, out, visited ) ;
8188 }
8289 }
8390 }
8491 }
8592
8693 ty:: Array ( element, _) => {
8794 // Don't look into the len const as it doesn't affect regions
88- compute_components ( tcx, element, out) ;
95+ compute_components ( tcx, element, out, visited ) ;
8996 }
9097
9198 ty:: Closure ( _, ref substs) => {
9299 for upvar_ty in substs. as_closure ( ) . upvar_tys ( ) {
93- compute_components ( tcx, upvar_ty, out) ;
100+ compute_components ( tcx, upvar_ty, out, visited ) ;
94101 }
95102 }
96103
97104 ty:: Generator ( _, ref substs, _) => {
98105 // Same as the closure case
99106 for upvar_ty in substs. as_generator ( ) . upvar_tys ( ) {
100- compute_components ( tcx, upvar_ty, out) ;
107+ compute_components ( tcx, upvar_ty, out, visited ) ;
101108 }
102109
103110 // We ignore regions in the generator interior as we don't
@@ -135,7 +142,8 @@ fn compute_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, out: &mut SmallVec<[Compo
135142 // OutlivesProjectionComponents. Continue walking
136143 // through and constrain Pi.
137144 let mut subcomponents = smallvec ! [ ] ;
138- compute_components_recursive ( tcx, ty. into ( ) , & mut subcomponents) ;
145+ let mut subvisited = MiniSet :: new ( ) ;
146+ compute_components_recursive ( tcx, ty. into ( ) , & mut subcomponents, & mut subvisited) ;
139147 out. push ( Component :: EscapingProjection ( subcomponents. into_iter ( ) . collect ( ) ) ) ;
140148 }
141149 }
@@ -177,7 +185,7 @@ fn compute_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, out: &mut SmallVec<[Compo
177185 // the "bound regions list". In our representation, no such
178186 // list is maintained explicitly, because bound regions
179187 // themselves can be readily identified.
180- compute_components_recursive ( tcx, ty. into ( ) , out) ;
188+ compute_components_recursive ( tcx, ty. into ( ) , out, visited ) ;
181189 }
182190 }
183191}
@@ -186,11 +194,12 @@ fn compute_components_recursive(
186194 tcx : TyCtxt < ' tcx > ,
187195 parent : GenericArg < ' tcx > ,
188196 out : & mut SmallVec < [ Component < ' tcx > ; 4 ] > ,
197+ visited : & mut MiniSet < GenericArg < ' tcx > > ,
189198) {
190- for child in parent. walk_shallow ( ) {
199+ for child in parent. walk_shallow ( visited ) {
191200 match child. unpack ( ) {
192201 GenericArgKind :: Type ( ty) => {
193- compute_components ( tcx, ty, out) ;
202+ compute_components ( tcx, ty, out, visited ) ;
194203 }
195204 GenericArgKind :: Lifetime ( lt) => {
196205 // Ignore late-bound regions.
@@ -199,7 +208,7 @@ fn compute_components_recursive(
199208 }
200209 }
201210 GenericArgKind :: Const ( _) => {
202- compute_components_recursive ( tcx, child, out) ;
211+ compute_components_recursive ( tcx, child, out, visited ) ;
203212 }
204213 }
205214 }
0 commit comments