Skip to content

Commit 51cfe21

Browse files
Rollup merge of rust-lang#156130 - nnethercote:fold-visit-tweaks, r=WaffleLapkin
Fold/visit tweaks Details in individual commits. r? @WaffleLapkin
2 parents 6d0b841 + 803c7ba commit 51cfe21

3 files changed

Lines changed: 40 additions & 48 deletions

File tree

compiler/rustc_type_ir/src/flags.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ bitflags::bitflags! {
118118
/// Does this have any `ReErased` regions?
119119
const HAS_RE_ERASED = 1 << 21;
120120

121+
/// Does this have any regions of any kind?
122+
const HAS_REGIONS = TypeFlags::HAS_FREE_REGIONS.bits()
123+
| TypeFlags::HAS_RE_BOUND.bits()
124+
| TypeFlags::HAS_RE_ERASED.bits();
125+
121126
/// Does this value have parameters/placeholders/inference variables which could be
122127
/// replaced later, in a way that would change the results of `impl` specialization?
123128
const STILL_FURTHER_SPECIALIZABLE = TypeFlags::HAS_TY_PARAM.bits()
@@ -139,7 +144,7 @@ bitflags::bitflags! {
139144
/// Does this type have any coroutines in it?
140145
const HAS_TY_CORO = 1 << 25;
141146

142-
/// Does this have have a `Bound(BoundVarIndexKind::Canonical, _)`?
147+
/// Does this have a `Bound(BoundVarIndexKind::Canonical, _)`?
143148
const HAS_CANONICAL_BOUND = 1 << 26;
144149
}
145150
}
@@ -192,7 +197,7 @@ impl<I: Interner> FlagComputation<I> {
192197
}
193198

194199
fn add_flags(&mut self, flags: TypeFlags) {
195-
self.flags = self.flags | flags;
200+
self.flags |= flags;
196201
}
197202

198203
/// indicates that `self` refers to something at binding level `binder`

compiler/rustc_type_ir/src/fold.rs

Lines changed: 16 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ use tracing::{debug, instrument};
5555

5656
use crate::inherent::*;
5757
use crate::visit::{TypeVisitable, TypeVisitableExt as _};
58-
use crate::{self as ty, BoundVarIndexKind, Interner, TypeFlags};
58+
use crate::{self as ty, BoundVarIndexKind, Interner};
5959

6060
/// This trait is implemented for every type that can be folded,
6161
/// providing the skeleton of the traversal.
@@ -121,10 +121,6 @@ pub trait TypeSuperFoldable<I: Interner>: TypeFoldable<I> {
121121
/// default that does an "identity" fold. Implementations of these methods
122122
/// often fall back to a `super_fold_with` method if the primary argument
123123
/// doesn't satisfy a particular condition.
124-
///
125-
/// A blanket implementation of [`FallibleTypeFolder`] will defer to
126-
/// the infallible methods of this trait to ensure that the two APIs
127-
/// are coherent.
128124
pub trait TypeFolder<I: Interner>: Sized {
129125
fn cx(&self) -> I;
130126

@@ -437,6 +433,10 @@ impl<I: Interner> TypeFolder<I> for Shifter<I> {
437433
fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate {
438434
if p.has_vars_bound_at_or_above(self.current_index) { p.super_fold_with(self) } else { p }
439435
}
436+
437+
fn fold_clauses(&mut self, c: I::Clauses) -> I::Clauses {
438+
if c.has_vars_bound_at_or_above(self.current_index) { c.super_fold_with(self) } else { c }
439+
}
440440
}
441441

442442
pub fn shift_region<I: Interner>(cx: I, region: I::Region, amount: u32) -> I::Region {
@@ -477,10 +477,10 @@ where
477477
/// Folds over the substructure of a type, visiting its component
478478
/// types and all regions that occur *free* within it.
479479
///
480-
/// That is, function pointer types and trait object can introduce
481-
/// new bound regions which are not visited by this visitors as
480+
/// That is, function pointer types and trait objects can introduce
481+
/// new bound regions which are not visited by this visitor as
482482
/// they are not free; only regions that occur free will be
483-
/// visited by `fld_r`.
483+
/// visited by `fold_region_fn`.
484484
pub struct RegionFolder<I, F> {
485485
cx: I,
486486

@@ -489,7 +489,7 @@ pub struct RegionFolder<I, F> {
489489
/// binder, it is incremented (via `shift_in`).
490490
current_index: ty::DebruijnIndex,
491491

492-
/// Callback invokes for each free region. The `DebruijnIndex`
492+
/// Callback invoked for each free region. The `DebruijnIndex`
493493
/// points to the binder *just outside* the ones we have passed
494494
/// through.
495495
fold_region_fn: F,
@@ -539,32 +539,18 @@ where
539539
}
540540

541541
fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
542-
if t.has_type_flags(
543-
TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_RE_BOUND | TypeFlags::HAS_RE_ERASED,
544-
) {
545-
t.super_fold_with(self)
546-
} else {
547-
t
548-
}
542+
if t.has_regions() { t.super_fold_with(self) } else { t }
549543
}
550544

551545
fn fold_const(&mut self, ct: I::Const) -> I::Const {
552-
if ct.has_type_flags(
553-
TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_RE_BOUND | TypeFlags::HAS_RE_ERASED,
554-
) {
555-
ct.super_fold_with(self)
556-
} else {
557-
ct
558-
}
546+
if ct.has_regions() { ct.super_fold_with(self) } else { ct }
559547
}
560548

561549
fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate {
562-
if p.has_type_flags(
563-
TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_RE_BOUND | TypeFlags::HAS_RE_ERASED,
564-
) {
565-
p.super_fold_with(self)
566-
} else {
567-
p
568-
}
550+
if p.has_regions() { p.super_fold_with(self) } else { p }
551+
}
552+
553+
fn fold_clauses(&mut self, c: I::Clauses) -> I::Clauses {
554+
if c.has_regions() { c.super_fold_with(self) } else { c }
569555
}
570556
}

compiler/rustc_type_ir/src/visit.rs

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ pub trait TypeVisitable<I: Interner>: fmt::Debug {
6767
/// each field/element.
6868
///
6969
/// For types of interest (such as `Ty`), the implementation of this method
70-
/// that calls a visitor method specifically for that type (such as
70+
/// calls a visitor method specifically for that type (such as
7171
/// `V::visit_ty`). This is where control transfers from `TypeVisitable` to
7272
/// `TypeVisitor`.
7373
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result;
@@ -102,8 +102,8 @@ pub trait TypeVisitor<I: Interner>: Sized {
102102
t.super_visit_with(self)
103103
}
104104

105-
// The default region visitor is a no-op because `Region` is non-recursive
106-
// and has no `super_visit_with` method to call.
105+
// `Region` is non-recursive so the default region visitor has no
106+
// `super_visit_with` method to call.
107107
fn visit_region(&mut self, r: I::Region) -> Self::Result {
108108
if let ty::ReError(guar) = r.kind() {
109109
self.visit_error(guar)
@@ -251,10 +251,10 @@ pub trait TypeVisitableExt<I: Interner>: TypeVisitable<I> {
251251
self.has_vars_bound_at_or_above(binder.shifted_in(1))
252252
}
253253

254-
/// Return `true` if this type has regions that are not a part of the type.
255-
/// For example, `for<'a> fn(&'a i32)` return `false`, while `fn(&'a i32)`
256-
/// would return `true`. The latter can occur when traversing through the
257-
/// former.
254+
/// Returns `true` if this type has regions that are not a part of the
255+
/// type. For example, given a `for<'a> fn(&'a i32)` this function returns
256+
/// `false`, while given a `fn(&'a i32)` it returns `true`. The latter can
257+
/// occur when traversing through the former.
258258
///
259259
/// See [`HasEscapingVarsVisitor`] for more information.
260260
fn has_escaping_bound_vars(&self) -> bool {
@@ -285,6 +285,10 @@ pub trait TypeVisitableExt<I: Interner>: TypeVisitable<I> {
285285
self.has_type_flags(TypeFlags::HAS_PARAM - TypeFlags::HAS_RE_PARAM)
286286
}
287287

288+
fn has_regions(&self) -> bool {
289+
self.has_type_flags(TypeFlags::HAS_REGIONS)
290+
}
291+
288292
fn has_infer_regions(&self) -> bool {
289293
self.has_type_flags(TypeFlags::HAS_RE_INFER)
290294
}
@@ -363,13 +367,12 @@ pub trait TypeVisitableExt<I: Interner>: TypeVisitable<I> {
363367

364368
impl<I: Interner, T: TypeVisitable<I>> TypeVisitableExt<I> for T {
365369
fn has_type_flags(&self, flags: TypeFlags) -> bool {
366-
let res =
367-
self.visit_with(&mut HasTypeFlagsVisitor { flags }) == ControlFlow::Break(FoundFlags);
368-
res
370+
self.visit_with(&mut HasTypeFlagsVisitor { flags }) == ControlFlow::Break(FoundFlags)
369371
}
370372

371373
fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool {
372-
self.visit_with(&mut HasEscapingVarsVisitor { outer_index: binder }).is_break()
374+
self.visit_with(&mut HasEscapingVarsVisitor { outer_index: binder })
375+
== ControlFlow::Break(FoundEscapingVars)
373376
}
374377

375378
fn error_reported(&self) -> Result<(), I::ErrorGuaranteed> {
@@ -438,8 +441,7 @@ impl<I: Interner> TypeVisitor<I> for HasTypeFlagsVisitor {
438441
#[inline]
439442
fn visit_ty(&mut self, t: I::Ty) -> Self::Result {
440443
// Note: no `super_visit_with` call.
441-
let flags = t.flags();
442-
if flags.intersects(self.flags) {
444+
if t.flags().intersects(self.flags) {
443445
ControlFlow::Break(FoundFlags)
444446
} else {
445447
ControlFlow::Continue(())
@@ -449,8 +451,7 @@ impl<I: Interner> TypeVisitor<I> for HasTypeFlagsVisitor {
449451
#[inline]
450452
fn visit_region(&mut self, r: I::Region) -> Self::Result {
451453
// Note: no `super_visit_with` call, as usual for `Region`.
452-
let flags = r.flags();
453-
if flags.intersects(self.flags) {
454+
if r.flags().intersects(self.flags) {
454455
ControlFlow::Break(FoundFlags)
455456
} else {
456457
ControlFlow::Continue(())
@@ -571,7 +572,7 @@ impl<I: Interner> TypeVisitor<I> for HasEscapingVarsVisitor {
571572
// `outer_index`, that means that `ct` contains some content
572573
// bound at `outer_index` or above (because
573574
// `outer_exclusive_binder` is always 1 higher than the
574-
// content in `t`). Therefore, `t` has some escaping vars.
575+
// content in `ct`). Therefore, `ct` has some escaping vars.
575576
if ct.outer_exclusive_binder() > self.outer_index {
576577
ControlFlow::Break(FoundEscapingVars)
577578
} else {

0 commit comments

Comments
 (0)