mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
TypeVisitor: use std::ops::ControlFlow
instead of bool
This commit is contained in:
parent
8df58ae03a
commit
2c85b6fae0
@ -15,8 +15,12 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::
|
||||
}
|
||||
})
|
||||
});
|
||||
let body_visit = s.fold(false, |acc, bind| {
|
||||
quote! { #acc || ::rustc_middle::ty::fold::TypeFoldable::visit_with(#bind, __folder) }
|
||||
|
||||
let body_visit = s.fold(quote!(), |acc, bind| {
|
||||
quote! {
|
||||
#acc
|
||||
::rustc_middle::ty::fold::TypeFoldable::visit_with(#bind, __folder)?;
|
||||
}
|
||||
});
|
||||
|
||||
s.bound_impl(
|
||||
@ -32,8 +36,9 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::
|
||||
fn super_visit_with<__F: ::rustc_middle::ty::fold::TypeVisitor<'tcx>>(
|
||||
&self,
|
||||
__folder: &mut __F
|
||||
) -> bool {
|
||||
) -> ::std::ops::ControlFlow<(), ()> {
|
||||
match *self { #body_visit }
|
||||
::std::ops::ControlFlow::CONTINUE
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -49,6 +49,7 @@
|
||||
#![feature(int_error_matching)]
|
||||
#![feature(half_open_range_patterns)]
|
||||
#![feature(exclusive_range_pattern)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![recursion_limit = "512"]
|
||||
|
||||
#[macro_use]
|
||||
|
@ -62,9 +62,9 @@ macro_rules! CloneTypeFoldableImpls {
|
||||
fn super_visit_with<F: $crate::ty::fold::TypeVisitor<$tcx>>(
|
||||
&self,
|
||||
_: &mut F)
|
||||
-> bool
|
||||
-> ::std::ops::ControlFlow<(), ()>
|
||||
{
|
||||
false
|
||||
::std::ops::ControlFlow::CONTINUE
|
||||
}
|
||||
}
|
||||
)+
|
||||
@ -105,7 +105,7 @@ macro_rules! EnumTypeFoldableImpl {
|
||||
fn super_visit_with<V: $crate::ty::fold::TypeVisitor<$tcx>>(
|
||||
&self,
|
||||
visitor: &mut V,
|
||||
) -> bool {
|
||||
) -> ::std::ops::ControlFlow<(), ()> {
|
||||
EnumTypeFoldableImpl!(@VisitVariants(self, visitor) input($($variants)*) output())
|
||||
}
|
||||
}
|
||||
@ -179,9 +179,10 @@ macro_rules! EnumTypeFoldableImpl {
|
||||
input($($input)*)
|
||||
output(
|
||||
$variant ( $($variant_arg),* ) => {
|
||||
false $(|| $crate::ty::fold::TypeFoldable::visit_with(
|
||||
$($crate::ty::fold::TypeFoldable::visit_with(
|
||||
$variant_arg, $visitor
|
||||
))*
|
||||
)?;)*
|
||||
::std::ops::ControlFlow::CONTINUE
|
||||
}
|
||||
$($output)*
|
||||
)
|
||||
@ -196,9 +197,10 @@ macro_rules! EnumTypeFoldableImpl {
|
||||
input($($input)*)
|
||||
output(
|
||||
$variant { $($variant_arg),* } => {
|
||||
false $(|| $crate::ty::fold::TypeFoldable::visit_with(
|
||||
$($crate::ty::fold::TypeFoldable::visit_with(
|
||||
$variant_arg, $visitor
|
||||
))*
|
||||
)?;)*
|
||||
::std::ops::ControlFlow::CONTINUE
|
||||
}
|
||||
$($output)*
|
||||
)
|
||||
@ -212,7 +214,7 @@ macro_rules! EnumTypeFoldableImpl {
|
||||
@VisitVariants($this, $visitor)
|
||||
input($($input)*)
|
||||
output(
|
||||
$variant => { false }
|
||||
$variant => { ::std::ops::ControlFlow::CONTINUE }
|
||||
$($output)*
|
||||
)
|
||||
)
|
||||
|
@ -32,7 +32,7 @@ use rustc_target::abi;
|
||||
use rustc_target::asm::InlineAsmRegOrRegClass;
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::{self, Debug, Display, Formatter, Write};
|
||||
use std::ops::{Index, IndexMut};
|
||||
use std::ops::{ControlFlow, Index, IndexMut};
|
||||
use std::slice;
|
||||
use std::{iter, mem, option};
|
||||
|
||||
@ -2489,7 +2489,7 @@ impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection {
|
||||
UserTypeProjection { base, projs }
|
||||
}
|
||||
|
||||
fn super_visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> bool {
|
||||
fn super_visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> ControlFlow<(), ()> {
|
||||
self.base.visit_with(visitor)
|
||||
// Note: there's nothing in `self.proj` to visit.
|
||||
}
|
||||
|
@ -87,41 +87,46 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
|
||||
Terminator { source_info: self.source_info, kind }
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
use crate::mir::TerminatorKind::*;
|
||||
|
||||
match self.kind {
|
||||
SwitchInt { ref discr, switch_ty, .. } => {
|
||||
discr.visit_with(visitor) || switch_ty.visit_with(visitor)
|
||||
discr.visit_with(visitor)?;
|
||||
switch_ty.visit_with(visitor)
|
||||
}
|
||||
Drop { ref place, .. } => place.visit_with(visitor),
|
||||
DropAndReplace { ref place, ref value, .. } => {
|
||||
place.visit_with(visitor) || value.visit_with(visitor)
|
||||
place.visit_with(visitor)?;
|
||||
value.visit_with(visitor)
|
||||
}
|
||||
Yield { ref value, .. } => value.visit_with(visitor),
|
||||
Call { ref func, ref args, ref destination, .. } => {
|
||||
let dest = if let Some((ref loc, _)) = *destination {
|
||||
loc.visit_with(visitor)
|
||||
} else {
|
||||
false
|
||||
if let Some((ref loc, _)) = *destination {
|
||||
loc.visit_with(visitor)?;
|
||||
};
|
||||
dest || func.visit_with(visitor) || args.visit_with(visitor)
|
||||
func.visit_with(visitor)?;
|
||||
args.visit_with(visitor)
|
||||
}
|
||||
Assert { ref cond, ref msg, .. } => {
|
||||
if cond.visit_with(visitor) {
|
||||
if cond.visit_with(visitor) == ControlFlow::BREAK {
|
||||
use AssertKind::*;
|
||||
match msg {
|
||||
BoundsCheck { ref len, ref index } => {
|
||||
len.visit_with(visitor) || index.visit_with(visitor)
|
||||
len.visit_with(visitor)?;
|
||||
index.visit_with(visitor)
|
||||
}
|
||||
Overflow(_, l, r) => {
|
||||
l.visit_with(visitor)?;
|
||||
r.visit_with(visitor)
|
||||
}
|
||||
Overflow(_, l, r) => l.visit_with(visitor) || r.visit_with(visitor),
|
||||
OverflowNeg(op) | DivisionByZero(op) | RemainderByZero(op) => {
|
||||
op.visit_with(visitor)
|
||||
}
|
||||
ResumedAfterReturn(_) | ResumedAfterPanic(_) => false,
|
||||
ResumedAfterReturn(_) | ResumedAfterPanic(_) => ControlFlow::CONTINUE,
|
||||
}
|
||||
} else {
|
||||
false
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
}
|
||||
InlineAsm { ref operands, .. } => operands.visit_with(visitor),
|
||||
@ -132,7 +137,7 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
|
||||
| GeneratorDrop
|
||||
| Unreachable
|
||||
| FalseEdge { .. }
|
||||
| FalseUnwind { .. } => false,
|
||||
| FalseUnwind { .. } => ControlFlow::CONTINUE,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -142,8 +147,8 @@ impl<'tcx> TypeFoldable<'tcx> for GeneratorKind {
|
||||
*self
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
|
||||
false
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<(), ()> {
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,8 +157,9 @@ impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
|
||||
Place { local: self.local.fold_with(folder), projection: self.projection.fold_with(folder) }
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.local.visit_with(visitor) || self.projection.visit_with(visitor)
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
self.local.visit_with(visitor)?;
|
||||
self.projection.visit_with(visitor)
|
||||
}
|
||||
}
|
||||
|
||||
@ -163,8 +169,8 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
|
||||
folder.tcx().intern_place_elems(&v)
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.iter().any(|t| t.visit_with(visitor))
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
self.iter().try_for_each(|t| t.visit_with(visitor))
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,32 +219,47 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
use crate::mir::Rvalue::*;
|
||||
match *self {
|
||||
Use(ref op) => op.visit_with(visitor),
|
||||
Repeat(ref op, _) => op.visit_with(visitor),
|
||||
ThreadLocalRef(did) => did.visit_with(visitor),
|
||||
Ref(region, _, ref place) => region.visit_with(visitor) || place.visit_with(visitor),
|
||||
Ref(region, _, ref place) => {
|
||||
region.visit_with(visitor)?;
|
||||
place.visit_with(visitor)
|
||||
}
|
||||
AddressOf(_, ref place) => place.visit_with(visitor),
|
||||
Len(ref place) => place.visit_with(visitor),
|
||||
Cast(_, ref op, ty) => op.visit_with(visitor) || ty.visit_with(visitor),
|
||||
Cast(_, ref op, ty) => {
|
||||
op.visit_with(visitor)?;
|
||||
ty.visit_with(visitor)
|
||||
}
|
||||
BinaryOp(_, ref rhs, ref lhs) | CheckedBinaryOp(_, ref rhs, ref lhs) => {
|
||||
rhs.visit_with(visitor) || lhs.visit_with(visitor)
|
||||
rhs.visit_with(visitor)?;
|
||||
lhs.visit_with(visitor)
|
||||
}
|
||||
UnaryOp(_, ref val) => val.visit_with(visitor),
|
||||
Discriminant(ref place) => place.visit_with(visitor),
|
||||
NullaryOp(_, ty) => ty.visit_with(visitor),
|
||||
Aggregate(ref kind, ref fields) => {
|
||||
(match **kind {
|
||||
AggregateKind::Array(ty) => ty.visit_with(visitor),
|
||||
AggregateKind::Tuple => false,
|
||||
AggregateKind::Adt(_, _, substs, user_ty, _) => {
|
||||
substs.visit_with(visitor) || user_ty.visit_with(visitor)
|
||||
match **kind {
|
||||
AggregateKind::Array(ty) => {
|
||||
ty.visit_with(visitor)?;
|
||||
}
|
||||
AggregateKind::Closure(_, substs) => substs.visit_with(visitor),
|
||||
AggregateKind::Generator(_, substs, _) => substs.visit_with(visitor),
|
||||
}) || fields.visit_with(visitor)
|
||||
AggregateKind::Tuple => {}
|
||||
AggregateKind::Adt(_, _, substs, user_ty, _) => {
|
||||
substs.visit_with(visitor)?;
|
||||
user_ty.visit_with(visitor)?;
|
||||
}
|
||||
AggregateKind::Closure(_, substs) => {
|
||||
substs.visit_with(visitor)?;
|
||||
}
|
||||
AggregateKind::Generator(_, substs, _) => {
|
||||
substs.visit_with(visitor)?;
|
||||
}
|
||||
}
|
||||
fields.visit_with(visitor)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -253,7 +274,7 @@ impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
match *self {
|
||||
Operand::Copy(ref place) | Operand::Move(ref place) => place.visit_with(visitor),
|
||||
Operand::Constant(ref c) => c.visit_with(visitor),
|
||||
@ -277,13 +298,13 @@ impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn super_visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> bool {
|
||||
fn super_visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> ControlFlow<(), ()> {
|
||||
use crate::mir::ProjectionElem::*;
|
||||
|
||||
match self {
|
||||
Field(_, ty) => ty.visit_with(visitor),
|
||||
Index(v) => v.visit_with(visitor),
|
||||
_ => false,
|
||||
_ => ControlFlow::CONTINUE,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -292,8 +313,8 @@ impl<'tcx> TypeFoldable<'tcx> for Field {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
|
||||
*self
|
||||
}
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
|
||||
false
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<(), ()> {
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
}
|
||||
|
||||
@ -301,8 +322,8 @@ impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
|
||||
*self
|
||||
}
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
|
||||
false
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<(), ()> {
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
}
|
||||
|
||||
@ -310,8 +331,8 @@ impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix<R, C> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
|
||||
self.clone()
|
||||
}
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
|
||||
false
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<(), ()> {
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
}
|
||||
|
||||
@ -323,7 +344,7 @@ impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
|
||||
literal: self.literal.fold_with(folder),
|
||||
}
|
||||
}
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
self.literal.visit_with(visitor)
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ use rustc_hir::def_id::DefId;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use std::collections::BTreeMap;
|
||||
use std::fmt;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
/// This trait is implemented for every type that can be folded.
|
||||
/// Basically, every type that has a corresponding method in `TypeFolder`.
|
||||
@ -48,8 +49,8 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
|
||||
self.super_fold_with(folder)
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool;
|
||||
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()>;
|
||||
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
self.super_visit_with(visitor)
|
||||
}
|
||||
|
||||
@ -59,6 +60,7 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
|
||||
/// there are any late-bound regions that appear free.
|
||||
fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool {
|
||||
self.visit_with(&mut HasEscapingVarsVisitor { outer_index: binder })
|
||||
== ControlFlow::Break(())
|
||||
}
|
||||
|
||||
/// Returns `true` if this `self` has any regions that escape `binder` (and
|
||||
@ -72,7 +74,7 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
|
||||
}
|
||||
|
||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||
self.visit_with(&mut HasTypeFlagsVisitor { flags })
|
||||
self.visit_with(&mut HasTypeFlagsVisitor { flags }) == ControlFlow::Break(())
|
||||
}
|
||||
fn has_projections(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_PROJECTION)
|
||||
@ -143,11 +145,14 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
|
||||
}
|
||||
|
||||
/// A visitor that does not recurse into types, works like `fn walk_shallow` in `Ty`.
|
||||
fn visit_tys_shallow(&self, visit: impl FnMut(Ty<'tcx>) -> bool) -> bool {
|
||||
fn visit_tys_shallow(
|
||||
&self,
|
||||
visit: impl FnMut(Ty<'tcx>) -> ControlFlow<(), ()>,
|
||||
) -> ControlFlow<(), ()> {
|
||||
pub struct Visitor<F>(F);
|
||||
|
||||
impl<'tcx, F: FnMut(Ty<'tcx>) -> bool> TypeVisitor<'tcx> for Visitor<F> {
|
||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
|
||||
impl<'tcx, F: FnMut(Ty<'tcx>) -> ControlFlow<(), ()>> TypeVisitor<'tcx> for Visitor<F> {
|
||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<(), ()> {
|
||||
self.0(ty)
|
||||
}
|
||||
}
|
||||
@ -160,8 +165,8 @@ impl TypeFoldable<'tcx> for hir::Constness {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
|
||||
*self
|
||||
}
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
|
||||
false
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<(), ()> {
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
}
|
||||
|
||||
@ -194,23 +199,23 @@ pub trait TypeFolder<'tcx>: Sized {
|
||||
}
|
||||
|
||||
pub trait TypeVisitor<'tcx>: Sized {
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> bool {
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> ControlFlow<(), ()> {
|
||||
t.super_visit_with(self)
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<(), ()> {
|
||||
t.super_visit_with(self)
|
||||
}
|
||||
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<(), ()> {
|
||||
r.super_visit_with(self)
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
|
||||
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow<(), ()> {
|
||||
c.super_visit_with(self)
|
||||
}
|
||||
|
||||
fn visit_predicate(&mut self, p: ty::Predicate<'tcx>) -> bool {
|
||||
fn visit_predicate(&mut self, p: ty::Predicate<'tcx>) -> ControlFlow<(), ()> {
|
||||
p.super_visit_with(self)
|
||||
}
|
||||
}
|
||||
@ -302,8 +307,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
value: &impl TypeFoldable<'tcx>,
|
||||
callback: impl FnMut(ty::Region<'tcx>) -> bool,
|
||||
) -> bool {
|
||||
return value.visit_with(&mut RegionVisitor { outer_index: ty::INNERMOST, callback });
|
||||
|
||||
struct RegionVisitor<F> {
|
||||
/// The index of a binder *just outside* the things we have
|
||||
/// traversed. If we encounter a bound region bound by this
|
||||
@ -330,31 +333,43 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
where
|
||||
F: FnMut(ty::Region<'tcx>) -> bool,
|
||||
{
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> bool {
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: &Binder<T>,
|
||||
) -> ControlFlow<(), ()> {
|
||||
self.outer_index.shift_in(1);
|
||||
let result = t.as_ref().skip_binder().visit_with(self);
|
||||
self.outer_index.shift_out(1);
|
||||
result
|
||||
}
|
||||
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<(), ()> {
|
||||
match *r {
|
||||
ty::ReLateBound(debruijn, _) if debruijn < self.outer_index => {
|
||||
false // ignore bound regions, keep visiting
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
_ => {
|
||||
if (self.callback)(r) {
|
||||
ControlFlow::BREAK
|
||||
} else {
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
}
|
||||
_ => (self.callback)(r),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
|
||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<(), ()> {
|
||||
// We're only interested in types involving regions
|
||||
if ty.flags().intersects(TypeFlags::HAS_FREE_REGIONS) {
|
||||
ty.super_visit_with(self)
|
||||
} else {
|
||||
false // keep visiting
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
value.visit_with(&mut RegionVisitor { outer_index: ty::INNERMOST, callback })
|
||||
== ControlFlow::BREAK
|
||||
}
|
||||
}
|
||||
|
||||
@ -670,7 +685,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
{
|
||||
let mut collector = LateBoundRegionsCollector::new(just_constraint);
|
||||
let result = value.as_ref().skip_binder().visit_with(&mut collector);
|
||||
assert!(!result); // should never have stopped early
|
||||
assert!(result == ControlFlow::Continue(())); // should never have stopped early
|
||||
collector.regions
|
||||
}
|
||||
|
||||
@ -836,43 +851,55 @@ struct HasEscapingVarsVisitor {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor {
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> bool {
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> ControlFlow<(), ()> {
|
||||
self.outer_index.shift_in(1);
|
||||
let result = t.super_visit_with(self);
|
||||
self.outer_index.shift_out(1);
|
||||
result
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<(), ()> {
|
||||
// If the outer-exclusive-binder is *strictly greater* than
|
||||
// `outer_index`, that means that `t` contains some content
|
||||
// bound at `outer_index` or above (because
|
||||
// `outer_exclusive_binder` is always 1 higher than the
|
||||
// content in `t`). Therefore, `t` has some escaping vars.
|
||||
t.outer_exclusive_binder > self.outer_index
|
||||
if t.outer_exclusive_binder > self.outer_index {
|
||||
ControlFlow::BREAK
|
||||
} else {
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<(), ()> {
|
||||
// If the region is bound by `outer_index` or anything outside
|
||||
// of outer index, then it escapes the binders we have
|
||||
// visited.
|
||||
r.bound_at_or_above_binder(self.outer_index)
|
||||
if r.bound_at_or_above_binder(self.outer_index) {
|
||||
ControlFlow::BREAK
|
||||
} else {
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> bool {
|
||||
fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> ControlFlow<(), ()> {
|
||||
// we don't have a `visit_infer_const` callback, so we have to
|
||||
// hook in here to catch this case (annoying...), but
|
||||
// otherwise we do want to remember to visit the rest of the
|
||||
// const, as it has types/regions embedded in a lot of other
|
||||
// places.
|
||||
match ct.val {
|
||||
ty::ConstKind::Bound(debruijn, _) if debruijn >= self.outer_index => true,
|
||||
ty::ConstKind::Bound(debruijn, _) if debruijn >= self.outer_index => ControlFlow::BREAK,
|
||||
_ => ct.super_visit_with(self),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> bool {
|
||||
predicate.inner.outer_exclusive_binder > self.outer_index
|
||||
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<(), ()> {
|
||||
if predicate.inner.outer_exclusive_binder > self.outer_index {
|
||||
ControlFlow::BREAK
|
||||
} else {
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -882,34 +909,38 @@ struct HasTypeFlagsVisitor {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
|
||||
fn visit_ty(&mut self, t: Ty<'_>) -> bool {
|
||||
fn visit_ty(&mut self, t: Ty<'_>) -> ControlFlow<(), ()> {
|
||||
debug!(
|
||||
"HasTypeFlagsVisitor: t={:?} t.flags={:?} self.flags={:?}",
|
||||
t,
|
||||
t.flags(),
|
||||
self.flags
|
||||
);
|
||||
t.flags().intersects(self.flags)
|
||||
if t.flags().intersects(self.flags) { ControlFlow::BREAK } else { ControlFlow::CONTINUE }
|
||||
}
|
||||
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<(), ()> {
|
||||
let flags = r.type_flags();
|
||||
debug!("HasTypeFlagsVisitor: r={:?} r.flags={:?} self.flags={:?}", r, flags, self.flags);
|
||||
flags.intersects(self.flags)
|
||||
if flags.intersects(self.flags) { ControlFlow::BREAK } else { ControlFlow::CONTINUE }
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
|
||||
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow<(), ()> {
|
||||
let flags = FlagComputation::for_const(c);
|
||||
debug!("HasTypeFlagsVisitor: c={:?} c.flags={:?} self.flags={:?}", c, flags, self.flags);
|
||||
flags.intersects(self.flags)
|
||||
if flags.intersects(self.flags) { ControlFlow::BREAK } else { ControlFlow::CONTINUE }
|
||||
}
|
||||
|
||||
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> bool {
|
||||
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<(), ()> {
|
||||
debug!(
|
||||
"HasTypeFlagsVisitor: predicate={:?} predicate.flags={:?} self.flags={:?}",
|
||||
predicate, predicate.inner.flags, self.flags
|
||||
);
|
||||
predicate.inner.flags.intersects(self.flags)
|
||||
if predicate.inner.flags.intersects(self.flags) {
|
||||
ControlFlow::BREAK
|
||||
} else {
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -940,45 +971,45 @@ impl LateBoundRegionsCollector {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector {
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> bool {
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> ControlFlow<(), ()> {
|
||||
self.current_index.shift_in(1);
|
||||
let result = t.super_visit_with(self);
|
||||
self.current_index.shift_out(1);
|
||||
result
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<(), ()> {
|
||||
// if we are only looking for "constrained" region, we have to
|
||||
// ignore the inputs to a projection, as they may not appear
|
||||
// in the normalized form
|
||||
if self.just_constrained {
|
||||
if let ty::Projection(..) | ty::Opaque(..) = t.kind() {
|
||||
return false;
|
||||
return ControlFlow::CONTINUE;
|
||||
}
|
||||
}
|
||||
|
||||
t.super_visit_with(self)
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
|
||||
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow<(), ()> {
|
||||
// if we are only looking for "constrained" region, we have to
|
||||
// ignore the inputs of an unevaluated const, as they may not appear
|
||||
// in the normalized form
|
||||
if self.just_constrained {
|
||||
if let ty::ConstKind::Unevaluated(..) = c.val {
|
||||
return false;
|
||||
return ControlFlow::CONTINUE;
|
||||
}
|
||||
}
|
||||
|
||||
c.super_visit_with(self)
|
||||
}
|
||||
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<(), ()> {
|
||||
if let ty::ReLateBound(debruijn, br) = *r {
|
||||
if debruijn == self.current_index {
|
||||
self.regions.insert(br);
|
||||
}
|
||||
}
|
||||
false
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ use std::cell::RefCell;
|
||||
use std::cmp::Ordering;
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::ops::Range;
|
||||
use std::ops::{ControlFlow, Range};
|
||||
use std::ptr;
|
||||
use std::str;
|
||||
|
||||
@ -1776,8 +1776,9 @@ impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> {
|
||||
ParamEnv::new(self.caller_bounds().fold_with(folder), self.reveal().fold_with(folder))
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.caller_bounds().visit_with(visitor) || self.reveal().visit_with(visitor)
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
self.caller_bounds().visit_with(visitor)?;
|
||||
self.reveal().visit_with(visitor)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ use std::cell::Cell;
|
||||
use std::char;
|
||||
use std::collections::BTreeMap;
|
||||
use std::fmt::{self, Write as _};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::ops::{ControlFlow, Deref, DerefMut};
|
||||
|
||||
// `pretty` is a separate module only for organization.
|
||||
use super::*;
|
||||
@ -1803,7 +1803,7 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
|
||||
{
|
||||
struct LateBoundRegionNameCollector<'a>(&'a mut FxHashSet<Symbol>);
|
||||
impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_> {
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<(), ()> {
|
||||
if let ty::ReLateBound(_, ty::BrNamed(_, name)) = *r {
|
||||
self.0.insert(name);
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ use rustc_index::vec::{Idx, IndexVec};
|
||||
|
||||
use smallvec::SmallVec;
|
||||
use std::fmt;
|
||||
use std::ops::ControlFlow;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -727,8 +728,8 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef {
|
||||
*self
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
|
||||
false
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
}
|
||||
|
||||
@ -737,8 +738,9 @@ impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for
|
||||
(self.0.fold_with(folder), self.1.fold_with(folder))
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.0.visit_with(visitor) || self.1.visit_with(visitor)
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
self.0.visit_with(visitor)?;
|
||||
self.1.visit_with(visitor)
|
||||
}
|
||||
}
|
||||
|
||||
@ -749,8 +751,10 @@ impl<'tcx, A: TypeFoldable<'tcx>, B: TypeFoldable<'tcx>, C: TypeFoldable<'tcx>>
|
||||
(self.0.fold_with(folder), self.1.fold_with(folder), self.2.fold_with(folder))
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.0.visit_with(visitor) || self.1.visit_with(visitor) || self.2.visit_with(visitor)
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
self.0.visit_with(visitor)?;
|
||||
self.1.visit_with(visitor)?;
|
||||
self.2.visit_with(visitor)
|
||||
}
|
||||
}
|
||||
|
||||
@ -773,7 +777,7 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
|
||||
Rc::new((**self).fold_with(folder))
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
(**self).visit_with(visitor)
|
||||
}
|
||||
}
|
||||
@ -783,7 +787,7 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc<T> {
|
||||
Arc::new((**self).fold_with(folder))
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
(**self).visit_with(visitor)
|
||||
}
|
||||
}
|
||||
@ -794,7 +798,7 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> {
|
||||
box content
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
(**self).visit_with(visitor)
|
||||
}
|
||||
}
|
||||
@ -804,8 +808,8 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
|
||||
self.iter().map(|t| t.fold_with(folder)).collect()
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.iter().any(|t| t.visit_with(visitor))
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
self.iter().try_for_each(|t| t.visit_with(visitor))
|
||||
}
|
||||
}
|
||||
|
||||
@ -814,8 +818,8 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> {
|
||||
self.iter().map(|t| t.fold_with(folder)).collect::<Vec<_>>().into_boxed_slice()
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.iter().any(|t| t.visit_with(visitor))
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
self.iter().try_for_each(|t| t.visit_with(visitor))
|
||||
}
|
||||
}
|
||||
|
||||
@ -828,11 +832,11 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {
|
||||
folder.fold_binder(self)
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
self.as_ref().skip_binder().visit_with(visitor)
|
||||
}
|
||||
|
||||
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
visitor.visit_binder(self)
|
||||
}
|
||||
}
|
||||
@ -842,8 +846,8 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::ExistentialPredicate<'tcx>>
|
||||
fold_list(*self, folder, |tcx, v| tcx.intern_existential_predicates(v))
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.iter().any(|p| p.visit_with(visitor))
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
self.iter().try_for_each(|p| p.visit_with(visitor))
|
||||
}
|
||||
}
|
||||
|
||||
@ -852,8 +856,8 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
|
||||
fold_list(*self, folder, |tcx, v| tcx.intern_type_list(v))
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.iter().any(|t| t.visit_with(visitor))
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
self.iter().try_for_each(|t| t.visit_with(visitor))
|
||||
}
|
||||
}
|
||||
|
||||
@ -862,8 +866,8 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> {
|
||||
fold_list(*self, folder, |tcx, v| tcx.intern_projs(v))
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.iter().any(|t| t.visit_with(visitor))
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
self.iter().try_for_each(|t| t.visit_with(visitor))
|
||||
}
|
||||
}
|
||||
|
||||
@ -888,20 +892,24 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
use crate::ty::InstanceDef::*;
|
||||
self.substs.visit_with(visitor)
|
||||
|| match self.def {
|
||||
Item(def) => def.visit_with(visitor),
|
||||
VtableShim(did) | ReifyShim(did) | Intrinsic(did) | Virtual(did, _) => {
|
||||
did.visit_with(visitor)
|
||||
}
|
||||
FnPtrShim(did, ty) | CloneShim(did, ty) => {
|
||||
did.visit_with(visitor) || ty.visit_with(visitor)
|
||||
}
|
||||
DropGlue(did, ty) => did.visit_with(visitor) || ty.visit_with(visitor),
|
||||
ClosureOnceShim { call_once } => call_once.visit_with(visitor),
|
||||
self.substs.visit_with(visitor)?;
|
||||
match self.def {
|
||||
Item(def) => def.visit_with(visitor),
|
||||
VtableShim(did) | ReifyShim(did) | Intrinsic(did) | Virtual(did, _) => {
|
||||
did.visit_with(visitor)
|
||||
}
|
||||
FnPtrShim(did, ty) | CloneShim(did, ty) => {
|
||||
did.visit_with(visitor)?;
|
||||
ty.visit_with(visitor)
|
||||
}
|
||||
DropGlue(did, ty) => {
|
||||
did.visit_with(visitor)?;
|
||||
ty.visit_with(visitor)
|
||||
}
|
||||
ClosureOnceShim { call_once } => call_once.visit_with(visitor),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -910,7 +918,7 @@ impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> {
|
||||
Self { instance: self.instance.fold_with(folder), promoted: self.promoted }
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
self.instance.visit_with(visitor)
|
||||
}
|
||||
}
|
||||
@ -959,19 +967,26 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
|
||||
folder.fold_ty(*self)
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
match self.kind() {
|
||||
ty::RawPtr(ref tm) => tm.visit_with(visitor),
|
||||
ty::Array(typ, sz) => typ.visit_with(visitor) || sz.visit_with(visitor),
|
||||
ty::Array(typ, sz) => {
|
||||
typ.visit_with(visitor)?;
|
||||
sz.visit_with(visitor)
|
||||
}
|
||||
ty::Slice(typ) => typ.visit_with(visitor),
|
||||
ty::Adt(_, substs) => substs.visit_with(visitor),
|
||||
ty::Dynamic(ref trait_ty, ref reg) => {
|
||||
trait_ty.visit_with(visitor) || reg.visit_with(visitor)
|
||||
trait_ty.visit_with(visitor)?;
|
||||
reg.visit_with(visitor)
|
||||
}
|
||||
ty::Tuple(ts) => ts.visit_with(visitor),
|
||||
ty::FnDef(_, substs) => substs.visit_with(visitor),
|
||||
ty::FnPtr(ref f) => f.visit_with(visitor),
|
||||
ty::Ref(r, ty, _) => r.visit_with(visitor) || ty.visit_with(visitor),
|
||||
ty::Ref(r, ty, _) => {
|
||||
r.visit_with(visitor)?;
|
||||
ty.visit_with(visitor)
|
||||
}
|
||||
ty::Generator(_did, ref substs, _) => substs.visit_with(visitor),
|
||||
ty::GeneratorWitness(ref types) => types.visit_with(visitor),
|
||||
ty::Closure(_did, ref substs) => substs.visit_with(visitor),
|
||||
@ -990,11 +1005,11 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
|
||||
| ty::Placeholder(..)
|
||||
| ty::Param(..)
|
||||
| ty::Never
|
||||
| ty::Foreign(..) => false,
|
||||
| ty::Foreign(..) => ControlFlow::CONTINUE,
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
visitor.visit_ty(self)
|
||||
}
|
||||
}
|
||||
@ -1008,11 +1023,11 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
|
||||
folder.fold_region(*self)
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
|
||||
false
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
|
||||
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
visitor.visit_region(*self)
|
||||
}
|
||||
}
|
||||
@ -1023,11 +1038,11 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
|
||||
folder.tcx().reuse_or_mk_predicate(*self, new)
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
ty::PredicateKind::super_visit_with(&self.inner.kind, visitor)
|
||||
}
|
||||
|
||||
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
visitor.visit_predicate(*self)
|
||||
}
|
||||
|
||||
@ -1045,8 +1060,8 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
|
||||
fold_list(*self, folder, |tcx, v| tcx.intern_predicates(v))
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.iter().any(|p| p.visit_with(visitor))
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
self.iter().try_for_each(|p| p.visit_with(visitor))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1055,8 +1070,8 @@ impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T>
|
||||
self.iter().map(|x| x.fold_with(folder)).collect()
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.iter().any(|t| t.visit_with(visitor))
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
self.iter().try_for_each(|t| t.visit_with(visitor))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1075,11 +1090,12 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
|
||||
folder.fold_const(*self)
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.ty.visit_with(visitor) || self.val.visit_with(visitor)
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
self.ty.visit_with(visitor)?;
|
||||
self.val.visit_with(visitor)
|
||||
}
|
||||
|
||||
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
visitor.visit_const(self)
|
||||
}
|
||||
}
|
||||
@ -1099,7 +1115,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
match *self {
|
||||
ty::ConstKind::Infer(ic) => ic.visit_with(visitor),
|
||||
ty::ConstKind::Param(p) => p.visit_with(visitor),
|
||||
@ -1107,7 +1123,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
|
||||
ty::ConstKind::Value(_)
|
||||
| ty::ConstKind::Bound(..)
|
||||
| ty::ConstKind::Placeholder(_)
|
||||
| ty::ConstKind::Error(_) => false,
|
||||
| ty::ConstKind::Error(_) => ControlFlow::CONTINUE,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1117,8 +1133,8 @@ impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> {
|
||||
*self
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
|
||||
false
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use std::num::NonZeroUsize;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
/// An entity in the Rust type system, which can be one of
|
||||
/// several kinds (types, lifetimes, and consts).
|
||||
@ -159,7 +160,7 @@ impl<'tcx> TypeFoldable<'tcx> for GenericArg<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
match self.unpack() {
|
||||
GenericArgKind::Lifetime(lt) => lt.visit_with(visitor),
|
||||
GenericArgKind::Type(ty) => ty.visit_with(visitor),
|
||||
@ -391,8 +392,8 @@ impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.iter().any(|t| t.visit_with(visitor))
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<(), ()> {
|
||||
self.iter().try_for_each(|t| t.visit_with(visitor))
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user