optimize HasTypeFlagsVisitor
This commit is contained in:
parent
977124590e
commit
eb5bbab37b
1 changed files with 83 additions and 35 deletions
|
@ -1128,26 +1128,20 @@ struct HasTypeFlagsVisitor<'tcx> {
|
||||||
impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor<'tcx> {
|
impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor<'tcx> {
|
||||||
type BreakTy = FoundFlags;
|
type BreakTy = FoundFlags;
|
||||||
fn tcx_for_anon_const_substs(&self) -> Option<TyCtxt<'tcx>> {
|
fn tcx_for_anon_const_substs(&self) -> Option<TyCtxt<'tcx>> {
|
||||||
self.tcx
|
bug!("we shouldn't call this method as we manually look at ct substs");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||||
debug!(
|
let flags = t.flags();
|
||||||
"HasTypeFlagsVisitor: t={:?} t.flags={:?} self.flags={:?}",
|
debug!("HasTypeFlagsVisitor: t={:?} flags={:?} self.flags={:?}", t, flags, self.flags);
|
||||||
t,
|
if flags.intersects(self.flags) {
|
||||||
t.flags(),
|
|
||||||
self.flags
|
|
||||||
);
|
|
||||||
if t.flags().intersects(self.flags) {
|
|
||||||
ControlFlow::Break(FoundFlags)
|
ControlFlow::Break(FoundFlags)
|
||||||
} else if t.flags().intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS)
|
|
||||||
&& self.flags.intersects(TypeFlags::MAY_NEED_DEFAULT_CONST_SUBSTS)
|
|
||||||
&& self.tcx.is_some()
|
|
||||||
{
|
|
||||||
t.super_visit_with(self)
|
|
||||||
} else {
|
} else {
|
||||||
ControlFlow::CONTINUE
|
match flags.intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) {
|
||||||
|
true if self.tcx.is_some() => UnknownConstSubstsVisitor::search(&self, t),
|
||||||
|
_ => ControlFlow::CONTINUE,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1168,13 +1162,11 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor<'tcx> {
|
||||||
debug!("HasTypeFlagsVisitor: c={:?} c.flags={:?} self.flags={:?}", c, flags, self.flags);
|
debug!("HasTypeFlagsVisitor: c={:?} c.flags={:?} self.flags={:?}", c, flags, self.flags);
|
||||||
if flags.intersects(self.flags) {
|
if flags.intersects(self.flags) {
|
||||||
ControlFlow::Break(FoundFlags)
|
ControlFlow::Break(FoundFlags)
|
||||||
} else if flags.intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS)
|
|
||||||
&& self.flags.intersects(TypeFlags::MAY_NEED_DEFAULT_CONST_SUBSTS)
|
|
||||||
&& self.tcx.is_some()
|
|
||||||
{
|
|
||||||
c.super_visit_with(self)
|
|
||||||
} else {
|
} else {
|
||||||
ControlFlow::CONTINUE
|
match flags.intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) {
|
||||||
|
true if self.tcx.is_some() => UnknownConstSubstsVisitor::search(&self, c),
|
||||||
|
_ => ControlFlow::CONTINUE,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1184,11 +1176,76 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor<'tcx> {
|
||||||
debug!("HasTypeFlagsVisitor: uv={:?} uv.flags={:?} self.flags={:?}", uv, flags, self.flags);
|
debug!("HasTypeFlagsVisitor: uv={:?} uv.flags={:?} self.flags={:?}", uv, flags, self.flags);
|
||||||
if flags.intersects(self.flags) {
|
if flags.intersects(self.flags) {
|
||||||
ControlFlow::Break(FoundFlags)
|
ControlFlow::Break(FoundFlags)
|
||||||
} else if flags.intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS)
|
} else {
|
||||||
&& self.flags.intersects(TypeFlags::MAY_NEED_DEFAULT_CONST_SUBSTS)
|
match flags.intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) {
|
||||||
&& self.tcx.is_some()
|
true if self.tcx.is_some() => UnknownConstSubstsVisitor::search(&self, uv),
|
||||||
{
|
_ => ControlFlow::CONTINUE,
|
||||||
uv.super_visit_with(self)
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||||
|
let flags = predicate.inner.flags;
|
||||||
|
debug!(
|
||||||
|
"HasTypeFlagsVisitor: predicate={:?} flags={:?} self.flags={:?}",
|
||||||
|
predicate, flags, self.flags
|
||||||
|
);
|
||||||
|
if flags.intersects(self.flags) {
|
||||||
|
ControlFlow::Break(FoundFlags)
|
||||||
|
} else {
|
||||||
|
match flags.intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) {
|
||||||
|
true if self.tcx.is_some() => UnknownConstSubstsVisitor::search(&self, predicate),
|
||||||
|
_ => ControlFlow::CONTINUE,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct UnknownConstSubstsVisitor<'tcx> {
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
flags: ty::TypeFlags,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> UnknownConstSubstsVisitor<'tcx> {
|
||||||
|
/// This is fairly cold and we don't want to
|
||||||
|
/// bloat the size of the `HasTypeFlagsVisitor`.
|
||||||
|
#[inline(never)]
|
||||||
|
pub fn search<T: TypeFoldable<'tcx>>(
|
||||||
|
visitor: &HasTypeFlagsVisitor<'tcx>,
|
||||||
|
v: T,
|
||||||
|
) -> ControlFlow<FoundFlags> {
|
||||||
|
if visitor.flags.intersects(TypeFlags::MAY_NEED_DEFAULT_CONST_SUBSTS) {
|
||||||
|
v.super_visit_with(&mut UnknownConstSubstsVisitor {
|
||||||
|
tcx: visitor.tcx.unwrap(),
|
||||||
|
flags: visitor.flags,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
ControlFlow::CONTINUE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> TypeVisitor<'tcx> for UnknownConstSubstsVisitor<'tcx> {
|
||||||
|
type BreakTy = FoundFlags;
|
||||||
|
fn tcx_for_anon_const_substs(&self) -> Option<TyCtxt<'tcx>> {
|
||||||
|
bug!("we shouldn't call this method as we manually look at ct substs");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||||
|
if t.flags().intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) {
|
||||||
|
t.super_visit_with(self)
|
||||||
|
} else {
|
||||||
|
ControlFlow::CONTINUE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_unevaluated_const(&mut self, uv: ty::Unevaluated<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||||
|
if uv.substs_.is_none() {
|
||||||
|
self.tcx
|
||||||
|
.default_anon_const_substs(uv.def.did)
|
||||||
|
.visit_with(&mut HasTypeFlagsVisitor { tcx: Some(self.tcx), flags: self.flags })
|
||||||
} else {
|
} else {
|
||||||
ControlFlow::CONTINUE
|
ControlFlow::CONTINUE
|
||||||
}
|
}
|
||||||
|
@ -1196,16 +1253,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor<'tcx> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||||
debug!(
|
if predicate.inner.flags.intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) {
|
||||||
"HasTypeFlagsVisitor: predicate={:?} predicate.flags={:?} self.flags={:?}",
|
|
||||||
predicate, predicate.inner.flags, self.flags
|
|
||||||
);
|
|
||||||
if predicate.inner.flags.intersects(self.flags) {
|
|
||||||
ControlFlow::Break(FoundFlags)
|
|
||||||
} else if predicate.inner.flags.intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS)
|
|
||||||
&& self.flags.intersects(TypeFlags::MAY_NEED_DEFAULT_CONST_SUBSTS)
|
|
||||||
&& self.tcx.is_some()
|
|
||||||
{
|
|
||||||
predicate.super_visit_with(self)
|
predicate.super_visit_with(self)
|
||||||
} else {
|
} else {
|
||||||
ControlFlow::CONTINUE
|
ControlFlow::CONTINUE
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue