diff --git a/compiler/rustc_infer/src/traits/structural_impls.rs b/compiler/rustc_infer/src/traits/structural_impls.rs index 82ee4bb29e8..c5d85d13cf0 100644 --- a/compiler/rustc_infer/src/traits/structural_impls.rs +++ b/compiler/rustc_infer/src/traits/structural_impls.rs @@ -2,6 +2,7 @@ use crate::traits::project::Normalized; use rustc_middle::ty; use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeVisitor}; +use rustc_middle::ty::visit::TypeVisitable; use std::fmt; use std::ops::ControlFlow; @@ -68,7 +69,9 @@ fn try_fold_with>(self, folder: &mut F) -> Result> TypeVisitable<'tcx> for traits::Obligation<'tcx, O> { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.predicate.visit_with(visitor)?; self.param_env.visit_with(visitor) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index b068b271564..1b6c6bda172 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -11,6 +11,7 @@ use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable, TypeVisitor}; use crate::ty::print::{FmtPrinter, Printer}; use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef}; +use crate::ty::visit::TypeVisitable; use crate::ty::{self, List, Ty, TyCtxt}; use crate::ty::{AdtDef, InstanceDef, ScalarInt, UserTypeAnnotationIndex}; @@ -68,6 +69,7 @@ pub mod traversal; mod type_foldable; +mod type_visitable; pub mod visit; pub use self::generic_graph::graphviz_safe_def_name; @@ -2650,7 +2652,9 @@ fn try_fold_with>(self, folder: &mut F) -> Result TypeVisitable<'tcx> for UserTypeProjection { fn visit_with>(&self, visitor: &mut Vs) -> ControlFlow { self.base.visit_with(visitor) // Note: there's nothing in `self.proj` to visit. diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index e1d50460f82..3c9850a9eb3 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -89,65 +89,12 @@ fn try_fold_with>(self, folder: &mut F) -> Result>(&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) - } - Drop { ref place, .. } => place.visit_with(visitor), - DropAndReplace { ref place, ref value, .. } => { - place.visit_with(visitor)?; - value.visit_with(visitor) - } - Yield { ref value, .. } => value.visit_with(visitor), - Call { ref func, ref args, ref destination, .. } => { - destination.visit_with(visitor)?; - func.visit_with(visitor)?; - args.visit_with(visitor) - } - Assert { ref cond, ref msg, .. } => { - cond.visit_with(visitor)?; - use AssertKind::*; - match msg { - BoundsCheck { ref len, ref index } => { - len.visit_with(visitor)?; - index.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(_) => ControlFlow::CONTINUE, - } - } - InlineAsm { ref operands, .. } => operands.visit_with(visitor), - Goto { .. } - | Resume - | Abort - | Return - | GeneratorDrop - | Unreachable - | FalseEdge { .. } - | FalseUnwind { .. } => ControlFlow::CONTINUE, - } - } } impl<'tcx> TypeFoldable<'tcx> for GeneratorKind { fn try_fold_with>(self, _: &mut F) -> Result { Ok(self) } - - fn visit_with>(&self, _: &mut V) -> ControlFlow { - ControlFlow::CONTINUE - } } impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> { @@ -157,21 +104,12 @@ fn try_fold_with>(self, folder: &mut F) -> Result>(&self, visitor: &mut V) -> ControlFlow { - self.local.visit_with(visitor)?; - self.projection.visit_with(visitor) - } } impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { fn try_fold_with>(self, folder: &mut F) -> Result { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_place_elems(v)) } - - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - self.iter().try_for_each(|t| t.visit_with(visitor)) - } } impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> { @@ -224,55 +162,6 @@ fn try_fold_with>(self, folder: &mut F) -> Result>(&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) - } - 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) - } - BinaryOp(_, box (ref rhs, ref lhs)) | CheckedBinaryOp(_, box (ref rhs, ref lhs)) => { - 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 => {} - 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) - } - ShallowInitBox(ref op, ty) => { - op.visit_with(visitor)?; - ty.visit_with(visitor) - } - } - } } impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> { @@ -283,13 +172,6 @@ fn try_fold_with>(self, folder: &mut F) -> Result Operand::Constant(c.try_fold_with(folder)?), }) } - - fn visit_with>(&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), - } - } } impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> { @@ -307,43 +189,24 @@ fn try_fold_with>(self, folder: &mut F) -> Result Subslice { from, to, from_end }, }) } - - fn visit_with>(&self, visitor: &mut Vs) -> ControlFlow { - use crate::mir::ProjectionElem::*; - - match self { - Field(_, ty) => ty.visit_with(visitor), - Index(v) => v.visit_with(visitor), - _ => ControlFlow::CONTINUE, - } - } } impl<'tcx> TypeFoldable<'tcx> for Field { fn try_fold_with>(self, _: &mut F) -> Result { Ok(self) } - fn visit_with>(&self, _: &mut V) -> ControlFlow { - ControlFlow::CONTINUE - } } impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal { fn try_fold_with>(self, _: &mut F) -> Result { Ok(self) } - fn visit_with>(&self, _: &mut V) -> ControlFlow { - ControlFlow::CONTINUE - } } impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix { fn try_fold_with>(self, _: &mut F) -> Result { Ok(self) } - fn visit_with>(&self, _: &mut V) -> ControlFlow { - ControlFlow::CONTINUE - } } impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> { @@ -354,10 +217,6 @@ fn try_fold_with>(self, folder: &mut F) -> Result>(&self, visitor: &mut V) -> ControlFlow { - self.literal.visit_with(visitor)?; - self.user_ty.visit_with(visitor) - } } impl<'tcx> TypeFoldable<'tcx> for ConstantKind<'tcx> { @@ -365,10 +224,6 @@ impl<'tcx> TypeFoldable<'tcx> for ConstantKind<'tcx> { fn try_fold_with>(self, folder: &mut F) -> Result { folder.try_fold_mir_const(self) } - - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - visitor.visit_mir_const(*self) - } } impl<'tcx> TypeSuperFoldable<'tcx> for ConstantKind<'tcx> { @@ -381,11 +236,4 @@ fn try_super_fold_with>( ConstantKind::Val(v, t) => Ok(ConstantKind::Val(v, t.try_fold_with(folder)?)), } } - - fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { - match *self { - ConstantKind::Ty(c) => c.visit_with(visitor), - ConstantKind::Val(_, t) => t.visit_with(visitor), - } - } } diff --git a/compiler/rustc_middle/src/mir/type_visitable.rs b/compiler/rustc_middle/src/mir/type_visitable.rs new file mode 100644 index 00000000000..d52ae5fac67 --- /dev/null +++ b/compiler/rustc_middle/src/mir/type_visitable.rs @@ -0,0 +1,186 @@ +//! `TypeVisitable` implementations for MIR types + +use super::*; +use crate::ty; + +impl<'tcx> TypeVisitable<'tcx> for Terminator<'tcx> { + fn visit_with>(&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) + } + Drop { ref place, .. } => place.visit_with(visitor), + DropAndReplace { ref place, ref value, .. } => { + place.visit_with(visitor)?; + value.visit_with(visitor) + } + Yield { ref value, .. } => value.visit_with(visitor), + Call { ref func, ref args, ref destination, .. } => { + destination.visit_with(visitor)?; + func.visit_with(visitor)?; + args.visit_with(visitor) + } + Assert { ref cond, ref msg, .. } => { + cond.visit_with(visitor)?; + use AssertKind::*; + match msg { + BoundsCheck { ref len, ref index } => { + len.visit_with(visitor)?; + index.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(_) => ControlFlow::CONTINUE, + } + } + InlineAsm { ref operands, .. } => operands.visit_with(visitor), + Goto { .. } + | Resume + | Abort + | Return + | GeneratorDrop + | Unreachable + | FalseEdge { .. } + | FalseUnwind { .. } => ControlFlow::CONTINUE, + } + } +} + +impl<'tcx> TypeVisitable<'tcx> for GeneratorKind { + fn visit_with>(&self, _: &mut V) -> ControlFlow { + ControlFlow::CONTINUE + } +} + +impl<'tcx> TypeVisitable<'tcx> for Place<'tcx> { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + self.local.visit_with(visitor)?; + self.projection.visit_with(visitor) + } +} + +impl<'tcx> TypeVisitable<'tcx> for &'tcx ty::List> { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + self.iter().try_for_each(|t| t.visit_with(visitor)) + } +} + +impl<'tcx> TypeVisitable<'tcx> for Rvalue<'tcx> { + fn visit_with>(&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) + } + 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) + } + BinaryOp(_, box (ref rhs, ref lhs)) | CheckedBinaryOp(_, box (ref rhs, ref lhs)) => { + 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 => {} + 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) + } + ShallowInitBox(ref op, ty) => { + op.visit_with(visitor)?; + ty.visit_with(visitor) + } + } + } +} + +impl<'tcx> TypeVisitable<'tcx> for Operand<'tcx> { + fn visit_with>(&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), + } + } +} + +impl<'tcx> TypeVisitable<'tcx> for PlaceElem<'tcx> { + fn visit_with>(&self, visitor: &mut Vs) -> ControlFlow { + use crate::mir::ProjectionElem::*; + + match self { + Field(_, ty) => ty.visit_with(visitor), + Index(v) => v.visit_with(visitor), + _ => ControlFlow::CONTINUE, + } + } +} + +impl<'tcx> TypeVisitable<'tcx> for Field { + fn visit_with>(&self, _: &mut V) -> ControlFlow { + ControlFlow::CONTINUE + } +} + +impl<'tcx> TypeVisitable<'tcx> for GeneratorSavedLocal { + fn visit_with>(&self, _: &mut V) -> ControlFlow { + ControlFlow::CONTINUE + } +} + +impl<'tcx, R: Idx, C: Idx> TypeVisitable<'tcx> for BitMatrix { + fn visit_with>(&self, _: &mut V) -> ControlFlow { + ControlFlow::CONTINUE + } +} + +impl<'tcx> TypeVisitable<'tcx> for Constant<'tcx> { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + self.literal.visit_with(visitor)?; + self.user_ty.visit_with(visitor) + } +} + +impl<'tcx> TypeVisitable<'tcx> for ConstantKind<'tcx> { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + visitor.visit_mir_const(*self) + } +} + +impl<'tcx> TypeSuperVisitable<'tcx> for ConstantKind<'tcx> { + fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { + match *self { + ConstantKind::Ty(c) => c.visit_with(visitor), + ConstantKind::Val(_, t) => t.visit_with(visitor), + } + } +} diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index d755bb8fde8..34ba5b81a67 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1385,7 +1385,9 @@ fn try_fold_with>( self.constness().try_fold_with(folder)?, )) } +} +impl<'tcx> TypeVisitable<'tcx> for ParamEnv<'tcx> { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.caller_bounds().visit_with(visitor)?; self.reveal().visit_with(visitor)?; diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 4ec3f30600a..a93deb94351 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -6,6 +6,7 @@ use crate::mir::ProjectionKind; use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable, TypeVisitor}; use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer}; +use crate::ty::visit::{TypeSuperVisitable, TypeVisitable}; use crate::ty::{self, InferConst, Lift, Term, Ty, TyCtxt}; use rustc_data_structures::functor::IdFunctor; use rustc_hir as hir; @@ -651,7 +652,9 @@ impl<'tcx> TypeFoldable<'tcx> for ty::AdtDef<'tcx> { fn try_fold_with>(self, _folder: &mut F) -> Result { Ok(self) } +} +impl<'tcx> TypeVisitable<'tcx> for ty::AdtDef<'tcx> { fn visit_with>(&self, _visitor: &mut V) -> ControlFlow { ControlFlow::CONTINUE } @@ -664,7 +667,9 @@ fn try_fold_with>( ) -> Result<(T, U), F::Error> { Ok((self.0.try_fold_with(folder)?, self.1.try_fold_with(folder)?)) } +} +impl<'tcx, T: TypeVisitable<'tcx>, U: TypeVisitable<'tcx>> TypeVisitable<'tcx> for (T, U) { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.0.visit_with(visitor)?; self.1.visit_with(visitor) @@ -684,7 +689,11 @@ fn try_fold_with>( self.2.try_fold_with(folder)?, )) } +} +impl<'tcx, A: TypeVisitable<'tcx>, B: TypeVisitable<'tcx>, C: TypeVisitable<'tcx>> + TypeVisitable<'tcx> for (A, B, C) +{ fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.0.visit_with(visitor)?; self.1.visit_with(visitor)?; @@ -756,7 +765,9 @@ fn try_fold_with>( Ok(Rc::from_raw(Rc::into_raw(unique).cast())) } } +} +impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Rc { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { (**self).visit_with(visitor) } @@ -800,7 +811,9 @@ fn try_fold_with>( Ok(Arc::from_raw(Arc::into_raw(unique).cast())) } } +} +impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Arc { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { (**self).visit_with(visitor) } @@ -810,7 +823,9 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box { fn try_fold_with>(self, folder: &mut F) -> Result { self.try_map_id(|value| value.try_fold_with(folder)) } +} +impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Box { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { (**self).visit_with(visitor) } @@ -820,7 +835,9 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec { fn try_fold_with>(self, folder: &mut F) -> Result { self.try_map_id(|t| t.try_fold_with(folder)) } +} +impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Vec { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.iter().try_for_each(|t| t.visit_with(visitor)) } @@ -830,7 +847,9 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> { fn try_fold_with>(self, folder: &mut F) -> Result { self.try_map_id(|t| t.try_fold_with(folder)) } +} +impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Box<[T]> { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.iter().try_for_each(|t| t.visit_with(visitor)) } @@ -840,7 +859,9 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::EarlyBinder { fn try_fold_with>(self, folder: &mut F) -> Result { self.try_map_bound(|ty| ty.try_fold_with(folder)) } +} +impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for ty::EarlyBinder { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.as_ref().0.visit_with(visitor) } @@ -850,7 +871,9 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<'tcx, T> { fn try_fold_with>(self, folder: &mut F) -> Result { folder.try_fold_binder(self) } +} +impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for ty::Binder<'tcx, T> { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { visitor.visit_binder(self) } @@ -863,7 +886,9 @@ fn try_super_fold_with>( ) -> Result { self.try_map_bound(|ty| ty.try_fold_with(folder)) } +} +impl<'tcx, T: TypeVisitable<'tcx>> TypeSuperVisitable<'tcx> for ty::Binder<'tcx, T> { fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { self.as_ref().skip_binder().visit_with(visitor) } @@ -873,7 +898,11 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List>(self, folder: &mut F) -> Result { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_poly_existential_predicates(v)) } +} +impl<'tcx> TypeVisitable<'tcx> + for &'tcx ty::List>> +{ fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.iter().try_for_each(|p| p.visit_with(visitor)) } @@ -883,7 +912,9 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List { fn try_fold_with>(self, folder: &mut F) -> Result { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projs(v)) } +} +impl<'tcx> TypeVisitable<'tcx> for &'tcx ty::List { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.iter().try_for_each(|t| t.visit_with(visitor)) } @@ -915,7 +946,9 @@ fn try_fold_with>(self, folder: &mut F) -> Result TypeVisitable<'tcx> for ty::instance::Instance<'tcx> { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { use crate::ty::InstanceDef::*; self.substs.visit_with(visitor)?; @@ -941,7 +974,9 @@ impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> { fn try_fold_with>(self, folder: &mut F) -> Result { Ok(Self { instance: self.instance.try_fold_with(folder)?, promoted: self.promoted }) } +} +impl<'tcx> TypeVisitable<'tcx> for interpret::GlobalId<'tcx> { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.instance.visit_with(visitor) } @@ -951,7 +986,9 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { fn try_fold_with>(self, folder: &mut F) -> Result { folder.try_fold_ty(self) } +} +impl<'tcx> TypeVisitable<'tcx> for Ty<'tcx> { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { visitor.visit_ty(*self) } @@ -1001,7 +1038,9 @@ fn try_super_fold_with>( Ok(if *self.kind() == kind { self } else { folder.tcx().mk_ty(kind) }) } +} +impl<'tcx> TypeSuperVisitable<'tcx> for Ty<'tcx> { fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { match self.kind() { ty::RawPtr(ref tm) => tm.visit_with(visitor), @@ -1049,7 +1088,9 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> { fn try_fold_with>(self, folder: &mut F) -> Result { folder.try_fold_region(self) } +} +impl<'tcx> TypeVisitable<'tcx> for ty::Region<'tcx> { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { visitor.visit_region(*self) } @@ -1062,7 +1103,9 @@ fn try_super_fold_with>( ) -> Result { Ok(self) } +} +impl<'tcx> TypeSuperVisitable<'tcx> for ty::Region<'tcx> { fn super_visit_with>(&self, _visitor: &mut V) -> ControlFlow { ControlFlow::CONTINUE } @@ -1072,7 +1115,9 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> { fn try_fold_with>(self, folder: &mut F) -> Result { folder.try_fold_predicate(self) } +} +impl<'tcx> TypeVisitable<'tcx> for ty::Predicate<'tcx> { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { visitor.visit_predicate(*self) } @@ -1094,7 +1139,9 @@ fn try_super_fold_with>( let new = self.kind().try_fold_with(folder)?; Ok(folder.tcx().reuse_or_mk_predicate(self, new)) } +} +impl<'tcx> TypeSuperVisitable<'tcx> for ty::Predicate<'tcx> { fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { self.kind().visit_with(visitor) } @@ -1104,7 +1151,9 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { fn try_fold_with>(self, folder: &mut F) -> Result { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_predicates(v)) } +} +impl<'tcx> TypeVisitable<'tcx> for &'tcx ty::List> { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.iter().try_for_each(|p| p.visit_with(visitor)) } @@ -1114,7 +1163,9 @@ impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec fn try_fold_with>(self, folder: &mut F) -> Result { self.try_map_id(|x| x.try_fold_with(folder)) } +} +impl<'tcx, T: TypeVisitable<'tcx>, I: Idx> TypeVisitable<'tcx> for IndexVec { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.iter().try_for_each(|t| t.visit_with(visitor)) } @@ -1124,7 +1175,9 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Const<'tcx> { fn try_fold_with>(self, folder: &mut F) -> Result { folder.try_fold_const(self) } +} +impl<'tcx> TypeVisitable<'tcx> for ty::Const<'tcx> { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { visitor.visit_const(*self) } @@ -1143,7 +1196,9 @@ fn try_super_fold_with>( Ok(self) } } +} +impl<'tcx> TypeSuperVisitable<'tcx> for ty::Const<'tcx> { fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { self.ty().visit_with(visitor)?; self.kind().visit_with(visitor) @@ -1162,7 +1217,9 @@ fn try_fold_with>(self, folder: &mut F) -> Result self, }) } +} +impl<'tcx> TypeVisitable<'tcx> for ty::ConstKind<'tcx> { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { match *self { ty::ConstKind::Infer(ic) => ic.visit_with(visitor), @@ -1180,7 +1237,9 @@ impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> { fn try_fold_with>(self, _folder: &mut F) -> Result { Ok(self) } +} +impl<'tcx> TypeVisitable<'tcx> for InferConst<'tcx> { fn visit_with>(&self, _visitor: &mut V) -> ControlFlow { ControlFlow::CONTINUE } @@ -1190,7 +1249,9 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx> { fn try_fold_with>(self, folder: &mut F) -> Result { folder.try_fold_unevaluated(self) } +} +impl<'tcx> TypeVisitable<'tcx> for ty::Unevaluated<'tcx> { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { visitor.visit_unevaluated(*self) } @@ -1207,7 +1268,9 @@ fn try_super_fold_with>( promoted: self.promoted, }) } +} +impl<'tcx> TypeSuperVisitable<'tcx> for ty::Unevaluated<'tcx> { fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { self.substs.visit_with(visitor) } @@ -1217,7 +1280,9 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx, ()> { fn try_fold_with>(self, folder: &mut F) -> Result { Ok(self.expand().try_fold_with(folder)?.shrink()) } +} +impl<'tcx> TypeVisitable<'tcx> for ty::Unevaluated<'tcx, ()> { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.expand().visit_with(visitor) } @@ -1227,7 +1292,9 @@ impl<'tcx> TypeFoldable<'tcx> for hir::Constness { fn try_fold_with>(self, _: &mut F) -> Result { Ok(self) } +} +impl<'tcx> TypeVisitable<'tcx> for hir::Constness { fn visit_with>(&self, _: &mut V) -> ControlFlow { ControlFlow::CONTINUE } diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 72afada46f7..4ca8471c10b 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -6,6 +6,7 @@ FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitor, }; use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts}; +use crate::ty::visit::TypeVisitable; use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt}; use rustc_data_structures::intern::{Interned, WithStableHash}; @@ -205,7 +206,9 @@ fn try_fold_with>(self, folder: &mut F) -> Result ct.try_fold_with(folder).map(Into::into), } } +} +impl<'tcx> TypeVisitable<'tcx> for GenericArg<'tcx> { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { match self.unpack() { GenericArgKind::Lifetime(lt) => lt.visit_with(visitor), @@ -449,7 +452,9 @@ fn try_fold_with>(self, folder: &mut F) -> Result ty::util::fold_list(self, folder, |tcx, v| tcx.intern_substs(v)), } } +} +impl<'tcx> TypeVisitable<'tcx> for SubstsRef<'tcx> { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.iter().try_for_each(|t| t.visit_with(visitor)) } @@ -485,7 +490,9 @@ fn try_fold_with>(self, folder: &mut F) -> Result ty::util::fold_list(self, folder, |tcx, v| tcx.intern_type_list(v)), } } +} +impl<'tcx> TypeVisitable<'tcx> for &'tcx ty::List> { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.iter().try_for_each(|t| t.visit_with(visitor)) }