From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_middle/src/ty/structural_impls.rs | 1304 ++++++++++++++++++++++ 1 file changed, 1304 insertions(+) create mode 100644 compiler/rustc_middle/src/ty/structural_impls.rs (limited to 'compiler/rustc_middle/src/ty/structural_impls.rs') diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs new file mode 100644 index 000000000..7660a2f3a --- /dev/null +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -0,0 +1,1304 @@ +//! This module contains implements of the `Lift` and `TypeFoldable` +//! traits for various types in the Rust compiler. Most are written by +//! hand, though we've recently added some macros and proc-macros to help with the tedium. + +use crate::mir::interpret; +use crate::mir::ProjectionKind; +use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}; +use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer}; +use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; +use crate::ty::{self, InferConst, Lift, Term, Ty, TyCtxt}; +use rustc_data_structures::functor::IdFunctor; +use rustc_hir as hir; +use rustc_hir::def::Namespace; +use rustc_index::vec::{Idx, IndexVec}; + +use std::fmt; +use std::mem::ManuallyDrop; +use std::ops::ControlFlow; +use std::rc::Rc; +use std::sync::Arc; + +impl fmt::Debug for ty::TraitDef { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + ty::tls::with(|tcx| { + with_no_trimmed_paths!({ + f.write_str( + &FmtPrinter::new(tcx, Namespace::TypeNS) + .print_def_path(self.def_id, &[])? + .into_buffer(), + ) + }) + }) + } +} + +impl<'tcx> fmt::Debug for ty::AdtDef<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + ty::tls::with(|tcx| { + with_no_trimmed_paths!({ + f.write_str( + &FmtPrinter::new(tcx, Namespace::TypeNS) + .print_def_path(self.did(), &[])? + .into_buffer(), + ) + }) + }) + } +} + +impl fmt::Debug for ty::UpvarId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let name = ty::tls::with(|tcx| tcx.hir().name(self.var_path.hir_id)); + write!(f, "UpvarId({:?};`{}`;{:?})", self.var_path.hir_id, name, self.closure_expr_id) + } +} + +impl<'tcx> fmt::Debug for ty::ExistentialTraitRef<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + with_no_trimmed_paths!(fmt::Display::fmt(self, f)) + } +} + +impl<'tcx> fmt::Debug for ty::adjustment::Adjustment<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?} -> {}", self.kind, self.target) + } +} + +impl fmt::Debug for ty::BoundRegionKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + ty::BrAnon(n) => write!(f, "BrAnon({:?})", n), + ty::BrNamed(did, name) => { + if did.is_crate_root() { + write!(f, "BrNamed({})", name) + } else { + write!(f, "BrNamed({:?}, {})", did, name) + } + } + ty::BrEnv => write!(f, "BrEnv"), + } + } +} + +impl fmt::Debug for ty::FreeRegion { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "ReFree({:?}, {:?})", self.scope, self.bound_region) + } +} + +impl<'tcx> fmt::Debug for ty::FnSig<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "({:?}; c_variadic: {})->{:?}", self.inputs(), self.c_variadic, self.output()) + } +} + +impl<'tcx> fmt::Debug for ty::ConstVid<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "_#{}c", self.index) + } +} + +impl fmt::Debug for ty::RegionVid { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "'_#{}r", self.index()) + } +} + +impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + with_no_trimmed_paths!(fmt::Display::fmt(self, f)) + } +} + +impl<'tcx> fmt::Debug for Ty<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + with_no_trimmed_paths!(fmt::Display::fmt(self, f)) + } +} + +impl fmt::Debug for ty::ParamTy { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}/#{}", self.name, self.index) + } +} + +impl fmt::Debug for ty::ParamConst { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}/#{}", self.name, self.index) + } +} + +impl<'tcx> fmt::Debug for ty::TraitPredicate<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if let ty::BoundConstness::ConstIfConst = self.constness { + write!(f, "~const ")?; + } + write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity) + } +} + +impl<'tcx> fmt::Debug for ty::ProjectionPredicate<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.term) + } +} + +impl<'tcx> fmt::Debug for ty::Predicate<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self.kind()) + } +} + +impl<'tcx> fmt::Debug for ty::PredicateKind<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + ty::PredicateKind::Trait(ref a) => a.fmt(f), + ty::PredicateKind::Subtype(ref pair) => pair.fmt(f), + ty::PredicateKind::Coerce(ref pair) => pair.fmt(f), + ty::PredicateKind::RegionOutlives(ref pair) => pair.fmt(f), + ty::PredicateKind::TypeOutlives(ref pair) => pair.fmt(f), + ty::PredicateKind::Projection(ref pair) => pair.fmt(f), + ty::PredicateKind::WellFormed(data) => write!(f, "WellFormed({:?})", data), + ty::PredicateKind::ObjectSafe(trait_def_id) => { + write!(f, "ObjectSafe({:?})", trait_def_id) + } + ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => { + write!(f, "ClosureKind({:?}, {:?}, {:?})", closure_def_id, closure_substs, kind) + } + ty::PredicateKind::ConstEvaluatable(uv) => { + write!(f, "ConstEvaluatable({:?}, {:?})", uv.def, uv.substs) + } + ty::PredicateKind::ConstEquate(c1, c2) => write!(f, "ConstEquate({:?}, {:?})", c1, c2), + ty::PredicateKind::TypeWellFormedFromEnv(ty) => { + write!(f, "TypeWellFormedFromEnv({:?})", ty) + } + } + } +} + +/////////////////////////////////////////////////////////////////////////// +// Atomic structs +// +// For things that don't carry any arena-allocated data (and are +// copy...), just add them to this list. + +TrivialTypeTraversalAndLiftImpls! { + (), + bool, + usize, + ::rustc_target::abi::VariantIdx, + u32, + u64, + String, + crate::middle::region::Scope, + crate::ty::FloatTy, + ::rustc_ast::InlineAsmOptions, + ::rustc_ast::InlineAsmTemplatePiece, + ::rustc_ast::NodeId, + ::rustc_span::symbol::Symbol, + ::rustc_hir::def::Res, + ::rustc_hir::def_id::DefId, + ::rustc_hir::def_id::LocalDefId, + ::rustc_hir::HirId, + ::rustc_hir::MatchSource, + ::rustc_hir::Mutability, + ::rustc_hir::Unsafety, + ::rustc_target::asm::InlineAsmRegOrRegClass, + ::rustc_target::spec::abi::Abi, + crate::mir::coverage::ExpressionOperandId, + crate::mir::coverage::CounterValueReference, + crate::mir::coverage::InjectedExpressionId, + crate::mir::coverage::InjectedExpressionIndex, + crate::mir::coverage::MappedExpressionIndex, + crate::mir::Local, + crate::mir::Promoted, + crate::traits::Reveal, + crate::ty::adjustment::AutoBorrowMutability, + crate::ty::AdtKind, + crate::ty::BoundConstness, + // Including `BoundRegionKind` is a *bit* dubious, but direct + // references to bound region appear in `ty::Error`, and aren't + // really meant to be folded. In general, we can only fold a fully + // general `Region`. + crate::ty::BoundRegionKind, + crate::ty::AssocItem, + crate::ty::AssocKind, + crate::ty::Placeholder, + crate::ty::ClosureKind, + crate::ty::FreeRegion, + crate::ty::InferTy, + crate::ty::IntVarValue, + crate::ty::ParamConst, + crate::ty::ParamTy, + crate::ty::adjustment::PointerCast, + crate::ty::RegionVid, + crate::ty::UniverseIndex, + crate::ty::Variance, + ::rustc_span::Span, + ::rustc_errors::ErrorGuaranteed, +} + +/////////////////////////////////////////////////////////////////////////// +// Lift implementations + +// FIXME(eddyb) replace all the uses of `Option::map` with `?`. +impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) { + type Lifted = (A::Lifted, B::Lifted); + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + Some((tcx.lift(self.0)?, tcx.lift(self.1)?)) + } +} + +impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>, C: Lift<'tcx>> Lift<'tcx> for (A, B, C) { + type Lifted = (A::Lifted, B::Lifted, C::Lifted); + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + Some((tcx.lift(self.0)?, tcx.lift(self.1)?, tcx.lift(self.2)?)) + } +} + +impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option { + type Lifted = Option; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + match self { + Some(x) => tcx.lift(x).map(Some), + None => Some(None), + } + } +} + +impl<'tcx, T: Lift<'tcx>, E: Lift<'tcx>> Lift<'tcx> for Result { + type Lifted = Result; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + match self { + Ok(x) => tcx.lift(x).map(Ok), + Err(e) => tcx.lift(e).map(Err), + } + } +} + +impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Box { + type Lifted = Box; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + tcx.lift(*self).map(Box::new) + } +} + +impl<'tcx, T: Lift<'tcx> + Clone> Lift<'tcx> for Rc { + type Lifted = Rc; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + tcx.lift(self.as_ref().clone()).map(Rc::new) + } +} + +impl<'tcx, T: Lift<'tcx> + Clone> Lift<'tcx> for Arc { + type Lifted = Arc; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + tcx.lift(self.as_ref().clone()).map(Arc::new) + } +} +impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Vec { + type Lifted = Vec; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + self.into_iter().map(|v| tcx.lift(v)).collect() + } +} + +impl<'tcx, I: Idx, T: Lift<'tcx>> Lift<'tcx> for IndexVec { + type Lifted = IndexVec; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + self.into_iter().map(|e| tcx.lift(e)).collect() + } +} + +impl<'a, 'tcx> Lift<'tcx> for ty::TraitRef<'a> { + type Lifted = ty::TraitRef<'tcx>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + tcx.lift(self.substs).map(|substs| ty::TraitRef { def_id: self.def_id, substs }) + } +} + +impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialTraitRef<'a> { + type Lifted = ty::ExistentialTraitRef<'tcx>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + tcx.lift(self.substs).map(|substs| ty::ExistentialTraitRef { def_id: self.def_id, substs }) + } +} + +impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialPredicate<'a> { + type Lifted = ty::ExistentialPredicate<'tcx>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + match self { + ty::ExistentialPredicate::Trait(x) => tcx.lift(x).map(ty::ExistentialPredicate::Trait), + ty::ExistentialPredicate::Projection(x) => { + tcx.lift(x).map(ty::ExistentialPredicate::Projection) + } + ty::ExistentialPredicate::AutoTrait(def_id) => { + Some(ty::ExistentialPredicate::AutoTrait(def_id)) + } + } + } +} + +impl<'a, 'tcx> Lift<'tcx> for Term<'a> { + type Lifted = ty::Term<'tcx>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + Some(match self { + Term::Ty(ty) => Term::Ty(tcx.lift(ty)?), + Term::Const(c) => Term::Const(tcx.lift(c)?), + }) + } +} + +impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> { + type Lifted = ty::TraitPredicate<'tcx>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option> { + tcx.lift(self.trait_ref).map(|trait_ref| ty::TraitPredicate { + trait_ref, + constness: self.constness, + polarity: self.polarity, + }) + } +} + +impl<'a, 'tcx> Lift<'tcx> for ty::SubtypePredicate<'a> { + type Lifted = ty::SubtypePredicate<'tcx>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option> { + tcx.lift((self.a, self.b)).map(|(a, b)| ty::SubtypePredicate { + a_is_expected: self.a_is_expected, + a, + b, + }) + } +} + +impl<'a, 'tcx> Lift<'tcx> for ty::CoercePredicate<'a> { + type Lifted = ty::CoercePredicate<'tcx>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option> { + tcx.lift((self.a, self.b)).map(|(a, b)| ty::CoercePredicate { a, b }) + } +} + +impl<'tcx, A: Copy + Lift<'tcx>, B: Copy + Lift<'tcx>> Lift<'tcx> for ty::OutlivesPredicate { + type Lifted = ty::OutlivesPredicate; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + tcx.lift((self.0, self.1)).map(|(a, b)| ty::OutlivesPredicate(a, b)) + } +} + +impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionTy<'a> { + type Lifted = ty::ProjectionTy<'tcx>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option> { + tcx.lift(self.substs) + .map(|substs| ty::ProjectionTy { item_def_id: self.item_def_id, substs }) + } +} + +impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionPredicate<'a> { + type Lifted = ty::ProjectionPredicate<'tcx>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option> { + tcx.lift((self.projection_ty, self.term)) + .map(|(projection_ty, term)| ty::ProjectionPredicate { projection_ty, term }) + } +} + +impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialProjection<'a> { + type Lifted = ty::ExistentialProjection<'tcx>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + tcx.lift(self.substs).map(|substs| ty::ExistentialProjection { + substs, + term: tcx.lift(self.term).expect("type must lift when substs do"), + item_def_id: self.item_def_id, + }) + } +} + +impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> { + type Lifted = ty::PredicateKind<'tcx>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + match self { + ty::PredicateKind::Trait(data) => tcx.lift(data).map(ty::PredicateKind::Trait), + ty::PredicateKind::Subtype(data) => tcx.lift(data).map(ty::PredicateKind::Subtype), + ty::PredicateKind::Coerce(data) => tcx.lift(data).map(ty::PredicateKind::Coerce), + ty::PredicateKind::RegionOutlives(data) => { + tcx.lift(data).map(ty::PredicateKind::RegionOutlives) + } + ty::PredicateKind::TypeOutlives(data) => { + tcx.lift(data).map(ty::PredicateKind::TypeOutlives) + } + ty::PredicateKind::Projection(data) => { + tcx.lift(data).map(ty::PredicateKind::Projection) + } + ty::PredicateKind::WellFormed(ty) => tcx.lift(ty).map(ty::PredicateKind::WellFormed), + ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => { + tcx.lift(closure_substs).map(|closure_substs| { + ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) + }) + } + ty::PredicateKind::ObjectSafe(trait_def_id) => { + Some(ty::PredicateKind::ObjectSafe(trait_def_id)) + } + ty::PredicateKind::ConstEvaluatable(uv) => { + tcx.lift(uv).map(|uv| ty::PredicateKind::ConstEvaluatable(uv)) + } + ty::PredicateKind::ConstEquate(c1, c2) => { + tcx.lift((c1, c2)).map(|(c1, c2)| ty::PredicateKind::ConstEquate(c1, c2)) + } + ty::PredicateKind::TypeWellFormedFromEnv(ty) => { + tcx.lift(ty).map(ty::PredicateKind::TypeWellFormedFromEnv) + } + } + } +} + +impl<'a, 'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<'a, T> +where + >::Lifted: TypeVisitable<'tcx>, +{ + type Lifted = ty::Binder<'tcx, T::Lifted>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + let bound_vars = tcx.lift(self.bound_vars()); + tcx.lift(self.skip_binder()) + .zip(bound_vars) + .map(|(value, vars)| ty::Binder::bind_with_vars(value, vars)) + } +} + +impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> { + type Lifted = ty::ParamEnv<'tcx>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + tcx.lift(self.caller_bounds()) + .map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal(), self.constness())) + } +} + +impl<'a, 'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::ParamEnvAnd<'a, T> { + type Lifted = ty::ParamEnvAnd<'tcx, T::Lifted>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + tcx.lift(self.param_env).and_then(|param_env| { + tcx.lift(self.value).map(|value| ty::ParamEnvAnd { param_env, value }) + }) + } +} + +impl<'a, 'tcx> Lift<'tcx> for ty::ClosureSubsts<'a> { + type Lifted = ty::ClosureSubsts<'tcx>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + tcx.lift(self.substs).map(|substs| ty::ClosureSubsts { substs }) + } +} + +impl<'a, 'tcx> Lift<'tcx> for ty::GeneratorSubsts<'a> { + type Lifted = ty::GeneratorSubsts<'tcx>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + tcx.lift(self.substs).map(|substs| ty::GeneratorSubsts { substs }) + } +} + +impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjustment<'a> { + type Lifted = ty::adjustment::Adjustment<'tcx>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + let ty::adjustment::Adjustment { kind, target } = self; + tcx.lift(kind).and_then(|kind| { + tcx.lift(target).map(|target| ty::adjustment::Adjustment { kind, target }) + }) + } +} + +impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjust<'a> { + type Lifted = ty::adjustment::Adjust<'tcx>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + match self { + ty::adjustment::Adjust::NeverToAny => Some(ty::adjustment::Adjust::NeverToAny), + ty::adjustment::Adjust::Pointer(ptr) => Some(ty::adjustment::Adjust::Pointer(ptr)), + ty::adjustment::Adjust::Deref(overloaded) => { + tcx.lift(overloaded).map(ty::adjustment::Adjust::Deref) + } + ty::adjustment::Adjust::Borrow(autoref) => { + tcx.lift(autoref).map(ty::adjustment::Adjust::Borrow) + } + } + } +} + +impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::OverloadedDeref<'a> { + type Lifted = ty::adjustment::OverloadedDeref<'tcx>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + tcx.lift(self.region).map(|region| ty::adjustment::OverloadedDeref { + region, + mutbl: self.mutbl, + span: self.span, + }) + } +} + +impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> { + type Lifted = ty::adjustment::AutoBorrow<'tcx>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + match self { + ty::adjustment::AutoBorrow::Ref(r, m) => { + tcx.lift(r).map(|r| ty::adjustment::AutoBorrow::Ref(r, m)) + } + ty::adjustment::AutoBorrow::RawPtr(m) => Some(ty::adjustment::AutoBorrow::RawPtr(m)), + } + } +} + +impl<'a, 'tcx> Lift<'tcx> for ty::GenSig<'a> { + type Lifted = ty::GenSig<'tcx>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + tcx.lift((self.resume_ty, self.yield_ty, self.return_ty)) + .map(|(resume_ty, yield_ty, return_ty)| ty::GenSig { resume_ty, yield_ty, return_ty }) + } +} + +impl<'a, 'tcx> Lift<'tcx> for ty::FnSig<'a> { + type Lifted = ty::FnSig<'tcx>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + tcx.lift(self.inputs_and_output).map(|x| ty::FnSig { + inputs_and_output: x, + c_variadic: self.c_variadic, + unsafety: self.unsafety, + abi: self.abi, + }) + } +} + +impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::error::ExpectedFound { + type Lifted = ty::error::ExpectedFound; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + let ty::error::ExpectedFound { expected, found } = self; + tcx.lift(expected).and_then(|expected| { + tcx.lift(found).map(|found| ty::error::ExpectedFound { expected, found }) + }) + } +} + +impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> { + type Lifted = ty::error::TypeError<'tcx>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + use crate::ty::error::TypeError::*; + + Some(match self { + Mismatch => Mismatch, + ConstnessMismatch(x) => ConstnessMismatch(x), + PolarityMismatch(x) => PolarityMismatch(x), + UnsafetyMismatch(x) => UnsafetyMismatch(x), + AbiMismatch(x) => AbiMismatch(x), + Mutability => Mutability, + ArgumentMutability(i) => ArgumentMutability(i), + TupleSize(x) => TupleSize(x), + FixedArraySize(x) => FixedArraySize(x), + ArgCount => ArgCount, + FieldMisMatch(x, y) => FieldMisMatch(x, y), + RegionsDoesNotOutlive(a, b) => { + return tcx.lift((a, b)).map(|(a, b)| RegionsDoesNotOutlive(a, b)); + } + RegionsInsufficientlyPolymorphic(a, b) => { + return tcx.lift(b).map(|b| RegionsInsufficientlyPolymorphic(a, b)); + } + RegionsOverlyPolymorphic(a, b) => { + return tcx.lift(b).map(|b| RegionsOverlyPolymorphic(a, b)); + } + RegionsPlaceholderMismatch => RegionsPlaceholderMismatch, + IntMismatch(x) => IntMismatch(x), + FloatMismatch(x) => FloatMismatch(x), + Traits(x) => Traits(x), + VariadicMismatch(x) => VariadicMismatch(x), + CyclicTy(t) => return tcx.lift(t).map(|t| CyclicTy(t)), + CyclicConst(ct) => return tcx.lift(ct).map(|ct| CyclicConst(ct)), + ProjectionMismatched(x) => ProjectionMismatched(x), + ArgumentSorts(x, i) => return tcx.lift(x).map(|x| ArgumentSorts(x, i)), + Sorts(x) => return tcx.lift(x).map(Sorts), + ExistentialMismatch(x) => return tcx.lift(x).map(ExistentialMismatch), + ConstMismatch(x) => return tcx.lift(x).map(ConstMismatch), + IntrinsicCast => IntrinsicCast, + TargetFeatureCast(x) => TargetFeatureCast(x), + ObjectUnsafeCoercion(x) => return tcx.lift(x).map(ObjectUnsafeCoercion), + }) + } +} + +impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> { + type Lifted = ty::InstanceDef<'tcx>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + match self { + ty::InstanceDef::Item(def_id) => Some(ty::InstanceDef::Item(def_id)), + ty::InstanceDef::VTableShim(def_id) => Some(ty::InstanceDef::VTableShim(def_id)), + ty::InstanceDef::ReifyShim(def_id) => Some(ty::InstanceDef::ReifyShim(def_id)), + ty::InstanceDef::Intrinsic(def_id) => Some(ty::InstanceDef::Intrinsic(def_id)), + ty::InstanceDef::FnPtrShim(def_id, ty) => { + Some(ty::InstanceDef::FnPtrShim(def_id, tcx.lift(ty)?)) + } + ty::InstanceDef::Virtual(def_id, n) => Some(ty::InstanceDef::Virtual(def_id, n)), + ty::InstanceDef::ClosureOnceShim { call_once, track_caller } => { + Some(ty::InstanceDef::ClosureOnceShim { call_once, track_caller }) + } + ty::InstanceDef::DropGlue(def_id, ty) => { + Some(ty::InstanceDef::DropGlue(def_id, tcx.lift(ty)?)) + } + ty::InstanceDef::CloneShim(def_id, ty) => { + Some(ty::InstanceDef::CloneShim(def_id, tcx.lift(ty)?)) + } + } + } +} + +/////////////////////////////////////////////////////////////////////////// +// TypeFoldable implementations. + +/// AdtDefs are basically the same as a DefId. +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 + } +} + +impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) { + fn try_fold_with>( + self, + folder: &mut F, + ) -> 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) + } +} + +impl<'tcx, A: TypeFoldable<'tcx>, B: TypeFoldable<'tcx>, C: TypeFoldable<'tcx>> TypeFoldable<'tcx> + for (A, B, C) +{ + fn try_fold_with>( + self, + folder: &mut F, + ) -> Result<(A, B, C), F::Error> { + Ok(( + self.0.try_fold_with(folder)?, + self.1.try_fold_with(folder)?, + 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)?; + self.2.visit_with(visitor) + } +} + +EnumTypeTraversalImpl! { + impl<'tcx, T> TypeFoldable<'tcx> for Option { + (Some)(a), + (None), + } where T: TypeFoldable<'tcx> +} +EnumTypeTraversalImpl! { + impl<'tcx, T> TypeVisitable<'tcx> for Option { + (Some)(a), + (None), + } where T: TypeVisitable<'tcx> +} + +EnumTypeTraversalImpl! { + impl<'tcx, T, E> TypeFoldable<'tcx> for Result { + (Ok)(a), + (Err)(a), + } where T: TypeFoldable<'tcx>, E: TypeFoldable<'tcx>, +} +EnumTypeTraversalImpl! { + impl<'tcx, T, E> TypeVisitable<'tcx> for Result { + (Ok)(a), + (Err)(a), + } where T: TypeVisitable<'tcx>, E: TypeVisitable<'tcx>, +} + +impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc { + fn try_fold_with>( + mut self, + folder: &mut F, + ) -> Result { + // We merely want to replace the contained `T`, if at all possible, + // so that we don't needlessly allocate a new `Rc` or indeed clone + // the contained type. + unsafe { + // First step is to ensure that we have a unique reference to + // the contained type, which `Rc::make_mut` will accomplish (by + // allocating a new `Rc` and cloning the `T` only if required). + // This is done *before* casting to `Rc>` so that + // panicking during `make_mut` does not leak the `T`. + Rc::make_mut(&mut self); + + // Casting to `Rc>` is safe because `ManuallyDrop` + // is `repr(transparent)`. + let ptr = Rc::into_raw(self).cast::>(); + let mut unique = Rc::from_raw(ptr); + + // Call to `Rc::make_mut` above guarantees that `unique` is the + // sole reference to the contained value, so we can avoid doing + // a checked `get_mut` here. + let slot = Rc::get_mut_unchecked(&mut unique); + + // Semantically move the contained type out from `unique`, fold + // it, then move the folded value back into `unique`. Should + // folding fail, `ManuallyDrop` ensures that the "moved-out" + // value is not re-dropped. + let owned = ManuallyDrop::take(slot); + let folded = owned.try_fold_with(folder)?; + *slot = ManuallyDrop::new(folded); + + // Cast back to `Rc`. + 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) + } +} + +impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc { + fn try_fold_with>( + mut self, + folder: &mut F, + ) -> Result { + // We merely want to replace the contained `T`, if at all possible, + // so that we don't needlessly allocate a new `Arc` or indeed clone + // the contained type. + unsafe { + // First step is to ensure that we have a unique reference to + // the contained type, which `Arc::make_mut` will accomplish (by + // allocating a new `Arc` and cloning the `T` only if required). + // This is done *before* casting to `Arc>` so that + // panicking during `make_mut` does not leak the `T`. + Arc::make_mut(&mut self); + + // Casting to `Arc>` is safe because `ManuallyDrop` + // is `repr(transparent)`. + let ptr = Arc::into_raw(self).cast::>(); + let mut unique = Arc::from_raw(ptr); + + // Call to `Arc::make_mut` above guarantees that `unique` is the + // sole reference to the contained value, so we can avoid doing + // a checked `get_mut` here. + let slot = Arc::get_mut_unchecked(&mut unique); + + // Semantically move the contained type out from `unique`, fold + // it, then move the folded value back into `unique`. Should + // folding fail, `ManuallyDrop` ensures that the "moved-out" + // value is not re-dropped. + let owned = ManuallyDrop::take(slot); + let folded = owned.try_fold_with(folder)?; + *slot = ManuallyDrop::new(folded); + + // Cast back to `Arc`. + 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) + } +} + +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) + } +} + +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)) + } +} + +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)) + } +} + +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) + } +} + +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) + } +} + +impl<'tcx, T: TypeFoldable<'tcx>> TypeSuperFoldable<'tcx> for ty::Binder<'tcx, T> { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> 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) + } +} + +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_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)) + } +} + +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)) + } +} + +impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { + fn try_fold_with>(self, folder: &mut F) -> Result { + use crate::ty::InstanceDef::*; + Ok(Self { + substs: self.substs.try_fold_with(folder)?, + def: match self.def { + Item(def) => Item(def.try_fold_with(folder)?), + VTableShim(did) => VTableShim(did.try_fold_with(folder)?), + ReifyShim(did) => ReifyShim(did.try_fold_with(folder)?), + Intrinsic(did) => Intrinsic(did.try_fold_with(folder)?), + FnPtrShim(did, ty) => { + FnPtrShim(did.try_fold_with(folder)?, ty.try_fold_with(folder)?) + } + Virtual(did, i) => Virtual(did.try_fold_with(folder)?, i), + ClosureOnceShim { call_once, track_caller } => { + ClosureOnceShim { call_once: call_once.try_fold_with(folder)?, track_caller } + } + DropGlue(did, ty) => { + DropGlue(did.try_fold_with(folder)?, ty.try_fold_with(folder)?) + } + CloneShim(did, ty) => { + CloneShim(did.try_fold_with(folder)?, ty.try_fold_with(folder)?) + } + }, + }) + } +} + +impl<'tcx> TypeVisitable<'tcx> for ty::instance::Instance<'tcx> { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + use crate::ty::InstanceDef::*; + self.substs.visit_with(visitor)?; + match self.def { + Item(def) => def.visit_with(visitor), + VTableShim(did) | ReifyShim(did) | Intrinsic(did) | Virtual(did, _) => { + did.visit_with(visitor) + } + FnPtrShim(did, ty) | CloneShim(did, ty) => { + did.visit_with(visitor)?; + ty.visit_with(visitor) + } + DropGlue(did, ty) => { + did.visit_with(visitor)?; + ty.visit_with(visitor) + } + ClosureOnceShim { call_once, track_caller: _ } => call_once.visit_with(visitor), + } + } +} + +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) + } +} + +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) + } +} + +impl<'tcx> TypeSuperFoldable<'tcx> for Ty<'tcx> { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { + let kind = match *self.kind() { + ty::RawPtr(tm) => ty::RawPtr(tm.try_fold_with(folder)?), + ty::Array(typ, sz) => ty::Array(typ.try_fold_with(folder)?, sz.try_fold_with(folder)?), + ty::Slice(typ) => ty::Slice(typ.try_fold_with(folder)?), + ty::Adt(tid, substs) => ty::Adt(tid, substs.try_fold_with(folder)?), + ty::Dynamic(trait_ty, region) => { + ty::Dynamic(trait_ty.try_fold_with(folder)?, region.try_fold_with(folder)?) + } + ty::Tuple(ts) => ty::Tuple(ts.try_fold_with(folder)?), + ty::FnDef(def_id, substs) => ty::FnDef(def_id, substs.try_fold_with(folder)?), + ty::FnPtr(f) => ty::FnPtr(f.try_fold_with(folder)?), + ty::Ref(r, ty, mutbl) => { + ty::Ref(r.try_fold_with(folder)?, ty.try_fold_with(folder)?, mutbl) + } + ty::Generator(did, substs, movability) => { + ty::Generator(did, substs.try_fold_with(folder)?, movability) + } + ty::GeneratorWitness(types) => ty::GeneratorWitness(types.try_fold_with(folder)?), + ty::Closure(did, substs) => ty::Closure(did, substs.try_fold_with(folder)?), + ty::Projection(data) => ty::Projection(data.try_fold_with(folder)?), + ty::Opaque(did, substs) => ty::Opaque(did, substs.try_fold_with(folder)?), + + ty::Bool + | ty::Char + | ty::Str + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Error(_) + | ty::Infer(_) + | ty::Param(..) + | ty::Bound(..) + | ty::Placeholder(..) + | ty::Never + | ty::Foreign(..) => return Ok(self), + }; + + 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), + ty::Array(typ, sz) => { + typ.visit_with(visitor)?; + sz.visit_with(visitor) + } + ty::Slice(typ) => typ.visit_with(visitor), + ty::Adt(_, substs) => substs.visit_with(visitor), + ty::Dynamic(ref trait_ty, ref reg) => { + trait_ty.visit_with(visitor)?; + reg.visit_with(visitor) + } + ty::Tuple(ts) => ts.visit_with(visitor), + ty::FnDef(_, substs) => substs.visit_with(visitor), + ty::FnPtr(ref f) => f.visit_with(visitor), + ty::Ref(r, ty, _) => { + r.visit_with(visitor)?; + ty.visit_with(visitor) + } + ty::Generator(_did, ref substs, _) => substs.visit_with(visitor), + ty::GeneratorWitness(ref types) => types.visit_with(visitor), + ty::Closure(_did, ref substs) => substs.visit_with(visitor), + ty::Projection(ref data) => data.visit_with(visitor), + ty::Opaque(_, ref substs) => substs.visit_with(visitor), + + ty::Bool + | ty::Char + | ty::Str + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Error(_) + | ty::Infer(_) + | ty::Bound(..) + | ty::Placeholder(..) + | ty::Param(..) + | ty::Never + | ty::Foreign(..) => ControlFlow::CONTINUE, + } + } +} + +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) + } +} + +impl<'tcx> TypeSuperFoldable<'tcx> for ty::Region<'tcx> { + fn try_super_fold_with>( + self, + _folder: &mut F, + ) -> Result { + Ok(self) + } +} + +impl<'tcx> TypeSuperVisitable<'tcx> for ty::Region<'tcx> { + fn super_visit_with>(&self, _visitor: &mut V) -> ControlFlow { + ControlFlow::CONTINUE + } +} + +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) + } + + #[inline] + fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool { + self.outer_exclusive_binder() > binder + } + + #[inline] + fn has_type_flags(&self, flags: ty::TypeFlags) -> bool { + self.flags().intersects(flags) + } +} + +impl<'tcx> TypeSuperFoldable<'tcx> for ty::Predicate<'tcx> { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { + 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) + } +} + +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)) + } +} + +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)) + } +} + +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) + } +} + +impl<'tcx> TypeSuperFoldable<'tcx> for ty::Const<'tcx> { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { + let ty = self.ty().try_fold_with(folder)?; + let kind = self.kind().try_fold_with(folder)?; + if ty != self.ty() || kind != self.kind() { + Ok(folder.tcx().mk_const(ty::ConstS { ty, kind })) + } else { + 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) + } +} + +impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { + fn try_fold_with>(self, folder: &mut F) -> Result { + Ok(match self { + 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::Unevaluated(uv) => ty::ConstKind::Unevaluated(uv.try_fold_with(folder)?), + ty::ConstKind::Value(_) + | ty::ConstKind::Bound(..) + | ty::ConstKind::Placeholder(..) + | ty::ConstKind::Error(_) => 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), + ty::ConstKind::Param(p) => p.visit_with(visitor), + ty::ConstKind::Unevaluated(uv) => uv.visit_with(visitor), + ty::ConstKind::Value(_) + | ty::ConstKind::Bound(..) + | ty::ConstKind::Placeholder(_) + | ty::ConstKind::Error(_) => ControlFlow::CONTINUE, + } + } +} + +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 + } +} + +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) + } +} + +impl<'tcx> TypeSuperFoldable<'tcx> for ty::Unevaluated<'tcx> { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { + Ok(ty::Unevaluated { + def: self.def, + substs: self.substs.try_fold_with(folder)?, + 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) + } +} + +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) + } +} + +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 + } +} -- cgit v1.2.3