Comments to clarify the working of HasTypeFlagsVisitor
.
This commit is contained in:
parent
df98a74c32
commit
4d8e50b2d3
@ -33,14 +33,6 @@ pub trait TypeVisitableExt<'tcx>: TypeVisitable<TyCtxt<'tcx>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||||
// N.B. Even though this uses a visitor, the visitor does not actually
|
|
||||||
// recurse through the whole `TypeVisitable` implementor type.
|
|
||||||
//
|
|
||||||
// Instead it stops on the first "level", visiting types, regions,
|
|
||||||
// consts and predicates just fetches their type flags.
|
|
||||||
//
|
|
||||||
// Thus this is a lot faster than it might seem and should be
|
|
||||||
// optimized to a simple field access.
|
|
||||||
let res =
|
let res =
|
||||||
self.visit_with(&mut HasTypeFlagsVisitor { flags }).break_value() == Some(FoundFlags);
|
self.visit_with(&mut HasTypeFlagsVisitor { flags }).break_value() == Some(FoundFlags);
|
||||||
trace!(?self, ?flags, ?res, "has_type_flags");
|
trace!(?self, ?flags, ?res, "has_type_flags");
|
||||||
@ -485,11 +477,16 @@ impl std::fmt::Debug for HasTypeFlagsVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note: this visitor traverses values down to the level of
|
||||||
|
// `Ty`/`Const`/`Predicate`, but not within those types. This is because the
|
||||||
|
// type flags at the outer layer are enough. So it's faster than it first
|
||||||
|
// looks, particular for `Ty`/`Predicate` where it's just a field access.
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor {
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor {
|
||||||
type BreakTy = FoundFlags;
|
type BreakTy = FoundFlags;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||||
|
// Note: no `super_visit_with` call.
|
||||||
let flags = t.flags();
|
let flags = t.flags();
|
||||||
if flags.intersects(self.flags) {
|
if flags.intersects(self.flags) {
|
||||||
ControlFlow::Break(FoundFlags)
|
ControlFlow::Break(FoundFlags)
|
||||||
@ -500,6 +497,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||||
|
// Note: no `super_visit_with` call, as usual for `Region`.
|
||||||
let flags = r.type_flags();
|
let flags = r.type_flags();
|
||||||
if flags.intersects(self.flags) {
|
if flags.intersects(self.flags) {
|
||||||
ControlFlow::Break(FoundFlags)
|
ControlFlow::Break(FoundFlags)
|
||||||
@ -510,6 +508,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||||
|
// Note: no `super_visit_with` call.
|
||||||
let flags = FlagComputation::for_const(c);
|
let flags = FlagComputation::for_const(c);
|
||||||
trace!(r.flags=?flags);
|
trace!(r.flags=?flags);
|
||||||
if flags.intersects(self.flags) {
|
if flags.intersects(self.flags) {
|
||||||
@ -521,6 +520,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor {
|
|||||||
|
|
||||||
#[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> {
|
||||||
|
// Note: no `super_visit_with` call.
|
||||||
if predicate.flags().intersects(self.flags) {
|
if predicate.flags().intersects(self.flags) {
|
||||||
ControlFlow::Break(FoundFlags)
|
ControlFlow::Break(FoundFlags)
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user