@@ -1128,26 +1128,20 @@ struct HasTypeFlagsVisitor<'tcx> {
11281128impl < ' tcx > TypeVisitor < ' tcx > for HasTypeFlagsVisitor < ' tcx > {
11291129 type BreakTy = FoundFlags ;
11301130 fn tcx_for_anon_const_substs ( & self ) -> Option < TyCtxt < ' tcx > > {
1131- self . tcx
1131+ bug ! ( "we shouldn't call this method as we manually look at ct substs" ) ;
11321132 }
11331133
11341134 #[ inline]
11351135 fn visit_ty ( & mut self , t : Ty < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
1136- debug ! (
1137- "HasTypeFlagsVisitor: t={:?} t.flags={:?} self.flags={:?}" ,
1138- t,
1139- t. flags( ) ,
1140- self . flags
1141- ) ;
1142- if t. flags ( ) . intersects ( self . flags ) {
1136+ let flags = t. flags ( ) ;
1137+ debug ! ( "HasTypeFlagsVisitor: t={:?} flags={:?} self.flags={:?}" , t, flags, self . flags) ;
1138+ if flags. intersects ( self . flags ) {
11431139 ControlFlow :: Break ( FoundFlags )
1144- } else if t. flags ( ) . intersects ( TypeFlags :: HAS_UNKNOWN_DEFAULT_CONST_SUBSTS )
1145- && self . flags . intersects ( TypeFlags :: MAY_NEED_DEFAULT_CONST_SUBSTS )
1146- && self . tcx . is_some ( )
1147- {
1148- t. super_visit_with ( self )
11491140 } else {
1150- ControlFlow :: CONTINUE
1141+ match flags. intersects ( TypeFlags :: HAS_UNKNOWN_DEFAULT_CONST_SUBSTS ) {
1142+ true if self . tcx . is_some ( ) => UnknownConstSubstsVisitor :: search ( & self , t) ,
1143+ _ => ControlFlow :: CONTINUE ,
1144+ }
11511145 }
11521146 }
11531147
@@ -1168,13 +1162,11 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor<'tcx> {
11681162 debug ! ( "HasTypeFlagsVisitor: c={:?} c.flags={:?} self.flags={:?}" , c, flags, self . flags) ;
11691163 if flags. intersects ( self . flags ) {
11701164 ControlFlow :: Break ( FoundFlags )
1171- } else if flags. intersects ( TypeFlags :: HAS_UNKNOWN_DEFAULT_CONST_SUBSTS )
1172- && self . flags . intersects ( TypeFlags :: MAY_NEED_DEFAULT_CONST_SUBSTS )
1173- && self . tcx . is_some ( )
1174- {
1175- c. super_visit_with ( self )
11761165 } else {
1177- ControlFlow :: CONTINUE
1166+ match flags. intersects ( TypeFlags :: HAS_UNKNOWN_DEFAULT_CONST_SUBSTS ) {
1167+ true if self . tcx . is_some ( ) => UnknownConstSubstsVisitor :: search ( & self , c) ,
1168+ _ => ControlFlow :: CONTINUE ,
1169+ }
11781170 }
11791171 }
11801172
@@ -1184,28 +1176,84 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor<'tcx> {
11841176 debug ! ( "HasTypeFlagsVisitor: uv={:?} uv.flags={:?} self.flags={:?}" , uv, flags, self . flags) ;
11851177 if flags. intersects ( self . flags ) {
11861178 ControlFlow :: Break ( FoundFlags )
1187- } else if flags. intersects ( TypeFlags :: HAS_UNKNOWN_DEFAULT_CONST_SUBSTS )
1188- && self . flags . intersects ( TypeFlags :: MAY_NEED_DEFAULT_CONST_SUBSTS )
1189- && self . tcx . is_some ( )
1190- {
1191- uv. super_visit_with ( self )
11921179 } else {
1193- ControlFlow :: CONTINUE
1180+ match flags. intersects ( TypeFlags :: HAS_UNKNOWN_DEFAULT_CONST_SUBSTS ) {
1181+ true if self . tcx . is_some ( ) => UnknownConstSubstsVisitor :: search ( & self , uv) ,
1182+ _ => ControlFlow :: CONTINUE ,
1183+ }
11941184 }
11951185 }
11961186
11971187 #[ inline]
11981188 fn visit_predicate ( & mut self , predicate : ty:: Predicate < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
1189+ let flags = predicate. inner . flags ;
11991190 debug ! (
1200- "HasTypeFlagsVisitor: predicate={:?} predicate. flags={:?} self.flags={:?}" ,
1201- predicate, predicate . inner . flags, self . flags
1191+ "HasTypeFlagsVisitor: predicate={:?} flags={:?} self.flags={:?}" ,
1192+ predicate, flags, self . flags
12021193 ) ;
1203- if predicate . inner . flags . intersects ( self . flags ) {
1194+ if flags. intersects ( self . flags ) {
12041195 ControlFlow :: Break ( FoundFlags )
1205- } else if predicate. inner . flags . intersects ( TypeFlags :: HAS_UNKNOWN_DEFAULT_CONST_SUBSTS )
1206- && self . flags . intersects ( TypeFlags :: MAY_NEED_DEFAULT_CONST_SUBSTS )
1207- && self . tcx . is_some ( )
1208- {
1196+ } else {
1197+ match flags. intersects ( TypeFlags :: HAS_UNKNOWN_DEFAULT_CONST_SUBSTS ) {
1198+ true if self . tcx . is_some ( ) => UnknownConstSubstsVisitor :: search ( & self , predicate) ,
1199+ _ => ControlFlow :: CONTINUE ,
1200+ }
1201+ }
1202+ }
1203+ }
1204+
1205+ struct UnknownConstSubstsVisitor < ' tcx > {
1206+ tcx : TyCtxt < ' tcx > ,
1207+ flags : ty:: TypeFlags ,
1208+ }
1209+
1210+ impl < ' tcx > UnknownConstSubstsVisitor < ' tcx > {
1211+ /// This is fairly cold and we don't want to
1212+ /// bloat the size of the `HasTypeFlagsVisitor`.
1213+ #[ inline( never) ]
1214+ pub fn search < T : TypeFoldable < ' tcx > > (
1215+ visitor : & HasTypeFlagsVisitor < ' tcx > ,
1216+ v : T ,
1217+ ) -> ControlFlow < FoundFlags > {
1218+ if visitor. flags . intersects ( TypeFlags :: MAY_NEED_DEFAULT_CONST_SUBSTS ) {
1219+ v. super_visit_with ( & mut UnknownConstSubstsVisitor {
1220+ tcx : visitor. tcx . unwrap ( ) ,
1221+ flags : visitor. flags ,
1222+ } )
1223+ } else {
1224+ ControlFlow :: CONTINUE
1225+ }
1226+ }
1227+ }
1228+
1229+ impl < ' tcx > TypeVisitor < ' tcx > for UnknownConstSubstsVisitor < ' tcx > {
1230+ type BreakTy = FoundFlags ;
1231+ fn tcx_for_anon_const_substs ( & self ) -> Option < TyCtxt < ' tcx > > {
1232+ bug ! ( "we shouldn't call this method as we manually look at ct substs" ) ;
1233+ }
1234+
1235+ fn visit_ty ( & mut self , t : Ty < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
1236+ if t. flags ( ) . intersects ( TypeFlags :: HAS_UNKNOWN_DEFAULT_CONST_SUBSTS ) {
1237+ t. super_visit_with ( self )
1238+ } else {
1239+ ControlFlow :: CONTINUE
1240+ }
1241+ }
1242+
1243+ #[ inline]
1244+ fn visit_unevaluated_const ( & mut self , uv : ty:: Unevaluated < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
1245+ if uv. substs_ . is_none ( ) {
1246+ self . tcx
1247+ . default_anon_const_substs ( uv. def . did )
1248+ . visit_with ( & mut HasTypeFlagsVisitor { tcx : Some ( self . tcx ) , flags : self . flags } )
1249+ } else {
1250+ ControlFlow :: CONTINUE
1251+ }
1252+ }
1253+
1254+ #[ inline]
1255+ fn visit_predicate ( & mut self , predicate : ty:: Predicate < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
1256+ if predicate. inner . flags . intersects ( TypeFlags :: HAS_UNKNOWN_DEFAULT_CONST_SUBSTS ) {
12091257 predicate. super_visit_with ( self )
12101258 } else {
12111259 ControlFlow :: CONTINUE
0 commit comments