@@ -11,7 +11,7 @@ use smallvec::{self, SmallVec};
1111type TypeWalkerStack < ' tcx > = SmallVec < [ GenericArg < ' tcx > ; 8 ] > ;
1212
1313pub struct TypeWalker < ' tcx > {
14- tcx : TyCtxt < ' tcx > ,
14+ expose_default_const_substs : Option < TyCtxt < ' tcx > > ,
1515 stack : TypeWalkerStack < ' tcx > ,
1616 last_subtree : usize ,
1717 pub visited : SsoHashSet < GenericArg < ' tcx > > ,
@@ -26,8 +26,13 @@ pub struct TypeWalker<'tcx> {
2626/// It maintains a set of visited types and
2727/// skips any types that are already there.
2828impl < ' 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+ }
3136 }
3237
3338 /// Skips the subtree corresponding to the last type
@@ -56,7 +61,7 @@ impl<'tcx> Iterator for TypeWalker<'tcx> {
5661 let next = self . stack . pop ( ) ?;
5762 self . last_subtree = self . stack . len ( ) ;
5863 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) ;
6065 debug ! ( "next: stack={:?}" , self . stack) ;
6166 return Some ( next) ;
6267 }
@@ -76,7 +81,7 @@ impl GenericArg<'tcx> {
7681 /// [isize] => { [isize], isize }
7782 /// ```
7883 pub fn walk ( self , tcx : TyCtxt < ' tcx > ) -> TypeWalker < ' tcx > {
79- TypeWalker :: new ( tcx, self )
84+ TypeWalker :: new ( Some ( tcx) , self )
8085 }
8186
8287 /// Iterator that walks the immediate children of `self`. Hence
@@ -92,13 +97,17 @@ impl GenericArg<'tcx> {
9297 visited : & mut SsoHashSet < GenericArg < ' tcx > > ,
9398 ) -> impl Iterator < Item = GenericArg < ' tcx > > {
9499 let mut stack = SmallVec :: new ( ) ;
95- push_inner ( tcx, & mut stack, self ) ;
100+ push_inner ( Some ( tcx) , & mut stack, self ) ;
96101 stack. retain ( |a| visited. insert ( * a) ) ;
97102 stack. into_iter ( )
98103 }
99104}
100105
101106impl < ' tcx > super :: TyS < ' tcx > {
107+ pub fn walk_ignoring_default_const_substs ( & ' tcx self ) -> TypeWalker < ' tcx > {
108+ TypeWalker :: new ( None , self . into ( ) )
109+ }
110+
102111 /// Iterator that walks `self` and any types reachable from
103112 /// `self`, in depth-first order. Note that just walks the types
104113 /// that appear in `self`, it does not descend into the fields of
@@ -110,7 +119,7 @@ impl<'tcx> super::TyS<'tcx> {
110119 /// [isize] => { [isize], isize }
111120 /// ```
112121 pub fn walk ( & ' tcx self , tcx : TyCtxt < ' tcx > ) -> TypeWalker < ' tcx > {
113- TypeWalker :: new ( tcx, self . into ( ) )
122+ TypeWalker :: new ( Some ( tcx) , self . into ( ) )
114123 }
115124}
116125
@@ -121,7 +130,7 @@ impl<'tcx> super::TyS<'tcx> {
121130/// natural order one would expect (basically, the order of the
122131/// types as they are written).
123132fn push_inner < ' tcx > (
124- tcx : TyCtxt < ' tcx > ,
133+ expose_default_const_substs : Option < TyCtxt < ' tcx > > ,
125134 stack : & mut TypeWalkerStack < ' tcx > ,
126135 parent : GenericArg < ' tcx > ,
127136) {
@@ -202,7 +211,11 @@ fn push_inner<'tcx>(
202211 | ty:: ConstKind :: Error ( _) => { }
203212
204213 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+ }
206219 }
207220 }
208221 }
0 commit comments