diff options
| author | Nicholas Nethercote <n.nethercote@gmail.com> | 2023-09-13 10:15:03 +1000 |
|---|---|---|
| committer | Nicholas Nethercote <n.nethercote@gmail.com> | 2023-09-13 16:50:35 +1000 |
| commit | 4d8e50b2d3ba1f6981db2265fde47c35782ac80e (patch) | |
| tree | 85ed49c27895cba2f3a74ffb1ebb847b745324c6 | |
| parent | df98a74c32a4c699256135952b7fd3a745c8dc06 (diff) | |
| download | rust-4d8e50b2d3ba1f6981db2265fde47c35782ac80e.tar.gz rust-4d8e50b2d3ba1f6981db2265fde47c35782ac80e.zip | |
Comments to clarify the working of `HasTypeFlagsVisitor`.
| -rw-r--r-- | compiler/rustc_middle/src/ty/visit.rs | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index 156eda477ad..fb760654ea7 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -33,14 +33,6 @@ pub trait TypeVisitableExt<'tcx>: TypeVisitable<TyCtxt<'tcx>> { } 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 = self.visit_with(&mut HasTypeFlagsVisitor { flags }).break_value() == Some(FoundFlags); 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 { type BreakTy = FoundFlags; #[inline] fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { + // Note: no `super_visit_with` call. let flags = t.flags(); if flags.intersects(self.flags) { ControlFlow::Break(FoundFlags) @@ -500,6 +497,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor { #[inline] 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(); if flags.intersects(self.flags) { ControlFlow::Break(FoundFlags) @@ -510,6 +508,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor { #[inline] fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> { + // Note: no `super_visit_with` call. let flags = FlagComputation::for_const(c); trace!(r.flags=?flags); if flags.intersects(self.flags) { @@ -521,6 +520,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor { #[inline] fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> { + // Note: no `super_visit_with` call. if predicate.flags().intersects(self.flags) { ControlFlow::Break(FoundFlags) } else { |
