@@ -1128,26 +1128,20 @@ struct HasTypeFlagsVisitor<'tcx> {
1128
1128
impl < ' tcx > TypeVisitor < ' tcx > for HasTypeFlagsVisitor < ' tcx > {
1129
1129
type BreakTy = FoundFlags ;
1130
1130
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" ) ;
1132
1132
}
1133
1133
1134
1134
#[ inline]
1135
1135
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 ) {
1143
1139
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 )
1149
1140
} 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
+ }
1151
1145
}
1152
1146
}
1153
1147
@@ -1168,13 +1162,11 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor<'tcx> {
1168
1162
debug ! ( "HasTypeFlagsVisitor: c={:?} c.flags={:?} self.flags={:?}" , c, flags, self . flags) ;
1169
1163
if flags. intersects ( self . flags ) {
1170
1164
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 )
1176
1165
} 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
+ }
1178
1170
}
1179
1171
}
1180
1172
@@ -1184,28 +1176,84 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor<'tcx> {
1184
1176
debug ! ( "HasTypeFlagsVisitor: uv={:?} uv.flags={:?} self.flags={:?}" , uv, flags, self . flags) ;
1185
1177
if flags. intersects ( self . flags ) {
1186
1178
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 )
1192
1179
} 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
+ }
1194
1184
}
1195
1185
}
1196
1186
1197
1187
#[ inline]
1198
1188
fn visit_predicate ( & mut self , predicate : ty:: Predicate < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
1189
+ let flags = predicate. inner . flags ;
1199
1190
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
1202
1193
) ;
1203
- if predicate . inner . flags . intersects ( self . flags ) {
1194
+ if flags. intersects ( self . flags ) {
1204
1195
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 ) {
1209
1257
predicate. super_visit_with ( self )
1210
1258
} else {
1211
1259
ControlFlow :: CONTINUE
0 commit comments