@@ -11,7 +11,7 @@ use smallvec::{self, SmallVec};
11
11
type TypeWalkerStack < ' tcx > = SmallVec < [ GenericArg < ' tcx > ; 8 ] > ;
12
12
13
13
pub struct TypeWalker < ' tcx > {
14
- tcx : TyCtxt < ' tcx > ,
14
+ expose_default_const_substs : Option < TyCtxt < ' tcx > > ,
15
15
stack : TypeWalkerStack < ' tcx > ,
16
16
last_subtree : usize ,
17
17
pub visited : SsoHashSet < GenericArg < ' tcx > > ,
@@ -26,8 +26,13 @@ pub struct TypeWalker<'tcx> {
26
26
/// It maintains a set of visited types and
27
27
/// skips any types that are already there.
28
28
impl < ' tcx > TypeWalker < ' tcx > {
29
- fn new ( tcx : TyCtxt < ' tcx > , root : GenericArg < ' tcx > ) -> Self {
30
- Self { tcx, stack : smallvec ! [ root] , last_subtree : 1 , visited : SsoHashSet :: new ( ) }
29
+ fn new ( expose_default_const_substs : Option < TyCtxt < ' tcx > > , root : GenericArg < ' tcx > ) -> Self {
30
+ Self {
31
+ expose_default_const_substs,
32
+ stack : smallvec ! [ root] ,
33
+ last_subtree : 1 ,
34
+ visited : SsoHashSet :: new ( ) ,
35
+ }
31
36
}
32
37
33
38
/// Skips the subtree corresponding to the last type
@@ -56,7 +61,7 @@ impl<'tcx> Iterator for TypeWalker<'tcx> {
56
61
let next = self . stack . pop ( ) ?;
57
62
self . last_subtree = self . stack . len ( ) ;
58
63
if self . visited . insert ( next) {
59
- push_inner ( self . tcx , & mut self . stack , next) ;
64
+ push_inner ( self . expose_default_const_substs , & mut self . stack , next) ;
60
65
debug ! ( "next: stack={:?}" , self . stack) ;
61
66
return Some ( next) ;
62
67
}
@@ -76,7 +81,7 @@ impl GenericArg<'tcx> {
76
81
/// [isize] => { [isize], isize }
77
82
/// ```
78
83
pub fn walk ( self , tcx : TyCtxt < ' tcx > ) -> TypeWalker < ' tcx > {
79
- TypeWalker :: new ( tcx, self )
84
+ TypeWalker :: new ( Some ( tcx) , self )
80
85
}
81
86
82
87
/// Iterator that walks the immediate children of `self`. Hence
@@ -92,13 +97,17 @@ impl GenericArg<'tcx> {
92
97
visited : & mut SsoHashSet < GenericArg < ' tcx > > ,
93
98
) -> impl Iterator < Item = GenericArg < ' tcx > > {
94
99
let mut stack = SmallVec :: new ( ) ;
95
- push_inner ( tcx, & mut stack, self ) ;
100
+ push_inner ( Some ( tcx) , & mut stack, self ) ;
96
101
stack. retain ( |a| visited. insert ( * a) ) ;
97
102
stack. into_iter ( )
98
103
}
99
104
}
100
105
101
106
impl < ' tcx > super :: TyS < ' tcx > {
107
+ pub fn walk_ignoring_default_const_substs ( & ' tcx self ) -> TypeWalker < ' tcx > {
108
+ TypeWalker :: new ( None , self . into ( ) )
109
+ }
110
+
102
111
/// Iterator that walks `self` and any types reachable from
103
112
/// `self`, in depth-first order. Note that just walks the types
104
113
/// that appear in `self`, it does not descend into the fields of
@@ -110,7 +119,7 @@ impl<'tcx> super::TyS<'tcx> {
110
119
/// [isize] => { [isize], isize }
111
120
/// ```
112
121
pub fn walk ( & ' tcx self , tcx : TyCtxt < ' tcx > ) -> TypeWalker < ' tcx > {
113
- TypeWalker :: new ( tcx, self . into ( ) )
122
+ TypeWalker :: new ( Some ( tcx) , self . into ( ) )
114
123
}
115
124
}
116
125
@@ -121,7 +130,7 @@ impl<'tcx> super::TyS<'tcx> {
121
130
/// natural order one would expect (basically, the order of the
122
131
/// types as they are written).
123
132
fn push_inner < ' tcx > (
124
- tcx : TyCtxt < ' tcx > ,
133
+ expose_default_const_substs : Option < TyCtxt < ' tcx > > ,
125
134
stack : & mut TypeWalkerStack < ' tcx > ,
126
135
parent : GenericArg < ' tcx > ,
127
136
) {
@@ -202,7 +211,11 @@ fn push_inner<'tcx>(
202
211
| ty:: ConstKind :: Error ( _) => { }
203
212
204
213
ty:: ConstKind :: Unevaluated ( ct) => {
205
- stack. extend ( ct. substs ( tcx) . iter ( ) . rev ( ) ) ;
214
+ if let Some ( tcx) = expose_default_const_substs {
215
+ stack. extend ( ct. substs ( tcx) . iter ( ) . rev ( ) ) ;
216
+ } else if let Some ( substs) = ct. substs_ {
217
+ stack. extend ( substs. iter ( ) . rev ( ) ) ;
218
+ }
206
219
}
207
220
}
208
221
}
0 commit comments