3
3
// RFC for reference.
4
4
5
5
use crate :: ty:: subst:: { GenericArg , GenericArgKind } ;
6
+ use crate :: ty:: walk:: MiniSet ;
6
7
use crate :: ty:: { self , Ty , TyCtxt , TypeFoldable } ;
7
8
use smallvec:: SmallVec ;
8
9
@@ -50,12 +51,18 @@ impl<'tcx> TyCtxt<'tcx> {
50
51
/// Push onto `out` all the things that must outlive `'a` for the condition
51
52
/// `ty0: 'a` to hold. Note that `ty0` must be a **fully resolved type**.
52
53
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) ;
54
56
debug ! ( "components({:?}) = {:?}" , ty0, out) ;
55
57
}
56
58
}
57
59
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
+ ) {
59
66
// Descend through the types, looking for the various "base"
60
67
// components and collecting them into `out`. This is not written
61
68
// 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
73
80
for child in substs {
74
81
match child. unpack ( ) {
75
82
GenericArgKind :: Type ( ty) => {
76
- compute_components ( tcx, ty, out) ;
83
+ compute_components ( tcx, ty, out, visited ) ;
77
84
}
78
85
GenericArgKind :: Lifetime ( _) => { }
79
86
GenericArgKind :: Const ( _) => {
80
- compute_components_recursive ( tcx, child, out) ;
87
+ compute_components_recursive ( tcx, child, out, visited ) ;
81
88
}
82
89
}
83
90
}
84
91
}
85
92
86
93
ty:: Array ( element, _) => {
87
94
// 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 ) ;
89
96
}
90
97
91
98
ty:: Closure ( _, ref substs) => {
92
99
for upvar_ty in substs. as_closure ( ) . upvar_tys ( ) {
93
- compute_components ( tcx, upvar_ty, out) ;
100
+ compute_components ( tcx, upvar_ty, out, visited ) ;
94
101
}
95
102
}
96
103
97
104
ty:: Generator ( _, ref substs, _) => {
98
105
// Same as the closure case
99
106
for upvar_ty in substs. as_generator ( ) . upvar_tys ( ) {
100
- compute_components ( tcx, upvar_ty, out) ;
107
+ compute_components ( tcx, upvar_ty, out, visited ) ;
101
108
}
102
109
103
110
// 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
135
142
// OutlivesProjectionComponents. Continue walking
136
143
// through and constrain Pi.
137
144
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) ;
139
147
out. push ( Component :: EscapingProjection ( subcomponents. into_iter ( ) . collect ( ) ) ) ;
140
148
}
141
149
}
@@ -177,7 +185,7 @@ fn compute_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, out: &mut SmallVec<[Compo
177
185
// the "bound regions list". In our representation, no such
178
186
// list is maintained explicitly, because bound regions
179
187
// themselves can be readily identified.
180
- compute_components_recursive ( tcx, ty. into ( ) , out) ;
188
+ compute_components_recursive ( tcx, ty. into ( ) , out, visited ) ;
181
189
}
182
190
}
183
191
}
@@ -186,11 +194,12 @@ fn compute_components_recursive(
186
194
tcx : TyCtxt < ' tcx > ,
187
195
parent : GenericArg < ' tcx > ,
188
196
out : & mut SmallVec < [ Component < ' tcx > ; 4 ] > ,
197
+ visited : & mut MiniSet < GenericArg < ' tcx > > ,
189
198
) {
190
- for child in parent. walk_shallow ( ) {
199
+ for child in parent. walk_shallow ( visited ) {
191
200
match child. unpack ( ) {
192
201
GenericArgKind :: Type ( ty) => {
193
- compute_components ( tcx, ty, out) ;
202
+ compute_components ( tcx, ty, out, visited ) ;
194
203
}
195
204
GenericArgKind :: Lifetime ( lt) => {
196
205
// Ignore late-bound regions.
@@ -199,7 +208,7 @@ fn compute_components_recursive(
199
208
}
200
209
}
201
210
GenericArgKind :: Const ( _) => {
202
- compute_components_recursive ( tcx, child, out) ;
211
+ compute_components_recursive ( tcx, child, out, visited ) ;
203
212
}
204
213
}
205
214
}
0 commit comments