Folding revamp.

This commit makes type folding more like the way chalk does it.

Currently, `TypeFoldable` has `fold_with` and `super_fold_with` methods.
- `fold_with` is the standard entry point, and defaults to calling
  `super_fold_with`.
- `super_fold_with` does the actual work of traversing a type.
- For a few types of interest (`Ty`, `Region`, etc.) `fold_with` instead
  calls into a `TypeFolder`, which can then call back into
  `super_fold_with`.

With the new approach, `TypeFoldable` has `fold_with` and
`TypeSuperFoldable` has `super_fold_with`.
- `fold_with` is still the standard entry point, *and* it does the
  actual work of traversing a type, for all types except types of
  interest.
- `super_fold_with` is only implemented for the types of interest.

Benefits of the new model.
- I find it easier to understand. The distinction between types of
  interest and other types is clearer, and `super_fold_with` doesn't
  exist for most types.
- With the current model is easy to get confused and implement a
  `super_fold_with` method that should be left defaulted. (Some of the
  precursor commits fixed such cases.)
- With the current model it's easy to call `super_fold_with` within
  `TypeFolder` impls where `fold_with` should be called. The new
  approach makes this mistake impossible, and this commit fixes a number
  of such cases.
- It's potentially faster, because it avoids the `fold_with` ->
  `super_fold_with` call in all cases except types of interest. A lot of
  the time the compile would inline those away, but not necessarily
  always.
This commit is contained in:
Nicholas Nethercote 2022-06-02 11:38:15 +10:00
parent 7480b501b4
commit 90db033955
47 changed files with 292 additions and 337 deletions

View File

@ -1,5 +1,5 @@
use rustc_middle::mir::interpret::InterpResult; use rustc_middle::mir::interpret::InterpResult;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitor}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitor};
use std::convert::TryInto; use std::convert::TryInto;
use std::ops::ControlFlow; use std::ops::ControlFlow;
@ -47,7 +47,7 @@ where
match (is_used, subst.needs_subst()) { match (is_used, subst.needs_subst()) {
// Just in case there are closures or generators within this subst, // Just in case there are closures or generators within this subst,
// recurse. // recurse.
(true, true) => return subst.super_visit_with(self), (true, true) => return subst.visit_with(self),
// Confirm that polymorphization replaced the parameter with // Confirm that polymorphization replaced the parameter with
// `ty::Param`/`ty::ConstKind::Param`. // `ty::Param`/`ty::ConstKind::Param`.
(false, true) if cfg!(debug_assertions) => match subst.unpack() { (false, true) if cfg!(debug_assertions) => match subst.unpack() {

View File

@ -11,7 +11,7 @@ use crate::infer::canonical::{
}; };
use crate::infer::InferCtxt; use crate::infer::InferCtxt;
use rustc_middle::ty::flags::FlagComputation; use rustc_middle::ty::flags::FlagComputation;
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder}; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::subst::GenericArg; use rustc_middle::ty::subst::GenericArg;
use rustc_middle::ty::{self, BoundVar, InferConst, List, Ty, TyCtxt, TypeFlags}; use rustc_middle::ty::{self, BoundVar, InferConst, List, Ty, TyCtxt, TypeFlags};
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;

View File

@ -70,7 +70,7 @@ use rustc_middle::ty::{
self, self,
error::TypeError, error::TypeError,
subst::{GenericArgKind, Subst, SubstsRef}, subst::{GenericArgKind, Subst, SubstsRef},
Binder, EarlyBinder, List, Region, Ty, TyCtxt, TypeFoldable, Binder, EarlyBinder, List, Region, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable,
}; };
use rustc_span::{sym, symbol::kw, BytePos, DesugaringKind, Pos, Span}; use rustc_span::{sym, symbol::kw, BytePos, DesugaringKind, Pos, Span};
use rustc_target::spec::abi; use rustc_target::spec::abi;

View File

@ -10,7 +10,7 @@ use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::{walk_ty, Visitor}; use rustc_hir::intravisit::{walk_ty, Visitor};
use rustc_hir::{self as hir, GenericBound, Item, ItemKind, Lifetime, LifetimeName, Node, TyKind}; use rustc_hir::{self as hir, GenericBound, Item, ItemKind, Lifetime, LifetimeName, Node, TyKind};
use rustc_middle::ty::{ use rustc_middle::ty::{
self, AssocItemContainer, StaticLifetimeVisitor, Ty, TyCtxt, TypeFoldable, TypeVisitor, self, AssocItemContainer, StaticLifetimeVisitor, Ty, TyCtxt, TypeSuperFoldable, TypeVisitor,
}; };
use rustc_span::symbol::Ident; use rustc_span::symbol::Ident;
use rustc_span::Span; use rustc_span::Span;

View File

@ -11,7 +11,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::Visitor;
use rustc_middle::hir::nested_filter; use rustc_middle::hir::nested_filter;
use rustc_middle::ty::print::RegionHighlightMode; use rustc_middle::ty::print::RegionHighlightMode;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitor}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperFoldable, TypeVisitor};
use rustc_span::{Span, Symbol}; use rustc_span::{Span, Symbol};
use std::ops::ControlFlow; use std::ops::ControlFlow;

View File

@ -34,7 +34,7 @@ use super::InferCtxt;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_middle::infer::unify_key::ToType; use rustc_middle::infer::unify_key::ToType;
use rustc_middle::ty::fold::TypeFolder; use rustc_middle::ty::fold::TypeFolder;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable};
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
pub struct TypeFreshener<'a, 'tcx> { pub struct TypeFreshener<'a, 'tcx> {

View File

@ -1,4 +1,4 @@
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder}; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::{self, ConstVid, FloatVid, IntVid, RegionVid, Ty, TyCtxt, TyVid}; use rustc_middle::ty::{self, ConstVid, FloatVid, IntVid, RegionVid, Ty, TyCtxt, TyVid};
use super::type_variable::TypeVariableOrigin; use super::type_variable::TypeVariableOrigin;

View File

@ -23,7 +23,7 @@ use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKin
use rustc_middle::mir::interpret::{ErrorHandled, EvalToConstValueResult}; use rustc_middle::mir::interpret::{ErrorHandled, EvalToConstValueResult};
use rustc_middle::traits::select; use rustc_middle::traits::select;
use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder}; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::relate::RelateResult; use rustc_middle::ty::relate::RelateResult;
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef};
pub use rustc_middle::ty::IntVarValue; pub use rustc_middle::ty::IntVarValue;

View File

@ -27,7 +27,7 @@ use crate::infer::{ConstVarValue, ConstVariableValue};
use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_middle::ty::error::TypeError; use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::fold::{TypeFoldable, TypeVisitor}; use rustc_middle::ty::fold::{TypeFoldable, TypeSuperFoldable, TypeVisitor};
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
use rustc_middle::ty::{self, InferConst, Ty, TyCtxt}; use rustc_middle::ty::{self, InferConst, Ty, TyCtxt};
use rustc_span::Span; use rustc_span::Span;

View File

@ -9,7 +9,7 @@ use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::fold::BottomUpFolder;
use rustc_middle::ty::subst::{GenericArgKind, Subst}; use rustc_middle::ty::subst::{GenericArgKind, Subst};
use rustc_middle::ty::{ use rustc_middle::ty::{
self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeVisitor, self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitor,
}; };
use rustc_span::Span; use rustc_span::Span;

View File

@ -1,7 +1,7 @@
use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use super::{FixupError, FixupResult, InferCtxt, Span}; use super::{FixupError, FixupResult, InferCtxt, Span};
use rustc_middle::mir; use rustc_middle::mir;
use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFolder, TypeVisitor}; use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable, TypeVisitor};
use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable}; use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable};
use std::ops::ControlFlow; use std::ops::ControlFlow;

View File

@ -60,10 +60,7 @@ impl<'tcx> fmt::Debug for traits::MismatchedProjectionTypes<'tcx> {
// TypeFoldable implementations. // TypeFoldable implementations.
impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx, O> { impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx, O> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
Ok(traits::Obligation { Ok(traits::Obligation {
cause: self.cause, cause: self.cause,
recursion_depth: self.recursion_depth, recursion_depth: self.recursion_depth,
@ -72,7 +69,7 @@ impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx
}) })
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.predicate.visit_with(visitor)?; self.predicate.visit_with(visitor)?;
self.param_env.visit_with(visitor) self.param_env.visit_with(visitor)
} }

View File

@ -8,7 +8,7 @@ use rustc_hir::def_id::DefId;
use rustc_hir::{is_range_literal, Expr, ExprKind, Node}; use rustc_hir::{is_range_literal, Expr, ExprKind, Node};
use rustc_middle::ty::layout::{IntegerExt, LayoutOf, SizeSkeleton}; use rustc_middle::ty::layout::{IntegerExt, LayoutOf, SizeSkeleton};
use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, AdtKind, DefIdTree, Ty, TyCtxt, TypeFoldable}; use rustc_middle::ty::{self, AdtKind, DefIdTree, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable};
use rustc_span::source_map; use rustc_span::source_map;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use rustc_span::{Span, Symbol, DUMMY_SP}; use rustc_span::{Span, Symbol, DUMMY_SP};

View File

@ -30,14 +30,14 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::
s.bound_impl( s.bound_impl(
quote!(::rustc_middle::ty::fold::TypeFoldable<'tcx>), quote!(::rustc_middle::ty::fold::TypeFoldable<'tcx>),
quote! { quote! {
fn try_super_fold_with<__F: ::rustc_middle::ty::fold::FallibleTypeFolder<'tcx>>( fn try_fold_with<__F: ::rustc_middle::ty::fold::FallibleTypeFolder<'tcx>>(
self, self,
__folder: &mut __F __folder: &mut __F
) -> Result<Self, __F::Error> { ) -> Result<Self, __F::Error> {
Ok(match self { #body_fold }) Ok(match self { #body_fold })
} }
fn super_visit_with<__F: ::rustc_middle::ty::fold::TypeVisitor<'tcx>>( fn visit_with<__F: ::rustc_middle::ty::fold::TypeVisitor<'tcx>>(
&self, &self,
__folder: &mut __F __folder: &mut __F
) -> ::std::ops::ControlFlow<__F::BreakTy> { ) -> ::std::ops::ControlFlow<__F::BreakTy> {

View File

@ -52,14 +52,14 @@ macro_rules! TrivialTypeFoldableImpls {
(for <$tcx:lifetime> { $($ty:ty,)+ }) => { (for <$tcx:lifetime> { $($ty:ty,)+ }) => {
$( $(
impl<$tcx> $crate::ty::fold::TypeFoldable<$tcx> for $ty { impl<$tcx> $crate::ty::fold::TypeFoldable<$tcx> for $ty {
fn try_super_fold_with<F: $crate::ty::fold::FallibleTypeFolder<$tcx>>( fn try_fold_with<F: $crate::ty::fold::FallibleTypeFolder<$tcx>>(
self, self,
_: &mut F _: &mut F
) -> ::std::result::Result<$ty, F::Error> { ) -> ::std::result::Result<$ty, F::Error> {
Ok(self) Ok(self)
} }
fn super_visit_with<F: $crate::ty::fold::TypeVisitor<$tcx>>( fn visit_with<F: $crate::ty::fold::TypeVisitor<$tcx>>(
&self, &self,
_: &mut F) _: &mut F)
-> ::std::ops::ControlFlow<F::BreakTy> -> ::std::ops::ControlFlow<F::BreakTy>
@ -95,14 +95,14 @@ macro_rules! EnumTypeFoldableImpl {
impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s
$(where $($wc)*)* $(where $($wc)*)*
{ {
fn try_super_fold_with<V: $crate::ty::fold::FallibleTypeFolder<$tcx>>( fn try_fold_with<V: $crate::ty::fold::FallibleTypeFolder<$tcx>>(
self, self,
folder: &mut V, folder: &mut V,
) -> ::std::result::Result<Self, V::Error> { ) -> ::std::result::Result<Self, V::Error> {
EnumTypeFoldableImpl!(@FoldVariants(self, folder) input($($variants)*) output()) EnumTypeFoldableImpl!(@FoldVariants(self, folder) input($($variants)*) output())
} }
fn super_visit_with<V: $crate::ty::fold::TypeVisitor<$tcx>>( fn visit_with<V: $crate::ty::fold::TypeVisitor<$tcx>>(
&self, &self,
visitor: &mut V, visitor: &mut V,
) -> ::std::ops::ControlFlow<V::BreakTy> { ) -> ::std::ops::ControlFlow<V::BreakTy> {

View File

@ -7,7 +7,7 @@ use crate::mir::interpret::{ConstAllocation, ConstValue, GlobalAlloc, LitToConst
use crate::mir::visit::MirVisitable; use crate::mir::visit::MirVisitable;
use crate::ty::adjustment::PointerCast; use crate::ty::adjustment::PointerCast;
use crate::ty::codec::{TyDecoder, TyEncoder}; use crate::ty::codec::{TyDecoder, TyEncoder};
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeVisitor}; use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable, TypeVisitor};
use crate::ty::print::{FmtPrinter, Printer}; use crate::ty::print::{FmtPrinter, Printer};
use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef}; use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
use crate::ty::{self, List, Ty, TyCtxt}; use crate::ty::{self, List, Ty, TyCtxt};
@ -3399,20 +3399,14 @@ impl UserTypeProjection {
TrivialTypeFoldableAndLiftImpls! { ProjectionKind, } TrivialTypeFoldableAndLiftImpls! { ProjectionKind, }
impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection { impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
Ok(UserTypeProjection { Ok(UserTypeProjection {
base: self.base.try_fold_with(folder)?, base: self.base.try_fold_with(folder)?,
projs: self.projs.try_fold_with(folder)?, projs: self.projs.try_fold_with(folder)?,
}) })
} }
fn super_visit_with<Vs: TypeVisitor<'tcx>>( fn visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> ControlFlow<Vs::BreakTy> {
&self,
visitor: &mut Vs,
) -> ControlFlow<Vs::BreakTy> {
self.base.visit_with(visitor) self.base.visit_with(visitor)
// Note: there's nothing in `self.proj` to visit. // Note: there's nothing in `self.proj` to visit.
} }

View File

@ -16,10 +16,7 @@ TrivialTypeFoldableAndLiftImpls! {
} }
impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
use crate::mir::TerminatorKind::*; use crate::mir::TerminatorKind::*;
let kind = match self.kind { let kind = match self.kind {
@ -93,7 +90,7 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
Ok(Terminator { source_info: self.source_info, kind }) Ok(Terminator { source_info: self.source_info, kind })
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
use crate::mir::TerminatorKind::*; use crate::mir::TerminatorKind::*;
match self.kind { match self.kind {
@ -144,50 +141,41 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
} }
impl<'tcx> TypeFoldable<'tcx> for GeneratorKind { impl<'tcx> TypeFoldable<'tcx> for GeneratorKind {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
Ok(self) Ok(self)
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
ControlFlow::CONTINUE ControlFlow::CONTINUE
} }
} }
impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> { impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
Ok(Place { Ok(Place {
local: self.local.try_fold_with(folder)?, local: self.local.try_fold_with(folder)?,
projection: self.projection.try_fold_with(folder)?, projection: self.projection.try_fold_with(folder)?,
}) })
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.local.visit_with(visitor)?; self.local.visit_with(visitor)?;
self.projection.visit_with(visitor) self.projection.visit_with(visitor)
} }
} }
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> { impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_place_elems(v)) ty::util::fold_list(self, folder, |tcx, v| tcx.intern_place_elems(v))
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.iter().try_for_each(|t| t.visit_with(visitor)) self.iter().try_for_each(|t| t.visit_with(visitor))
} }
} }
impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> { impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
use crate::mir::Rvalue::*; use crate::mir::Rvalue::*;
Ok(match self { Ok(match self {
Use(op) => Use(op.try_fold_with(folder)?), Use(op) => Use(op.try_fold_with(folder)?),
@ -237,7 +225,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
}) })
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
use crate::mir::Rvalue::*; use crate::mir::Rvalue::*;
match *self { match *self {
Use(ref op) => op.visit_with(visitor), Use(ref op) => op.visit_with(visitor),
@ -288,10 +276,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
} }
impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> { impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
Ok(match self { Ok(match self {
Operand::Copy(place) => Operand::Copy(place.try_fold_with(folder)?), Operand::Copy(place) => Operand::Copy(place.try_fold_with(folder)?),
Operand::Move(place) => Operand::Move(place.try_fold_with(folder)?), Operand::Move(place) => Operand::Move(place.try_fold_with(folder)?),
@ -299,7 +284,7 @@ impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
}) })
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
match *self { match *self {
Operand::Copy(ref place) | Operand::Move(ref place) => place.visit_with(visitor), Operand::Copy(ref place) | Operand::Move(ref place) => place.visit_with(visitor),
Operand::Constant(ref c) => c.visit_with(visitor), Operand::Constant(ref c) => c.visit_with(visitor),
@ -308,10 +293,7 @@ impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
} }
impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> { impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
use crate::mir::ProjectionElem::*; use crate::mir::ProjectionElem::*;
Ok(match self { Ok(match self {
@ -326,10 +308,7 @@ impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> {
}) })
} }
fn super_visit_with<Vs: TypeVisitor<'tcx>>( fn visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> ControlFlow<Vs::BreakTy> {
&self,
visitor: &mut Vs,
) -> ControlFlow<Vs::BreakTy> {
use crate::mir::ProjectionElem::*; use crate::mir::ProjectionElem::*;
match self { match self {
@ -341,44 +320,41 @@ impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> {
} }
impl<'tcx> TypeFoldable<'tcx> for Field { impl<'tcx> TypeFoldable<'tcx> for Field {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
Ok(self) Ok(self)
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
ControlFlow::CONTINUE ControlFlow::CONTINUE
} }
} }
impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal { impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
Ok(self) Ok(self)
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
ControlFlow::CONTINUE ControlFlow::CONTINUE
} }
} }
impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix<R, C> { impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix<R, C> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
Ok(self) Ok(self)
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
ControlFlow::CONTINUE ControlFlow::CONTINUE
} }
} }
impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> { impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
Ok(Constant { Ok(Constant {
span: self.span, span: self.span,
user_ty: self.user_ty.try_fold_with(folder)?, user_ty: self.user_ty.try_fold_with(folder)?,
literal: self.literal.try_fold_with(folder)?, literal: self.literal.try_fold_with(folder)?,
}) })
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.literal.visit_with(visitor)?; self.literal.visit_with(visitor)?;
self.user_ty.visit_with(visitor) self.user_ty.visit_with(visitor)
} }
@ -390,6 +366,12 @@ impl<'tcx> TypeFoldable<'tcx> for ConstantKind<'tcx> {
folder.try_fold_mir_const(self) folder.try_fold_mir_const(self)
} }
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
visitor.visit_mir_const(*self)
}
}
impl<'tcx> TypeSuperFoldable<'tcx> for ConstantKind<'tcx> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
self, self,
folder: &mut F, folder: &mut F,
@ -406,8 +388,4 @@ impl<'tcx> TypeFoldable<'tcx> for ConstantKind<'tcx> {
ConstantKind::Val(_, t) => t.visit_with(visitor), ConstantKind::Val(_, t) => t.visit_with(visitor),
} }
} }
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
visitor.visit_mir_const(*self)
}
} }

View File

@ -1,5 +1,5 @@
use crate::mir; use crate::mir;
use crate::ty::fold::{TypeFoldable, TypeFolder}; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use crate::ty::{self, Ty, TyCtxt, TypeFlags}; use crate::ty::{self, Ty, TyCtxt, TypeFlags};
pub(super) fn provide(providers: &mut ty::query::Providers) { pub(super) fn provide(providers: &mut ty::query::Providers) {

View File

@ -15,16 +15,20 @@
//! the ones containing the most important type-related information, such as //! the ones containing the most important type-related information, such as
//! `Ty`, `Predicate`, `Region`, and `Const`. //! `Ty`, `Predicate`, `Region`, and `Const`.
//! //!
//! There are two traits involved in each traversal type. //! There are three traits involved in each traversal type.
//! - The first trait is `TypeFoldable`, which is implemented once for many //! - `TypeFoldable`. This is implemented once for many types. This includes
//! types. This includes both (a) types of interest, and (b) all other //! both:
//! relevant types, including generic containers like `Vec` and `Option`. It //! - Types of interest, for which the the methods delegate to the
//! defines a "skeleton" of how they should be traversed, for both folding //! folder/visitor.
//! and visiting. //! - All other types, including generic containers like `Vec` and `Option`.
//! - The second trait is `TypeFolder`/`FallibleTypeFolder` (for //! It defines a "skeleton" of how they should be traversed, for both
//! infallible/fallible folding traversals) or `TypeVisitor` (for visiting //! folding and visiting.
//! traversals). One of these is implemented for each folder/visitor. This //! - `TypeSuperFoldable`. This is implemented only for each type of interest,
//! defines how types of interest are handled. //! and defines the traversal "skeleton" for these types.
//! - `TypeFolder`/`FallibleTypeFolder` (for infallible/fallible folding
//! traversals) or `TypeVisitor` (for visiting traversals). One of these is
//! implemented for each folder/visitor. This defines how types of interest
//! are folded/visited.
//! //!
//! This means each traversal is a mixture of (a) generic traversal operations, //! This means each traversal is a mixture of (a) generic traversal operations,
//! and (b) custom fold/visit operations that are specific to the //! and (b) custom fold/visit operations that are specific to the
@ -32,22 +36,23 @@
//! - The `TypeFoldable` impls handle most of the traversal, and call into //! - The `TypeFoldable` impls handle most of the traversal, and call into
//! `TypeFolder`/`FallibleTypeFolder`/`TypeVisitor` when they encounter a //! `TypeFolder`/`FallibleTypeFolder`/`TypeVisitor` when they encounter a
//! type of interest. //! type of interest.
//! - A `TypeFolder`/`FallibleTypeFolder`/`TypeVisitor` may also call back into //! - A `TypeFolder`/`FallibleTypeFolder`/`TypeVisitor` may call into another
//! a `TypeFoldable` impl, because (a) the types of interest are recursive //! `TypeFoldable` impl, because some of the types of interest are recursive
//! and can contain other types of interest, and (b) each folder/visitor //! and can contain other types of interest.
//! might provide custom handling only for some types of interest, or only //! - A `TypeFolder`/`FallibleTypeFolder`/`TypeVisitor` may also call into
//! for some variants of each type of interest, and then use default //! a `TypeSuperFoldable` impl, because each folder/visitor might provide
//! traversal for the remaining cases. //! custom handling only for some types of interest, or only for some
//! variants of each type of interest, and then use default traversal for the
//! remaining cases.
//! //!
//! For example, if you have `struct S(Ty, U)` where `S: TypeFoldable` and `U: //! For example, if you have `struct S(Ty, U)` where `S: TypeFoldable` and `U:
//! TypeFoldable`, and an instance `S(ty, u)`, it would be visited like so: //! TypeFoldable`, and an instance `s = S(ty, u)`, it would be visited like so:
//! ```text //! ```text
//! s.visit_with(visitor) calls //! s.visit_with(visitor) calls
//! - s.super_visit_with(visitor) calls //! - ty.visit_with(visitor) calls
//! - ty.visit_with(visitor) calls //! - visitor.visit_ty(ty) may call
//! - visitor.visit_ty(ty) may call //! - ty.super_visit_with(visitor)
//! - ty.super_visit_with(visitor) //! - u.visit_with(visitor)
//! - u.visit_with(visitor)
//! ``` //! ```
use crate::mir; use crate::mir;
use crate::ty::{self, flags::FlagComputation, Binder, Ty, TyCtxt, TypeFlags}; use crate::ty::{self, flags::FlagComputation, Binder, Ty, TyCtxt, TypeFlags};
@ -66,18 +71,17 @@ use std::ops::ControlFlow;
/// To implement this conveniently, use the derive macro located in /// To implement this conveniently, use the derive macro located in
/// `rustc_macros`. /// `rustc_macros`.
pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
/// The main entry point for folding. To fold a value `t` with a folder `f` /// The entry point for folding. To fold a value `t` with a folder `f`
/// call: `t.try_fold_with(f)`. /// call: `t.try_fold_with(f)`.
/// ///
/// For types of interest (such as `Ty`), this default is overridden with a /// For most types, this just traverses the value, calling `try_fold_with`
/// method that calls a folder method specifically for that type (such as /// on each field/element.
///
/// For types of interest (such as `Ty`), the implementation of method
/// calls a folder method specifically for that type (such as
/// `F::try_fold_ty`). This is where control transfers from `TypeFoldable` /// `F::try_fold_ty`). This is where control transfers from `TypeFoldable`
/// to `TypeFolder`. /// to `TypeFolder`.
/// fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error>;
/// For other types, this default is used.
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self.try_super_fold_with(folder)
}
/// A convenient alternative to `try_fold_with` for use with infallible /// A convenient alternative to `try_fold_with` for use with infallible
/// folders. Do not override this method, to ensure coherence with /// folders. Do not override this method, to ensure coherence with
@ -86,40 +90,17 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
self.try_fold_with(folder).into_ok() self.try_fold_with(folder).into_ok()
} }
/// Traverses the type in question, typically by calling `try_fold_with` on
/// each field/element. This is true even for types of interest such as
/// `Ty`. This should only be called within `TypeFolder` methods, when
/// non-custom traversals are desired for types of interest.
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
self,
folder: &mut F,
) -> Result<Self, F::Error>;
/// A convenient alternative to `try_super_fold_with` for use with
/// infallible folders. Do not override this method, to ensure coherence
/// with `try_super_fold_with`.
fn super_fold_with<F: TypeFolder<'tcx, Error = !>>(self, folder: &mut F) -> Self {
self.try_super_fold_with(folder).into_ok()
}
/// The entry point for visiting. To visit a value `t` with a visitor `v` /// The entry point for visiting. To visit a value `t` with a visitor `v`
/// call: `t.visit_with(v)`. /// call: `t.visit_with(v)`.
/// ///
/// For types of interest (such as `Ty`), this default is overridden with a /// For most types, this just traverses the value, calling `visit_with` on
/// method that calls a visitor method specifically for that type (such as /// each field/element.
///
/// For types of interest (such as `Ty`), the implementation of this method
/// that calls a visitor method specifically for that type (such as
/// `V::visit_ty`). This is where control transfers from `TypeFoldable` to /// `V::visit_ty`). This is where control transfers from `TypeFoldable` to
/// `TypeVisitor`. /// `TypeVisitor`.
/// fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy>;
/// For other types, this default is used.
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.super_visit_with(visitor)
}
/// Traverses the type in question, typically by calling `visit_with` on
/// each field/element. This is true even for types of interest such as
/// `Ty`. This should only be called within `TypeVisitor` methods, when
/// non-custom traversals are desired for types of interest.
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy>;
/// Returns `true` if `self` has any late-bound regions that are either /// Returns `true` if `self` has any late-bound regions that are either
/// bound by `binder` or bound by some binder outside of `binder`. /// bound by `binder` or bound by some binder outside of `binder`.
@ -219,9 +200,40 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
} }
} }
// This trait is implemented for types of interest.
pub trait TypeSuperFoldable<'tcx>: TypeFoldable<'tcx> {
/// Provides a default fold for a type of interest. This should only be
/// called within `TypeFolder` methods, when a non-custom traversal is
/// desired for the value of the type of interest passed to that method.
/// For example, in `MyFolder::try_fold_ty(ty)`, it is valid to call
/// `ty.try_super_fold_with(self)`, but any other folding should be done
/// with `xyz.try_fold_with(self)`.
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
self,
folder: &mut F,
) -> Result<Self, F::Error>;
/// A convenient alternative to `try_super_fold_with` for use with
/// infallible folders. Do not override this method, to ensure coherence
/// with `try_super_fold_with`.
fn super_fold_with<F: TypeFolder<'tcx, Error = !>>(self, folder: &mut F) -> Self {
self.try_super_fold_with(folder).into_ok()
}
/// Provides a default visit for a type of interest. This should only be
/// called within `TypeVisitor` methods, when a non-custom traversal is
/// desired for the value of the type of interest passed to that method.
/// For example, in `MyVisitor::visit_ty(ty)`, it is valid to call
/// `ty.super_visit_with(self)`, but any other visiting should be done
/// with `xyz.visit_with(self)`.
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy>;
}
/// This trait is implemented for every folding traversal. There is a fold /// This trait is implemented for every folding traversal. There is a fold
/// method defined for every type of interest. Each such method has a default /// method defined for every type of interest. Each such method has a default
/// that does an "identity" fold. /// that does an "identity" fold. Implementations of these methods often fall
/// back to a `super_fold_with` method if the primary argument doesn't
/// satisfy a particular condition.
/// ///
/// If this folder is fallible (and therefore its [`Error`][`TypeFolder::Error`] /// If this folder is fallible (and therefore its [`Error`][`TypeFolder::Error`]
/// associated type is something other than the default `!`) then /// associated type is something other than the default `!`) then

View File

@ -1,7 +1,7 @@
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use crate::ty::print::{FmtPrinter, Printer}; use crate::ty::print::{FmtPrinter, Printer};
use crate::ty::subst::{InternalSubsts, Subst}; use crate::ty::subst::{InternalSubsts, Subst};
use crate::ty::{self, EarlyBinder, SubstsRef, Ty, TyCtxt, TypeFoldable}; use crate::ty::{self, EarlyBinder, SubstsRef, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable};
use rustc_errors::ErrorGuaranteed; use rustc_errors::ErrorGuaranteed;
use rustc_hir::def::Namespace; use rustc_hir::def::Namespace;
use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::def_id::{CrateNum, DefId};

View File

@ -9,7 +9,9 @@
//! //!
//! ["The `ty` module: representing types"]: https://rustc-dev-guide.rust-lang.org/ty.html //! ["The `ty` module: representing types"]: https://rustc-dev-guide.rust-lang.org/ty.html
pub use self::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeVisitor}; pub use self::fold::{
FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitor,
};
pub use self::AssocItemContainer::*; pub use self::AssocItemContainer::*;
pub use self::BorrowKind::*; pub use self::BorrowKind::*;
pub use self::IntVarValue::*; pub use self::IntVarValue::*;
@ -1434,7 +1436,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ParamEnv<'tcx> {
} }
impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> { impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> {
fn try_super_fold_with<F: ty::fold::FallibleTypeFolder<'tcx>>( fn try_fold_with<F: ty::fold::FallibleTypeFolder<'tcx>>(
self, self,
folder: &mut F, folder: &mut F,
) -> Result<Self, F::Error> { ) -> Result<Self, F::Error> {
@ -1445,7 +1447,7 @@ impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> {
)) ))
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.caller_bounds().visit_with(visitor)?; self.caller_bounds().visit_with(visitor)?;
self.reveal().visit_with(visitor)?; self.reveal().visit_with(visitor)?;
self.constness().visit_with(visitor) self.constness().visit_with(visitor)

View File

@ -1,6 +1,9 @@
use crate::mir::interpret::{AllocRange, ConstValue, GlobalAlloc, Pointer, Provenance, Scalar}; use crate::mir::interpret::{AllocRange, ConstValue, GlobalAlloc, Pointer, Provenance, Scalar};
use crate::ty::subst::{GenericArg, GenericArgKind, Subst}; use crate::ty::subst::{GenericArg, GenericArgKind, Subst};
use crate::ty::{self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, Ty, TyCtxt, TypeFoldable}; use crate::ty::{
self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, Ty, TyCtxt, TypeFoldable,
TypeSuperFoldable,
};
use rustc_apfloat::ieee::{Double, Single}; use rustc_apfloat::ieee::{Double, Single};
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sso::SsoHashSet; use rustc_data_structures::sso::SsoHashSet;

View File

@ -4,7 +4,7 @@
use crate::mir::interpret; use crate::mir::interpret;
use crate::mir::ProjectionKind; use crate::mir::ProjectionKind;
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeVisitor}; use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable, TypeVisitor};
use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer}; use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
use crate::ty::{self, InferConst, Lift, Term, Ty, TyCtxt}; use crate::ty::{self, InferConst, Lift, Term, Ty, TyCtxt};
use rustc_data_structures::functor::IdFunctor; use rustc_data_structures::functor::IdFunctor;
@ -672,27 +672,24 @@ impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> {
/// AdtDefs are basically the same as a DefId. /// AdtDefs are basically the same as a DefId.
impl<'tcx> TypeFoldable<'tcx> for ty::AdtDef<'tcx> { impl<'tcx> TypeFoldable<'tcx> for ty::AdtDef<'tcx> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> {
self,
_folder: &mut F,
) -> Result<Self, F::Error> {
Ok(self) Ok(self)
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
ControlFlow::CONTINUE ControlFlow::CONTINUE
} }
} }
impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) { impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(
self, self,
folder: &mut F, folder: &mut F,
) -> Result<(T, U), F::Error> { ) -> Result<(T, U), F::Error> {
Ok((self.0.try_fold_with(folder)?, self.1.try_fold_with(folder)?)) Ok((self.0.try_fold_with(folder)?, self.1.try_fold_with(folder)?))
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.0.visit_with(visitor)?; self.0.visit_with(visitor)?;
self.1.visit_with(visitor) self.1.visit_with(visitor)
} }
@ -701,7 +698,7 @@ impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for
impl<'tcx, A: TypeFoldable<'tcx>, B: TypeFoldable<'tcx>, C: TypeFoldable<'tcx>> TypeFoldable<'tcx> impl<'tcx, A: TypeFoldable<'tcx>, B: TypeFoldable<'tcx>, C: TypeFoldable<'tcx>> TypeFoldable<'tcx>
for (A, B, C) for (A, B, C)
{ {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(
self, self,
folder: &mut F, folder: &mut F,
) -> Result<(A, B, C), F::Error> { ) -> Result<(A, B, C), F::Error> {
@ -712,7 +709,7 @@ impl<'tcx, A: TypeFoldable<'tcx>, B: TypeFoldable<'tcx>, C: TypeFoldable<'tcx>>
)) ))
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.0.visit_with(visitor)?; self.0.visit_with(visitor)?;
self.1.visit_with(visitor)?; self.1.visit_with(visitor)?;
self.2.visit_with(visitor) self.2.visit_with(visitor)
@ -734,7 +731,7 @@ EnumTypeFoldableImpl! {
} }
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> { impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(
mut self, mut self,
folder: &mut F, folder: &mut F,
) -> Result<Self, F::Error> { ) -> Result<Self, F::Error> {
@ -772,13 +769,13 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
} }
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
(**self).visit_with(visitor) (**self).visit_with(visitor)
} }
} }
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc<T> { impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc<T> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(
mut self, mut self,
folder: &mut F, folder: &mut F,
) -> Result<Self, F::Error> { ) -> Result<Self, F::Error> {
@ -816,115 +813,96 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc<T> {
} }
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
(**self).visit_with(visitor) (**self).visit_with(visitor)
} }
} }
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> { impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
self.try_map_id(|value| value.try_fold_with(folder)) self.try_map_id(|value| value.try_fold_with(folder))
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
(**self).visit_with(visitor) (**self).visit_with(visitor)
} }
} }
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> { impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
self.try_map_id(|t| t.try_fold_with(folder)) self.try_map_id(|t| t.try_fold_with(folder))
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.iter().try_for_each(|t| t.visit_with(visitor)) self.iter().try_for_each(|t| t.visit_with(visitor))
} }
} }
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> { impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
self.try_map_id(|t| t.try_fold_with(folder)) self.try_map_id(|t| t.try_fold_with(folder))
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.iter().try_for_each(|t| t.visit_with(visitor)) self.iter().try_for_each(|t| t.visit_with(visitor))
} }
} }
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::EarlyBinder<T> { impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::EarlyBinder<T> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
self.try_map_bound(|ty| ty.try_fold_with(folder)) self.try_map_bound(|ty| ty.try_fold_with(folder))
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.as_ref().0.visit_with(visitor) self.as_ref().0.visit_with(visitor)
} }
} }
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<'tcx, T> { impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<'tcx, T> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
self,
folder: &mut F,
) -> Result<Self, F::Error> {
self.try_map_bound(|ty| ty.try_fold_with(folder))
}
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
folder.try_fold_binder(self) folder.try_fold_binder(self)
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.as_ref().skip_binder().visit_with(visitor)
}
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
visitor.visit_binder(self) visitor.visit_binder(self)
} }
} }
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>> { impl<'tcx, T: TypeFoldable<'tcx>> TypeSuperFoldable<'tcx> for ty::Binder<'tcx, T> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
self, self,
folder: &mut F, folder: &mut F,
) -> Result<Self, F::Error> { ) -> Result<Self, F::Error> {
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_poly_existential_predicates(v)) self.try_map_bound(|ty| ty.try_fold_with(folder))
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.as_ref().skip_binder().visit_with(visitor)
}
}
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>> {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_poly_existential_predicates(v))
}
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.iter().try_for_each(|p| p.visit_with(visitor)) self.iter().try_for_each(|p| p.visit_with(visitor))
} }
} }
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> { impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projs(v)) ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projs(v))
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.iter().try_for_each(|t| t.visit_with(visitor)) self.iter().try_for_each(|t| t.visit_with(visitor))
} }
} }
impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
use crate::ty::InstanceDef::*; use crate::ty::InstanceDef::*;
Ok(Self { Ok(Self {
substs: self.substs.try_fold_with(folder)?, substs: self.substs.try_fold_with(folder)?,
@ -950,7 +928,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
}) })
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
use crate::ty::InstanceDef::*; use crate::ty::InstanceDef::*;
self.substs.visit_with(visitor)?; self.substs.visit_with(visitor)?;
match self.def { match self.def {
@ -972,19 +950,26 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
} }
impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> { impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
Ok(Self { instance: self.instance.try_fold_with(folder)?, promoted: self.promoted }) Ok(Self { instance: self.instance.try_fold_with(folder)?, promoted: self.promoted })
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.instance.visit_with(visitor) self.instance.visit_with(visitor)
} }
} }
impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
folder.try_fold_ty(self)
}
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
visitor.visit_ty(*self)
}
}
impl<'tcx> TypeSuperFoldable<'tcx> for Ty<'tcx> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
self, self,
folder: &mut F, folder: &mut F,
@ -1029,10 +1014,6 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
Ok(if *self.kind() == kind { self } else { folder.tcx().mk_ty(kind) }) Ok(if *self.kind() == kind { self } else { folder.tcx().mk_ty(kind) })
} }
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
folder.try_fold_ty(self)
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
match self.kind() { match self.kind() {
ty::RawPtr(ref tm) => tm.visit_with(visitor), ty::RawPtr(ref tm) => tm.visit_with(visitor),
@ -1074,50 +1055,36 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
| ty::Foreign(..) => ControlFlow::CONTINUE, | ty::Foreign(..) => ControlFlow::CONTINUE,
} }
} }
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
visitor.visit_ty(*self)
}
} }
impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> { impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
self,
_folder: &mut F,
) -> Result<Self, F::Error> {
Ok(self)
}
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
folder.try_fold_region(self) folder.try_fold_region(self)
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
ControlFlow::CONTINUE
}
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
visitor.visit_region(*self) visitor.visit_region(*self)
} }
} }
impl<'tcx> TypeSuperFoldable<'tcx> for ty::Region<'tcx> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
self,
_folder: &mut F,
) -> Result<Self, F::Error> {
Ok(self)
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
ControlFlow::CONTINUE
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> { impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
folder.try_fold_predicate(self) folder.try_fold_predicate(self)
} }
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
self,
folder: &mut F,
) -> Result<Self, F::Error> {
let new = self.kind().try_fold_with(folder)?;
Ok(folder.tcx().reuse_or_mk_predicate(self, new))
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.kind().visit_with(visitor)
}
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
visitor.visit_predicate(*self) visitor.visit_predicate(*self)
} }
@ -1131,33 +1098,51 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
} }
} }
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> { impl<'tcx> TypeSuperFoldable<'tcx> for ty::Predicate<'tcx> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
self, self,
folder: &mut F, folder: &mut F,
) -> Result<Self, F::Error> { ) -> Result<Self, F::Error> {
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_predicates(v)) let new = self.kind().try_fold_with(folder)?;
Ok(folder.tcx().reuse_or_mk_predicate(self, new))
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.kind().visit_with(visitor)
}
}
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_predicates(v))
}
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.iter().try_for_each(|p| p.visit_with(visitor)) self.iter().try_for_each(|p| p.visit_with(visitor))
} }
} }
impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> { impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
self.try_map_id(|x| x.try_fold_with(folder)) self.try_map_id(|x| x.try_fold_with(folder))
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.iter().try_for_each(|t| t.visit_with(visitor)) self.iter().try_for_each(|t| t.visit_with(visitor))
} }
} }
impl<'tcx> TypeFoldable<'tcx> for ty::Const<'tcx> { impl<'tcx> TypeFoldable<'tcx> for ty::Const<'tcx> {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
folder.try_fold_const(self)
}
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
visitor.visit_const(*self)
}
}
impl<'tcx> TypeSuperFoldable<'tcx> for ty::Const<'tcx> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
self, self,
folder: &mut F, folder: &mut F,
@ -1171,25 +1156,14 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Const<'tcx> {
} }
} }
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
folder.try_fold_const(self)
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.ty().visit_with(visitor)?; self.ty().visit_with(visitor)?;
self.val().visit_with(visitor) self.val().visit_with(visitor)
} }
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
visitor.visit_const(*self)
}
} }
impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
Ok(match self { Ok(match self {
ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.try_fold_with(folder)?), ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.try_fold_with(folder)?),
ty::ConstKind::Param(p) => ty::ConstKind::Param(p.try_fold_with(folder)?), ty::ConstKind::Param(p) => ty::ConstKind::Param(p.try_fold_with(folder)?),
@ -1201,7 +1175,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
}) })
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
match *self { match *self {
ty::ConstKind::Infer(ic) => ic.visit_with(visitor), ty::ConstKind::Infer(ic) => ic.visit_with(visitor),
ty::ConstKind::Param(p) => p.visit_with(visitor), ty::ConstKind::Param(p) => p.visit_with(visitor),
@ -1215,14 +1189,11 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
} }
impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> { impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> {
self,
_folder: &mut F,
) -> Result<Self, F::Error> {
Ok(self) Ok(self)
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
ControlFlow::CONTINUE ControlFlow::CONTINUE
} }
} }
@ -1232,6 +1203,12 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx> {
folder.try_fold_unevaluated(self) folder.try_fold_unevaluated(self)
} }
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
visitor.visit_unevaluated(*self)
}
}
impl<'tcx> TypeSuperFoldable<'tcx> for ty::Unevaluated<'tcx> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
self, self,
folder: &mut F, folder: &mut F,
@ -1243,34 +1220,27 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx> {
}) })
} }
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
visitor.visit_unevaluated(*self)
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.substs.visit_with(visitor) self.substs.visit_with(visitor)
} }
} }
impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx, ()> { impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx, ()> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
Ok(self.expand().try_fold_with(folder)?.shrink()) Ok(self.expand().try_fold_with(folder)?.shrink())
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.expand().visit_with(visitor) self.expand().visit_with(visitor)
} }
} }
impl<'tcx> TypeFoldable<'tcx> for hir::Constness { impl<'tcx> TypeFoldable<'tcx> for hir::Constness {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
Ok(self) Ok(self)
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
ControlFlow::CONTINUE ControlFlow::CONTINUE
} }
} }

View File

@ -7,7 +7,8 @@ use crate::ty::fold::ValidateBoundVars;
use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef}; use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
use crate::ty::InferTy::*; use crate::ty::InferTy::*;
use crate::ty::{ use crate::ty::{
self, AdtDef, DefIdTree, Discr, Term, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeVisitor, self, AdtDef, DefIdTree, Discr, Term, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeSuperFoldable,
TypeVisitor,
}; };
use crate::ty::{List, ParamEnv}; use crate::ty::{List, ParamEnv};
use polonius_engine::Atom; use polonius_engine::Atom;

View File

@ -2,7 +2,9 @@
use crate::mir; use crate::mir;
use crate::ty::codec::{TyDecoder, TyEncoder}; use crate::ty::codec::{TyDecoder, TyEncoder};
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::fold::{
FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitor,
};
use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts}; use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts};
use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt}; use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};
@ -196,10 +198,7 @@ impl<'a, 'tcx> Lift<'tcx> for GenericArg<'a> {
} }
impl<'tcx> TypeFoldable<'tcx> for GenericArg<'tcx> { impl<'tcx> TypeFoldable<'tcx> for GenericArg<'tcx> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
match self.unpack() { match self.unpack() {
GenericArgKind::Lifetime(lt) => lt.try_fold_with(folder).map(Into::into), GenericArgKind::Lifetime(lt) => lt.try_fold_with(folder).map(Into::into),
GenericArgKind::Type(ty) => ty.try_fold_with(folder).map(Into::into), GenericArgKind::Type(ty) => ty.try_fold_with(folder).map(Into::into),
@ -207,7 +206,7 @@ impl<'tcx> TypeFoldable<'tcx> for GenericArg<'tcx> {
} }
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
match self.unpack() { match self.unpack() {
GenericArgKind::Lifetime(lt) => lt.visit_with(visitor), GenericArgKind::Lifetime(lt) => lt.visit_with(visitor),
GenericArgKind::Type(ty) => ty.visit_with(visitor), GenericArgKind::Type(ty) => ty.visit_with(visitor),
@ -425,10 +424,7 @@ impl<'tcx> InternalSubsts<'tcx> {
} }
impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> { impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
// This code is hot enough that it's worth specializing for the most // This code is hot enough that it's worth specializing for the most
// common length lists, to avoid the overhead of `SmallVec` creation. // common length lists, to avoid the overhead of `SmallVec` creation.
// The match arms are in order of frequency. The 1, 2, and 0 cases are // The match arms are in order of frequency. The 1, 2, and 0 cases are
@ -454,16 +450,13 @@ impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> {
} }
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.iter().try_for_each(|t| t.visit_with(visitor)) self.iter().try_for_each(|t| t.visit_with(visitor))
} }
} }
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> { impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
// This code is fairly hot, though not as hot as `SubstsRef`. // This code is fairly hot, though not as hot as `SubstsRef`.
// //
// When compiling stage 2, I get the following results: // When compiling stage 2, I get the following results:
@ -493,7 +486,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
} }
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.iter().try_for_each(|t| t.visit_with(visitor)) self.iter().try_for_each(|t| t.visit_with(visitor))
} }
} }

View File

@ -1,11 +1,12 @@
//! Miscellaneous type-system utilities that are too small to deserve their own modules. //! Miscellaneous type-system utilities that are too small to deserve their own modules.
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use crate::ty::fold::{FallibleTypeFolder, TypeFolder};
use crate::ty::layout::IntegerExt; use crate::ty::layout::IntegerExt;
use crate::ty::query::TyCtxtAt; use crate::ty::query::TyCtxtAt;
use crate::ty::subst::{GenericArgKind, Subst, SubstsRef}; use crate::ty::subst::{GenericArgKind, Subst, SubstsRef};
use crate::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable}; use crate::ty::{
self, DefIdTree, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
};
use rustc_apfloat::Float as _; use rustc_apfloat::Float as _;
use rustc_ast as ast; use rustc_ast as ast;
use rustc_attr::{self as attr, SignedInt, UnsignedInt}; use rustc_attr::{self as attr, SignedInt, UnsignedInt};

View File

@ -13,7 +13,7 @@ use rustc_middle::mir::{
}; };
use rustc_middle::ty::{ use rustc_middle::ty::{
self, self,
fold::{TypeFoldable, TypeVisitor}, fold::{TypeFoldable, TypeSuperFoldable, TypeVisitor},
query::Providers, query::Providers,
subst::SubstsRef, subst::SubstsRef,
Const, Ty, TyCtxt, Const, Ty, TyCtxt,

View File

@ -20,11 +20,10 @@ use rustc_middle::hir::nested_filter;
use rustc_middle::middle::privacy::{AccessLevel, AccessLevels}; use rustc_middle::middle::privacy::{AccessLevel, AccessLevels};
use rustc_middle::span_bug; use rustc_middle::span_bug;
use rustc_middle::thir::abstract_const::Node as ACNode; use rustc_middle::thir::abstract_const::Node as ACNode;
use rustc_middle::ty::fold::TypeVisitor;
use rustc_middle::ty::query::Providers; use rustc_middle::ty::query::Providers;
use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::{self, Const, DefIdTree, GenericParamDefKind}; use rustc_middle::ty::{self, Const, DefIdTree, GenericParamDefKind};
use rustc_middle::ty::{TraitRef, Ty, TyCtxt, TypeFoldable}; use rustc_middle::ty::{TraitRef, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitor};
use rustc_session::lint; use rustc_session::lint;
use rustc_span::hygiene::Transparency; use rustc_span::hygiene::Transparency;
use rustc_span::symbol::{kw, Ident}; use rustc_span::symbol::{kw, Ident};
@ -181,7 +180,8 @@ where
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<V::BreakTy> { fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<V::BreakTy> {
let tcx = self.def_id_visitor.tcx(); let tcx = self.def_id_visitor.tcx();
// InternalSubsts are not visited here because they are visited below in `super_visit_with`. // InternalSubsts are not visited here because they are visited below
// in `super_visit_with`.
match *ty.kind() { match *ty.kind() {
ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), ..) ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), ..)
| ty::Foreign(def_id) | ty::Foreign(def_id)

View File

@ -7,7 +7,7 @@ use rustc_hir::OpaqueTyOrigin;
use rustc_infer::infer::error_reporting::unexpected_hidden_region_diagnostic; use rustc_infer::infer::error_reporting::unexpected_hidden_region_diagnostic;
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt as _}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt as _};
use rustc_infer::traits::{Obligation, ObligationCause, TraitEngine}; use rustc_infer::traits::{Obligation, ObligationCause, TraitEngine};
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder}; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts};
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, ToPredicate, Ty, TyCtxt}; use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, ToPredicate, Ty, TyCtxt};
use rustc_span::Span; use rustc_span::Span;

View File

@ -6,7 +6,7 @@ use super::*;
use crate::infer::region_constraints::{Constraint, RegionConstraintData}; use crate::infer::region_constraints::{Constraint, RegionConstraintData};
use crate::infer::InferCtxt; use crate::infer::InferCtxt;
use crate::traits::project::ProjectAndUnifyResult; use crate::traits::project::ProjectAndUnifyResult;
use rustc_middle::ty::fold::TypeFolder; use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::{Region, RegionVid, Term}; use rustc_middle::ty::{Region, RegionVid, Term};
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};

View File

@ -27,7 +27,7 @@ use rustc_infer::traits::TraitEngine;
use rustc_middle::thir::abstract_const::NotConstEvaluatable; use rustc_middle::thir::abstract_const::NotConstEvaluatable;
use rustc_middle::traits::select::OverflowError; use rustc_middle::traits::select::OverflowError;
use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::error::ExpectedFound;
use rustc_middle::ty::fold::TypeFolder; use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::{ use rustc_middle::ty::{
self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable, self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable,
}; };

View File

@ -18,7 +18,9 @@ use rustc_errors::{FatalError, MultiSpan};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_middle::ty::subst::{GenericArg, InternalSubsts, Subst}; use rustc_middle::ty::subst::{GenericArg, InternalSubsts, Subst};
use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeVisitor}; use rustc_middle::ty::{
self, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitor,
};
use rustc_middle::ty::{Predicate, ToPredicate}; use rustc_middle::ty::{Predicate, ToPredicate};
use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY; use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY;
use rustc_span::symbol::Symbol; use rustc_span::symbol::Symbol;

View File

@ -29,7 +29,7 @@ use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem; use rustc_hir::lang_items::LangItem;
use rustc_infer::infer::resolve::OpportunisticRegionResolver; use rustc_infer::infer::resolve::OpportunisticRegionResolver;
use rustc_middle::traits::select::OverflowError; use rustc_middle::traits::select::OverflowError;
use rustc_middle::ty::fold::{MaxUniverse, TypeFoldable, TypeFolder}; use rustc_middle::ty::fold::{MaxUniverse, TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::subst::Subst; use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::{self, EarlyBinder, Term, ToPredicate, Ty, TyCtxt}; use rustc_middle::ty::{self, EarlyBinder, Term, ToPredicate, Ty, TyCtxt};
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
@ -514,7 +514,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
self.selcx.infcx().report_overflow_error(&obligation, true); self.selcx.infcx().report_overflow_error(&obligation, true);
} }
let substs = substs.super_fold_with(self); let substs = substs.fold_with(self);
let generic_ty = self.tcx().bound_type_of(def_id); let generic_ty = self.tcx().bound_type_of(def_id);
let concrete_ty = generic_ty.subst(self.tcx(), substs); let concrete_ty = generic_ty.subst(self.tcx(), substs);
self.depth += 1; self.depth += 1;
@ -531,8 +531,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
// placeholders (see branch below). *Also*, we know that we can // placeholders (see branch below). *Also*, we know that we can
// register an obligation to *later* project, since we know // register an obligation to *later* project, since we know
// there won't be bound vars there. // there won't be bound vars there.
let data = data.fold_with(self);
let data = data.super_fold_with(self);
let normalized_ty = if self.eager_inference_replacement { let normalized_ty = if self.eager_inference_replacement {
normalize_projection_type( normalize_projection_type(
self.selcx, self.selcx,
@ -581,7 +580,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
let infcx = self.selcx.infcx(); let infcx = self.selcx.infcx();
let (data, mapped_regions, mapped_types, mapped_consts) = let (data, mapped_regions, mapped_types, mapped_consts) =
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data); BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data);
let data = data.super_fold_with(self); let data = data.fold_with(self);
let normalized_ty = opt_normalize_projection_type( let normalized_ty = opt_normalize_projection_type(
self.selcx, self.selcx,
self.param_env, self.param_env,
@ -671,7 +670,7 @@ impl<'me, 'tcx> BoundVarReplacer<'me, 'tcx> {
universe_indices, universe_indices,
}; };
let value = value.super_fold_with(&mut replacer); let value = value.fold_with(&mut replacer);
(value, replacer.mapped_regions, replacer.mapped_types, replacer.mapped_consts) (value, replacer.mapped_regions, replacer.mapped_types, replacer.mapped_consts)
} }
@ -794,7 +793,7 @@ impl<'me, 'tcx> PlaceholderReplacer<'me, 'tcx> {
universe_indices, universe_indices,
current_index: ty::INNERMOST, current_index: ty::INNERMOST,
}; };
value.super_fold_with(&mut replacer) value.fold_with(&mut replacer)
} }
} }

View File

@ -12,7 +12,7 @@ use rustc_data_structures::sso::SsoHashMap;
use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_infer::traits::Normalized; use rustc_infer::traits::Normalized;
use rustc_middle::mir; use rustc_middle::mir;
use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder}; use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::subst::Subst; use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor};
@ -205,7 +205,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
Reveal::UserFacing => ty.try_super_fold_with(self), Reveal::UserFacing => ty.try_super_fold_with(self),
Reveal::All => { Reveal::All => {
let substs = substs.try_super_fold_with(self)?; let substs = substs.try_fold_with(self)?;
let recursion_limit = self.tcx().recursion_limit(); let recursion_limit = self.tcx().recursion_limit();
if !recursion_limit.value_within_limit(self.anon_depth) { if !recursion_limit.value_within_limit(self.anon_depth) {
let obligation = Obligation::with_depth( let obligation = Obligation::with_depth(
@ -242,7 +242,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
// we don't need to replace them with placeholders (see branch below). // we don't need to replace them with placeholders (see branch below).
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
let data = data.try_super_fold_with(self)?; let data = data.try_fold_with(self)?;
let mut orig_values = OriginalQueryValues::default(); let mut orig_values = OriginalQueryValues::default();
// HACK(matthewjasper) `'static` is special-cased in selection, // HACK(matthewjasper) `'static` is special-cased in selection,
@ -281,7 +281,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
&mut self.universes, &mut self.universes,
data, data,
); );
let data = data.try_super_fold_with(self)?; let data = data.try_fold_with(self)?;
let mut orig_values = OriginalQueryValues::default(); let mut orig_values = OriginalQueryValues::default();
// HACK(matthewjasper) `'static` is special-cased in selection, // HACK(matthewjasper) `'static` is special-cased in selection,
@ -334,7 +334,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
&mut self, &mut self,
constant: mir::ConstantKind<'tcx>, constant: mir::ConstantKind<'tcx>,
) -> Result<mir::ConstantKind<'tcx>, Self::Error> { ) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
let constant_kind = match constant { Ok(match constant {
mir::ConstantKind::Ty(c) => { mir::ConstantKind::Ty(c) => {
let const_folded = c.try_fold_with(self)?; let const_folded = c.try_fold_with(self)?;
match const_folded.val() { match const_folded.val() {
@ -347,8 +347,6 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
} }
} }
mir::ConstantKind::Val(_, _) => constant.try_super_fold_with(self)?, mir::ConstantKind::Val(_, _) => constant.try_super_fold_with(self)?,
}; })
Ok(constant_kind)
} }
} }

View File

@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::lang_items::LangItem; use rustc_hir::lang_items::LangItem;
use rustc_middle::ty::query::Providers; use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt, TypeFoldable, TypeVisitor}; use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitor};
use rustc_span::Span; use rustc_span::Span;
use std::ops::ControlFlow; use std::ops::ControlFlow;

View File

@ -9,7 +9,7 @@
use rustc_middle::traits::ChalkRustInterner as RustInterner; use rustc_middle::traits::ChalkRustInterner as RustInterner;
use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
use rustc_middle::ty::{ use rustc_middle::ty::{
self, AssocItemContainer, AssocKind, EarlyBinder, Ty, TyCtxt, TypeFoldable, self, AssocItemContainer, AssocKind, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable,
}; };
use rustc_ast::ast; use rustc_ast::ast;

View File

@ -33,9 +33,10 @@
use rustc_ast::ast; use rustc_ast::ast;
use rustc_middle::traits::{ChalkEnvironmentAndGoal, ChalkRustInterner as RustInterner}; use rustc_middle::traits::{ChalkEnvironmentAndGoal, ChalkRustInterner as RustInterner};
use rustc_middle::ty::fold::TypeFolder;
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
use rustc_middle::ty::{self, Binder, Region, Ty, TyCtxt, TypeFoldable, TypeVisitor}; use rustc_middle::ty::{
self, Binder, Region, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitor,
};
use rustc_span::def_id::DefId; use rustc_span::def_id::DefId;
use chalk_ir::{FnSig, ForeignDefId}; use chalk_ir::{FnSig, ForeignDefId};

View File

@ -3,7 +3,9 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::traits::CodegenObligationError; use rustc_middle::traits::CodegenObligationError;
use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, Binder, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitor}; use rustc_middle::ty::{
self, Binder, Instance, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitor,
};
use rustc_span::{sym, DUMMY_SP}; use rustc_span::{sym, DUMMY_SP};
use rustc_trait_selection::traits; use rustc_trait_selection::traits;
use traits::{translate_substs, Reveal}; use traits::{translate_substs, Reveal};

View File

@ -17,11 +17,10 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt}; use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
use rustc_infer::traits::Obligation; use rustc_infer::traits::Obligation;
use rustc_middle::hir::nested_filter; use rustc_middle::hir::nested_filter;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES}; use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::util::{Discr, IntTypeExt}; use rustc_middle::ty::util::{Discr, IntTypeExt};
use rustc_middle::ty::{self, ParamEnv, ToPredicate, Ty, TyCtxt}; use rustc_middle::ty::{self, ParamEnv, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable};
use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS}; use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS};
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use rustc_span::{self, Span}; use rustc_span::{self, Span};

View File

@ -9,8 +9,9 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
use rustc_middle::ty::adjustment::{ use rustc_middle::ty::adjustment::{
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability,
}; };
use rustc_middle::ty::fold::TypeFolder; use rustc_middle::ty::{
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitor}; self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitor,
};
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
use rustc_span::symbol::{sym, Ident}; use rustc_span::symbol::{sym, Ident};
use rustc_span::Span; use rustc_span::Span;

View File

@ -22,7 +22,7 @@ use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
use rustc_middle::ty::trait_def::TraitSpecializationKind; use rustc_middle::ty::trait_def::TraitSpecializationKind;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, AdtKind, EarlyBinder, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, self, AdtKind, EarlyBinder, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable,
TypeVisitor, TypeSuperFoldable, TypeVisitor,
}; };
use rustc_session::parse::feature_err; use rustc_session::parse::feature_err;
use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::symbol::{sym, Ident, Symbol};

View File

@ -14,7 +14,7 @@ use rustc_infer::infer::InferCtxt;
use rustc_middle::hir::place::Place as HirPlace; use rustc_middle::hir::place::Place as HirPlace;
use rustc_middle::mir::FakeReadCause; use rustc_middle::mir::FakeReadCause;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder}; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::{self, ClosureSizeProfileData, Ty, TyCtxt}; use rustc_middle::ty::{self, ClosureSizeProfileData, Ty, TyCtxt};
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use rustc_span::Span; use rustc_span::Span;

View File

@ -9,7 +9,9 @@ use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::util::IgnoreRegions; use rustc_middle::ty::util::IgnoreRegions;
use rustc_middle::ty::{self, ImplPolarity, Ty, TyCtxt, TypeFoldable, TypeVisitor}; use rustc_middle::ty::{
self, ImplPolarity, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitor,
};
use rustc_session::lint; use rustc_session::lint;
use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::Span; use rustc_span::Span;
@ -439,7 +441,7 @@ fn fast_reject_auto_impl<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, self_ty:
} }
match t.kind() { match t.kind() {
ty::Adt(def, substs) if def.is_phantom_data() => substs.super_visit_with(self), ty::Adt(def, substs) if def.is_phantom_data() => substs.visit_with(self),
ty::Adt(def, substs) => { ty::Adt(def, substs) => {
// @lcnr: This is the only place where cycles can happen. We avoid this // @lcnr: This is the only place where cycles can happen. We avoid this
// by only visiting each `DefId` once. // by only visiting each `DefId` once.

View File

@ -8,7 +8,7 @@ use rustc_hir::{HirId, Node};
use rustc_middle::hir::nested_filter; use rustc_middle::hir::nested_filter;
use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable, TypeFolder}; use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_span::symbol::Ident; use rustc_span::symbol::Ident;
use rustc_span::{Span, DUMMY_SP}; use rustc_span::{Span, DUMMY_SP};

View File

@ -1,5 +1,5 @@
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_middle::ty::fold::{TypeFoldable, TypeVisitor}; use rustc_middle::ty::fold::{TypeFoldable, TypeSuperFoldable, TypeVisitor};
use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
use std::ops::ControlFlow; use std::ops::ControlFlow;

View File

@ -1,7 +1,7 @@
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::lang_items::LangItem; use rustc_hir::lang_items::LangItem;
use rustc_middle::ty::{self, Region, RegionVid, TypeFoldable}; use rustc_middle::ty::{self, Region, RegionVid, TypeFoldable, TypeSuperFoldable};
use rustc_trait_selection::traits::auto_trait::{self, AutoTraitResult}; use rustc_trait_selection::traits::auto_trait::{self, AutoTraitResult};
use std::fmt::Debug; use std::fmt::Debug;

View File

@ -7,7 +7,7 @@ use rustc_hir::def::{DefKind, Res};
use rustc_hir::{Expr, ExprKind, PatKind, Stmt, StmtKind}; use rustc_hir::{Expr, ExprKind, PatKind, Stmt, StmtKind};
use rustc_lint::{LateContext, LintContext}; use rustc_lint::{LateContext, LintContext};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, Ty, TypeFoldable, TypeVisitor}; use rustc_middle::ty::{self, Ty, TypeFoldable, TypeSuperFoldable, TypeVisitor};
use super::LET_UNIT_VALUE; use super::LET_UNIT_VALUE;