@@ -33,14 +33,6 @@ pub trait TypeVisitableExt<'tcx>: TypeVisitable<TyCtxt<'tcx>> {
3333 }
3434
3535 fn has_type_flags ( & self , flags : TypeFlags ) -> bool {
36- // N.B. Even though this uses a visitor, the visitor does not actually
37- // recurse through the whole `TypeVisitable` implementor type.
38- //
39- // Instead it stops on the first "level", visiting types, regions,
40- // consts and predicates just fetches their type flags.
41- //
42- // Thus this is a lot faster than it might seem and should be
43- // optimized to a simple field access.
4436 let res =
4537 self . visit_with ( & mut HasTypeFlagsVisitor { flags } ) . break_value ( ) == Some ( FoundFlags ) ;
4638 trace ! ( ?self , ?flags, ?res, "has_type_flags" ) ;
@@ -485,11 +477,16 @@ impl std::fmt::Debug for HasTypeFlagsVisitor {
485477 }
486478}
487479
480+ // Note: this visitor traverses values down to the level of
481+ // `Ty`/`Const`/`Predicate`, but not within those types. This is because the
482+ // type flags at the outer layer are enough. So it's faster than it first
483+ // looks, particular for `Ty`/`Predicate` where it's just a field access.
488484impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for HasTypeFlagsVisitor {
489485 type BreakTy = FoundFlags ;
490486
491487 #[ inline]
492488 fn visit_ty ( & mut self , t : Ty < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
489+ // Note: no `super_visit_with` call.
493490 let flags = t. flags ( ) ;
494491 if flags. intersects ( self . flags ) {
495492 ControlFlow :: Break ( FoundFlags )
@@ -500,6 +497,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor {
500497
501498 #[ inline]
502499 fn visit_region ( & mut self , r : ty:: Region < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
500+ // Note: no `super_visit_with` call, as usual for `Region`.
503501 let flags = r. type_flags ( ) ;
504502 if flags. intersects ( self . flags ) {
505503 ControlFlow :: Break ( FoundFlags )
@@ -510,6 +508,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor {
510508
511509 #[ inline]
512510 fn visit_const ( & mut self , c : ty:: Const < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
511+ // Note: no `super_visit_with` call.
513512 let flags = FlagComputation :: for_const ( c) ;
514513 trace ! ( r. flags=?flags) ;
515514 if flags. intersects ( self . flags ) {
@@ -521,6 +520,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor {
521520
522521 #[ inline]
523522 fn visit_predicate ( & mut self , predicate : ty:: Predicate < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
523+ // Note: no `super_visit_with` call.
524524 if predicate. flags ( ) . intersects ( self . flags ) {
525525 ControlFlow :: Break ( FoundFlags )
526526 } else {
0 commit comments