Skip to content

Commit eb5bbab

Browse files
committed
optimize HasTypeFlagsVisitor
1 parent 9771245 commit eb5bbab

File tree

1 file changed

+81
-33
lines changed
  • compiler/rustc_middle/src/ty

1 file changed

+81
-33
lines changed

compiler/rustc_middle/src/ty/fold.rs

+81-33
Original file line numberDiff line numberDiff line change
@@ -1128,26 +1128,20 @@ struct HasTypeFlagsVisitor<'tcx> {
11281128
impl<'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

Comments
 (0)