Auto merge of #101858 - oli-obk:lift_derive, r=lcnr

derive various impls instead of hand-rolling them

r? `@lcnr`

This may not have been what you asked for in 964b97e845 (r84051418) but I got carried away while following the compiler team meeting today.
This commit is contained in:
bors 2022-09-15 18:14:29 +00:00
commit df34db9b03
17 changed files with 90 additions and 887 deletions

View File

@ -44,6 +44,15 @@ pub struct Canonical<'tcx, V> {
pub type CanonicalVarInfos<'tcx> = &'tcx List<CanonicalVarInfo<'tcx>>; pub type CanonicalVarInfos<'tcx> = &'tcx List<CanonicalVarInfo<'tcx>>;
impl<'tcx> ty::TypeFoldable<'tcx> for CanonicalVarInfos<'tcx> {
fn try_fold_with<F: ty::FallibleTypeFolder<'tcx>>(
self,
folder: &mut F,
) -> Result<Self, F::Error> {
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_canonical_var_infos(v))
}
}
/// A set of values corresponding to the canonical variables from some /// A set of values corresponding to the canonical variables from some
/// `Canonical`. You can give these values to /// `Canonical`. You can give these values to
/// `canonical_value.substitute` to substitute them into the canonical /// `canonical_value.substitute` to substitute them into the canonical
@ -90,6 +99,7 @@ impl<'tcx> Default for OriginalQueryValues<'tcx> {
/// a copy of the canonical value in some other inference context, /// a copy of the canonical value in some other inference context,
/// with fresh inference variables replacing the canonical values. /// with fresh inference variables replacing the canonical values.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable, HashStable)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable, HashStable)]
#[derive(TypeFoldable, TypeVisitable)]
pub struct CanonicalVarInfo<'tcx> { pub struct CanonicalVarInfo<'tcx> {
pub kind: CanonicalVarKind<'tcx>, pub kind: CanonicalVarKind<'tcx>,
} }
@ -115,6 +125,7 @@ impl<'tcx> CanonicalVarInfo<'tcx> {
/// in the type-theory sense of the term -- i.e., a "meta" type system /// in the type-theory sense of the term -- i.e., a "meta" type system
/// that analyzes type-like values. /// that analyzes type-like values.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable, HashStable)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable, HashStable)]
#[derive(TypeFoldable, TypeVisitable)]
pub enum CanonicalVarKind<'tcx> { pub enum CanonicalVarKind<'tcx> {
/// Some kind of type inference variable. /// Some kind of type inference variable.
Ty(CanonicalTyVarKind), Ty(CanonicalTyVarKind),
@ -299,14 +310,7 @@ pub type QueryOutlivesConstraint<'tcx> = (
TrivialTypeTraversalAndLiftImpls! { TrivialTypeTraversalAndLiftImpls! {
for <'tcx> { for <'tcx> {
crate::infer::canonical::Certainty, crate::infer::canonical::Certainty,
crate::infer::canonical::CanonicalVarInfo<'tcx>, crate::infer::canonical::CanonicalTyVarKind,
crate::infer::canonical::CanonicalVarKind<'tcx>,
}
}
TrivialTypeTraversalImpls! {
for <'tcx> {
crate::infer::canonical::CanonicalVarInfos<'tcx>,
} }
} }

View File

@ -137,7 +137,7 @@ pub use self::pointer::{Pointer, PointerArithmetic, Provenance};
/// - A constant /// - A constant
/// - A static /// - A static
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, TyEncodable, TyDecodable)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, TyEncodable, TyDecodable)]
#[derive(HashStable, Lift)] #[derive(HashStable, Lift, TypeFoldable, TypeVisitable)]
pub struct GlobalId<'tcx> { pub struct GlobalId<'tcx> {
/// For a constant or static, the `Instance` of the item itself. /// For a constant or static, the `Instance` of the item itself.
/// For a promoted global, the `Instance` of the function they belong to. /// For a promoted global, the `Instance` of the function they belong to.

View File

@ -8,7 +8,7 @@ use rustc_apfloat::{
use rustc_macros::HashStable; use rustc_macros::HashStable;
use rustc_target::abi::{HasDataLayout, Size}; use rustc_target::abi::{HasDataLayout, Size};
use crate::ty::{Lift, ParamEnv, ScalarInt, Ty, TyCtxt}; use crate::ty::{ParamEnv, ScalarInt, Ty, TyCtxt};
use super::{ use super::{
AllocId, AllocRange, ConstAllocation, InterpResult, Pointer, PointerArithmetic, Provenance, AllocId, AllocRange, ConstAllocation, InterpResult, Pointer, PointerArithmetic, Provenance,
@ -27,7 +27,7 @@ pub struct ConstAlloc<'tcx> {
/// Represents a constant value in Rust. `Scalar` and `Slice` are optimizations for /// Represents a constant value in Rust. `Scalar` and `Slice` are optimizations for
/// array length computations, enum discriminants and the pattern matching logic. /// array length computations, enum discriminants and the pattern matching logic.
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)] #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)]
#[derive(HashStable)] #[derive(HashStable, Lift)]
pub enum ConstValue<'tcx> { pub enum ConstValue<'tcx> {
/// Used only for types with `layout::abi::Scalar` ABI. /// Used only for types with `layout::abi::Scalar` ABI.
/// ///
@ -53,22 +53,6 @@ pub enum ConstValue<'tcx> {
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(ConstValue<'_>, 32); static_assert_size!(ConstValue<'_>, 32);
impl<'a, 'tcx> Lift<'tcx> for ConstValue<'a> {
type Lifted = ConstValue<'tcx>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ConstValue<'tcx>> {
Some(match self {
ConstValue::Scalar(s) => ConstValue::Scalar(s),
ConstValue::ZeroSized => ConstValue::ZeroSized,
ConstValue::Slice { data, start, end } => {
ConstValue::Slice { data: tcx.lift(data)?, start, end }
}
ConstValue::ByRef { alloc, offset } => {
ConstValue::ByRef { alloc: tcx.lift(alloc)?, offset }
}
})
}
}
impl<'tcx> ConstValue<'tcx> { impl<'tcx> ConstValue<'tcx> {
#[inline] #[inline]
pub fn try_to_scalar(&self) -> Option<Scalar<AllocId>> { pub fn try_to_scalar(&self) -> Option<Scalar<AllocId>> {

View File

@ -2028,6 +2028,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
/// particular, one must be wary of `NaN`! /// particular, one must be wary of `NaN`!
#[derive(Clone, Copy, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)] #[derive(Clone, Copy, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]
#[derive(TypeFoldable, TypeVisitable)]
pub struct Constant<'tcx> { pub struct Constant<'tcx> {
pub span: Span, pub span: Span,
@ -2551,8 +2552,6 @@ impl UserTypeProjection {
} }
} }
TrivialTypeTraversalAndLiftImpls! { ProjectionKind, }
impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection { impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection {
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> {
Ok(UserTypeProjection { Ok(UserTypeProjection {

View File

@ -488,7 +488,7 @@ pub struct CopyNonOverlapping<'tcx> {
/// must also be `cleanup`. This is a part of the type system and checked statically, so it is /// must also be `cleanup`. This is a part of the type system and checked statically, so it is
/// still an error to have such an edge in the CFG even if it's known that it won't be taken at /// still an error to have such an edge in the CFG even if it's known that it won't be taken at
/// runtime. /// runtime.
#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)] #[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, TypeFoldable, TypeVisitable)]
pub enum TerminatorKind<'tcx> { pub enum TerminatorKind<'tcx> {
/// Block has one successor; we continue execution there. /// Block has one successor; we continue execution there.
Goto { target: BasicBlock }, Goto { target: BasicBlock },
@ -741,7 +741,7 @@ pub enum TerminatorKind<'tcx> {
} }
/// Information about an assertion failure. /// Information about an assertion failure.
#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)] #[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, TypeFoldable, TypeVisitable)]
pub enum AssertKind<O> { pub enum AssertKind<O> {
BoundsCheck { len: O, index: O }, BoundsCheck { len: O, index: O },
Overflow(BinOp, O, O), Overflow(BinOp, O, O),
@ -863,7 +863,7 @@ pub type AssertMessage<'tcx> = AssertKind<Operand<'tcx>>;
/// ///
/// Rust currently requires that every place obey those two rules. This is checked by MIRI and taken /// Rust currently requires that every place obey those two rules. This is checked by MIRI and taken
/// advantage of by codegen (via `gep inbounds`). That is possibly subject to change. /// advantage of by codegen (via `gep inbounds`). That is possibly subject to change.
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, HashStable)] #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, HashStable, TypeFoldable, TypeVisitable)]
pub struct Place<'tcx> { pub struct Place<'tcx> {
pub local: Local, pub local: Local,
@ -872,7 +872,7 @@ pub struct Place<'tcx> {
} }
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(TyEncodable, TyDecodable, HashStable)] #[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
pub enum ProjectionElem<V, T> { pub enum ProjectionElem<V, T> {
Deref, Deref,
Field(Field, T), Field(Field, T),
@ -955,7 +955,7 @@ pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
/// **Needs clarifiation:** Is loading a place that has its variant index set well-formed? Miri /// **Needs clarifiation:** Is loading a place that has its variant index set well-formed? Miri
/// currently implements it, but it seems like this may be something to check against in the /// currently implements it, but it seems like this may be something to check against in the
/// validator. /// validator.
#[derive(Clone, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)] #[derive(Clone, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
pub enum Operand<'tcx> { pub enum Operand<'tcx> {
/// Creates a value by loading the given place. /// Creates a value by loading the given place.
/// ///
@ -986,7 +986,7 @@ pub enum Operand<'tcx> {
/// Computing any rvalue begins by evaluating the places and operands in some order (**Needs /// Computing any rvalue begins by evaluating the places and operands in some order (**Needs
/// clarification**: Which order?). These are then used to produce a "value" - the same kind of /// clarification**: Which order?). These are then used to produce a "value" - the same kind of
/// value that an [`Operand`] produces. /// value that an [`Operand`] produces.
#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)] #[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, TypeFoldable, TypeVisitable)]
pub enum Rvalue<'tcx> { pub enum Rvalue<'tcx> {
/// Yields the operand unchanged /// Yields the operand unchanged
Use(Operand<'tcx>), Use(Operand<'tcx>),
@ -1146,6 +1146,7 @@ pub enum CastKind {
} }
#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)] #[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
#[derive(TypeFoldable, TypeVisitable)]
pub enum AggregateKind<'tcx> { pub enum AggregateKind<'tcx> {
/// The type is of the element /// The type is of the element
Array(Ty<'tcx>), Array(Ty<'tcx>),

View File

@ -102,7 +102,7 @@ impl<'a> Iterator for SwitchTargetsIter<'a> {
impl<'a> ExactSizeIterator for SwitchTargetsIter<'a> {} impl<'a> ExactSizeIterator for SwitchTargetsIter<'a> {}
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)] #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
pub struct Terminator<'tcx> { pub struct Terminator<'tcx> {
pub source_info: SourceInfo, pub source_info: SourceInfo,
pub kind: TerminatorKind<'tcx>, pub kind: TerminatorKind<'tcx>,

View File

@ -1,8 +1,9 @@
//! `TypeFoldable` implementations for MIR types //! `TypeFoldable` implementations for MIR types
use rustc_ast::InlineAsmTemplatePiece;
use super::*; use super::*;
use crate::ty; use crate::ty;
use rustc_data_structures::functor::IdFunctor;
TrivialTypeTraversalAndLiftImpls! { TrivialTypeTraversalAndLiftImpls! {
BlockTailInfo, BlockTailInfo,
@ -13,96 +14,27 @@ TrivialTypeTraversalAndLiftImpls! {
SourceScope, SourceScope,
SourceScopeLocalData, SourceScopeLocalData,
UserTypeAnnotationIndex, UserTypeAnnotationIndex,
BorrowKind,
CastKind,
BinOp,
NullOp,
UnOp,
hir::Movability,
BasicBlock,
SwitchTargets,
GeneratorKind,
GeneratorSavedLocal,
} }
impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { impl<'tcx> TypeFoldable<'tcx> for &'tcx [InlineAsmTemplatePiece] {
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> {
use crate::mir::TerminatorKind::*;
let kind = match self.kind {
Goto { target } => Goto { target },
SwitchInt { discr, switch_ty, targets } => SwitchInt {
discr: discr.try_fold_with(folder)?,
switch_ty: switch_ty.try_fold_with(folder)?,
targets,
},
Drop { place, target, unwind } => {
Drop { place: place.try_fold_with(folder)?, target, unwind }
}
DropAndReplace { place, value, target, unwind } => DropAndReplace {
place: place.try_fold_with(folder)?,
value: value.try_fold_with(folder)?,
target,
unwind,
},
Yield { value, resume, resume_arg, drop } => Yield {
value: value.try_fold_with(folder)?,
resume,
resume_arg: resume_arg.try_fold_with(folder)?,
drop,
},
Call { func, args, destination, target, cleanup, from_hir_call, fn_span } => Call {
func: func.try_fold_with(folder)?,
args: args.try_fold_with(folder)?,
destination: destination.try_fold_with(folder)?,
target,
cleanup,
from_hir_call,
fn_span,
},
Assert { cond, expected, msg, target, cleanup } => {
use AssertKind::*;
let msg = match msg {
BoundsCheck { len, index } => BoundsCheck {
len: len.try_fold_with(folder)?,
index: index.try_fold_with(folder)?,
},
Overflow(op, l, r) => {
Overflow(op, l.try_fold_with(folder)?, r.try_fold_with(folder)?)
}
OverflowNeg(op) => OverflowNeg(op.try_fold_with(folder)?),
DivisionByZero(op) => DivisionByZero(op.try_fold_with(folder)?),
RemainderByZero(op) => RemainderByZero(op.try_fold_with(folder)?),
ResumedAfterReturn(_) | ResumedAfterPanic(_) => msg,
};
Assert { cond: cond.try_fold_with(folder)?, expected, msg, target, cleanup }
}
GeneratorDrop => GeneratorDrop,
Resume => Resume,
Abort => Abort,
Return => Return,
Unreachable => Unreachable,
FalseEdge { real_target, imaginary_target } => {
FalseEdge { real_target, imaginary_target }
}
FalseUnwind { real_target, unwind } => FalseUnwind { real_target, unwind },
InlineAsm { template, operands, options, line_spans, destination, cleanup } => {
InlineAsm {
template,
operands: operands.try_fold_with(folder)?,
options,
line_spans,
destination,
cleanup,
}
}
};
Ok(Terminator { source_info: self.source_info, kind })
}
}
impl<'tcx> TypeFoldable<'tcx> for GeneratorKind {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
Ok(self) Ok(self)
} }
} }
impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> { impl<'tcx> TypeFoldable<'tcx> for &'tcx [Span] {
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> {
Ok(Place { Ok(self)
local: self.local.try_fold_with(folder)?,
projection: self.projection.try_fold_with(folder)?,
})
} }
} }
@ -112,114 +44,12 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
} }
} }
impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
use crate::mir::Rvalue::*;
Ok(match self {
Use(op) => Use(op.try_fold_with(folder)?),
Repeat(op, len) => Repeat(op.try_fold_with(folder)?, len.try_fold_with(folder)?),
ThreadLocalRef(did) => ThreadLocalRef(did.try_fold_with(folder)?),
Ref(region, bk, place) => {
Ref(region.try_fold_with(folder)?, bk, place.try_fold_with(folder)?)
}
CopyForDeref(place) => CopyForDeref(place.try_fold_with(folder)?),
AddressOf(mutability, place) => AddressOf(mutability, place.try_fold_with(folder)?),
Len(place) => Len(place.try_fold_with(folder)?),
Cast(kind, op, ty) => Cast(kind, op.try_fold_with(folder)?, ty.try_fold_with(folder)?),
BinaryOp(op, box (rhs, lhs)) => {
BinaryOp(op, Box::new((rhs.try_fold_with(folder)?, lhs.try_fold_with(folder)?)))
}
CheckedBinaryOp(op, box (rhs, lhs)) => CheckedBinaryOp(
op,
Box::new((rhs.try_fold_with(folder)?, lhs.try_fold_with(folder)?)),
),
UnaryOp(op, val) => UnaryOp(op, val.try_fold_with(folder)?),
Discriminant(place) => Discriminant(place.try_fold_with(folder)?),
NullaryOp(op, ty) => NullaryOp(op, ty.try_fold_with(folder)?),
Aggregate(kind, fields) => {
let kind = kind.try_map_id(|kind| {
Ok(match kind {
AggregateKind::Array(ty) => AggregateKind::Array(ty.try_fold_with(folder)?),
AggregateKind::Tuple => AggregateKind::Tuple,
AggregateKind::Adt(def, v, substs, user_ty, n) => AggregateKind::Adt(
def,
v,
substs.try_fold_with(folder)?,
user_ty.try_fold_with(folder)?,
n,
),
AggregateKind::Closure(id, substs) => {
AggregateKind::Closure(id, substs.try_fold_with(folder)?)
}
AggregateKind::Generator(id, substs, movablity) => {
AggregateKind::Generator(id, substs.try_fold_with(folder)?, movablity)
}
})
})?;
Aggregate(kind, fields.try_fold_with(folder)?)
}
ShallowInitBox(op, ty) => {
ShallowInitBox(op.try_fold_with(folder)?, ty.try_fold_with(folder)?)
}
})
}
}
impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
Ok(match self {
Operand::Copy(place) => Operand::Copy(place.try_fold_with(folder)?),
Operand::Move(place) => Operand::Move(place.try_fold_with(folder)?),
Operand::Constant(c) => Operand::Constant(c.try_fold_with(folder)?),
})
}
}
impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
use crate::mir::ProjectionElem::*;
Ok(match self {
Deref => Deref,
Field(f, ty) => Field(f, ty.try_fold_with(folder)?),
Index(v) => Index(v.try_fold_with(folder)?),
Downcast(symbol, variantidx) => Downcast(symbol, variantidx),
ConstantIndex { offset, min_length, from_end } => {
ConstantIndex { offset, min_length, from_end }
}
Subslice { from, to, from_end } => Subslice { from, to, from_end },
})
}
}
impl<'tcx> TypeFoldable<'tcx> for Field {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
Ok(self)
}
}
impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
Ok(self)
}
}
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_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)
} }
} }
impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
Ok(Constant {
span: self.span,
user_ty: self.user_ty.try_fold_with(folder)?,
literal: self.literal.try_fold_with(folder)?,
})
}
}
impl<'tcx> TypeFoldable<'tcx> for ConstantKind<'tcx> { impl<'tcx> TypeFoldable<'tcx> for ConstantKind<'tcx> {
#[inline(always)] #[inline(always)]
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> {

View File

@ -1,165 +1,6 @@
//! `TypeVisitable` implementations for MIR types //! `TypeVisitable` implementations for MIR types
use super::*; use super::*;
use crate::ty;
impl<'tcx> TypeVisitable<'tcx> for Terminator<'tcx> {
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
use crate::mir::TerminatorKind::*;
match self.kind {
SwitchInt { ref discr, switch_ty, .. } => {
discr.visit_with(visitor)?;
switch_ty.visit_with(visitor)
}
Drop { ref place, .. } => place.visit_with(visitor),
DropAndReplace { ref place, ref value, .. } => {
place.visit_with(visitor)?;
value.visit_with(visitor)
}
Yield { ref value, .. } => value.visit_with(visitor),
Call { ref func, ref args, ref destination, .. } => {
destination.visit_with(visitor)?;
func.visit_with(visitor)?;
args.visit_with(visitor)
}
Assert { ref cond, ref msg, .. } => {
cond.visit_with(visitor)?;
use AssertKind::*;
match msg {
BoundsCheck { ref len, ref index } => {
len.visit_with(visitor)?;
index.visit_with(visitor)
}
Overflow(_, l, r) => {
l.visit_with(visitor)?;
r.visit_with(visitor)
}
OverflowNeg(op) | DivisionByZero(op) | RemainderByZero(op) => {
op.visit_with(visitor)
}
ResumedAfterReturn(_) | ResumedAfterPanic(_) => ControlFlow::CONTINUE,
}
}
InlineAsm { ref operands, .. } => operands.visit_with(visitor),
Goto { .. }
| Resume
| Abort
| Return
| GeneratorDrop
| Unreachable
| FalseEdge { .. }
| FalseUnwind { .. } => ControlFlow::CONTINUE,
}
}
}
impl<'tcx> TypeVisitable<'tcx> for GeneratorKind {
fn visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
ControlFlow::CONTINUE
}
}
impl<'tcx> TypeVisitable<'tcx> for Place<'tcx> {
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.local.visit_with(visitor)?;
self.projection.visit_with(visitor)
}
}
impl<'tcx> TypeVisitable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.iter().try_for_each(|t| t.visit_with(visitor))
}
}
impl<'tcx> TypeVisitable<'tcx> for Rvalue<'tcx> {
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
use crate::mir::Rvalue::*;
match *self {
Use(ref op) => op.visit_with(visitor),
CopyForDeref(ref place) => {
let op = &Operand::Copy(*place);
op.visit_with(visitor)
}
Repeat(ref op, _) => op.visit_with(visitor),
ThreadLocalRef(did) => did.visit_with(visitor),
Ref(region, _, ref place) => {
region.visit_with(visitor)?;
place.visit_with(visitor)
}
AddressOf(_, ref place) => place.visit_with(visitor),
Len(ref place) => place.visit_with(visitor),
Cast(_, ref op, ty) => {
op.visit_with(visitor)?;
ty.visit_with(visitor)
}
BinaryOp(_, box (ref rhs, ref lhs)) | CheckedBinaryOp(_, box (ref rhs, ref lhs)) => {
rhs.visit_with(visitor)?;
lhs.visit_with(visitor)
}
UnaryOp(_, ref val) => val.visit_with(visitor),
Discriminant(ref place) => place.visit_with(visitor),
NullaryOp(_, ty) => ty.visit_with(visitor),
Aggregate(ref kind, ref fields) => {
match **kind {
AggregateKind::Array(ty) => {
ty.visit_with(visitor)?;
}
AggregateKind::Tuple => {}
AggregateKind::Adt(_, _, substs, user_ty, _) => {
substs.visit_with(visitor)?;
user_ty.visit_with(visitor)?;
}
AggregateKind::Closure(_, substs) => {
substs.visit_with(visitor)?;
}
AggregateKind::Generator(_, substs, _) => {
substs.visit_with(visitor)?;
}
}
fields.visit_with(visitor)
}
ShallowInitBox(ref op, ty) => {
op.visit_with(visitor)?;
ty.visit_with(visitor)
}
}
}
}
impl<'tcx> TypeVisitable<'tcx> for Operand<'tcx> {
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
match *self {
Operand::Copy(ref place) | Operand::Move(ref place) => place.visit_with(visitor),
Operand::Constant(ref c) => c.visit_with(visitor),
}
}
}
impl<'tcx> TypeVisitable<'tcx> for PlaceElem<'tcx> {
fn visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> ControlFlow<Vs::BreakTy> {
use crate::mir::ProjectionElem::*;
match self {
Field(_, ty) => ty.visit_with(visitor),
Index(v) => v.visit_with(visitor),
_ => ControlFlow::CONTINUE,
}
}
}
impl<'tcx> TypeVisitable<'tcx> for Field {
fn visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
ControlFlow::CONTINUE
}
}
impl<'tcx> TypeVisitable<'tcx> for GeneratorSavedLocal {
fn visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
ControlFlow::CONTINUE
}
}
impl<'tcx, R: Idx, C: Idx> TypeVisitable<'tcx> for BitMatrix<R, C> { impl<'tcx, R: Idx, C: Idx> TypeVisitable<'tcx> for BitMatrix<R, C> {
fn visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> { fn visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
@ -167,13 +8,6 @@ impl<'tcx, R: Idx, C: Idx> TypeVisitable<'tcx> for BitMatrix<R, C> {
} }
} }
impl<'tcx> TypeVisitable<'tcx> for Constant<'tcx> {
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.literal.visit_with(visitor)?;
self.user_ty.visit_with(visitor)
}
}
impl<'tcx> TypeVisitable<'tcx> for ConstantKind<'tcx> { impl<'tcx> TypeVisitable<'tcx> for ConstantKind<'tcx> {
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_mir_const(*self) visitor.visit_mir_const(*self)

View File

@ -77,7 +77,7 @@ pub enum PointerCast {
/// At some point, of course, `Box` should move out of the compiler, in which /// At some point, of course, `Box` should move out of the compiler, in which
/// case this is analogous to transforming a struct. E.g., `Box<[i32; 4]>` -> /// case this is analogous to transforming a struct. E.g., `Box<[i32; 4]>` ->
/// `Box<[i32]>` is an `Adjust::Unsize` with the target `Box<[i32]>`. /// `Box<[i32]>` is an `Adjust::Unsize` with the target `Box<[i32]>`.
#[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] #[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct Adjustment<'tcx> { pub struct Adjustment<'tcx> {
pub kind: Adjust<'tcx>, pub kind: Adjust<'tcx>,
pub target: Ty<'tcx>, pub target: Ty<'tcx>,
@ -89,7 +89,7 @@ impl<'tcx> Adjustment<'tcx> {
} }
} }
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable, Lift)]
pub enum Adjust<'tcx> { pub enum Adjust<'tcx> {
/// Go from ! to any type. /// Go from ! to any type.
NeverToAny, NeverToAny,
@ -108,7 +108,7 @@ pub enum Adjust<'tcx> {
/// The target type is `U` in both cases, with the region and mutability /// The target type is `U` in both cases, with the region and mutability
/// being those shared by both the receiver and the returned reference. /// being those shared by both the receiver and the returned reference.
#[derive(Copy, Clone, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)] #[derive(Copy, Clone, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)]
#[derive(TypeFoldable, TypeVisitable)] #[derive(TypeFoldable, TypeVisitable, Lift)]
pub struct OverloadedDeref<'tcx> { pub struct OverloadedDeref<'tcx> {
pub region: ty::Region<'tcx>, pub region: ty::Region<'tcx>,
pub mutbl: hir::Mutability, pub mutbl: hir::Mutability,
@ -167,7 +167,7 @@ impl From<AutoBorrowMutability> for hir::Mutability {
} }
#[derive(Copy, Clone, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)] #[derive(Copy, Clone, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)]
#[derive(TypeFoldable, TypeVisitable)] #[derive(TypeFoldable, TypeVisitable, Lift)]
pub enum AutoBorrow<'tcx> { pub enum AutoBorrow<'tcx> {
/// Converts from T to &T. /// Converts from T to &T.
Ref(ty::Region<'tcx>, AutoBorrowMutability), Ref(ty::Region<'tcx>, AutoBorrowMutability),

View File

@ -50,7 +50,7 @@ impl<'tcx, P: Default> Unevaluated<'tcx, P> {
/// Represents a constant in Rust. /// Represents a constant in Rust.
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)] #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)]
#[derive(Hash, HashStable)] #[derive(Hash, HashStable, TypeFoldable, TypeVisitable)]
pub enum ConstKind<'tcx> { pub enum ConstKind<'tcx> {
/// A const generic parameter. /// A const generic parameter.
Param(ty::ParamConst), Param(ty::ParamConst),

View File

@ -1820,7 +1820,9 @@ nop_list_lift! {bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariable
// This is the impl for `&'a InternalSubsts<'a>`. // This is the impl for `&'a InternalSubsts<'a>`.
nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>} nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>}
CloneLiftImpls! { for<'tcx> { Constness, traits::WellFormedLoc, } } CloneLiftImpls! { for<'tcx> {
Constness, traits::WellFormedLoc, ImplPolarity, crate::mir::ReturnConstraint,
} }
pub mod tls { pub mod tls {
use super::{ptr_eq, GlobalCtxt, TyCtxt}; use super::{ptr_eq, GlobalCtxt, TyCtxt};

View File

@ -14,7 +14,7 @@ use rustc_target::spec::abi;
use std::borrow::Cow; use std::borrow::Cow;
use std::fmt; use std::fmt;
#[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable, TypeVisitable)] #[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable, TypeVisitable, Lift)]
pub struct ExpectedFound<T> { pub struct ExpectedFound<T> {
pub expected: T, pub expected: T,
pub found: T, pub found: T,
@ -31,7 +31,7 @@ impl<T> ExpectedFound<T> {
} }
// Data structures used in type unification // Data structures used in type unification
#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)] #[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift)]
#[rustc_pass_by_value] #[rustc_pass_by_value]
pub enum TypeError<'tcx> { pub enum TypeError<'tcx> {
Mismatch, Mismatch,

View File

@ -20,14 +20,14 @@ use std::fmt;
/// simply couples a potentially generic `InstanceDef` with some substs, and codegen and const eval /// simply couples a potentially generic `InstanceDef` with some substs, and codegen and const eval
/// will do all required substitution as they run. /// will do all required substitution as they run.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
#[derive(HashStable, Lift)] #[derive(HashStable, Lift, TypeFoldable, TypeVisitable)]
pub struct Instance<'tcx> { pub struct Instance<'tcx> {
pub def: InstanceDef<'tcx>, pub def: InstanceDef<'tcx>,
pub substs: SubstsRef<'tcx>, pub substs: SubstsRef<'tcx>,
} }
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] #[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable, Lift)]
pub enum InstanceDef<'tcx> { pub enum InstanceDef<'tcx> {
/// A user-defined callable item. /// A user-defined callable item.
/// ///

View File

@ -636,7 +636,7 @@ impl rustc_errors::IntoDiagnosticArg for Predicate<'_> {
} }
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub enum PredicateKind<'tcx> { pub enum PredicateKind<'tcx> {
/// Corresponds to `where Foo: Bar<A, B, C>`. `Foo` here would be /// Corresponds to `where Foo: Bar<A, B, C>`. `Foo` here would be
/// the `Self` type of the trait reference and `A`, `B`, and `C` /// the `Self` type of the trait reference and `A`, `B`, and `C`
@ -808,7 +808,7 @@ impl<'tcx> Predicate<'tcx> {
} }
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct TraitPredicate<'tcx> { pub struct TraitPredicate<'tcx> {
pub trait_ref: TraitRef<'tcx>, pub trait_ref: TraitRef<'tcx>,
@ -888,7 +888,7 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
} }
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct OutlivesPredicate<A, B>(pub A, pub B); // `A: B` pub struct OutlivesPredicate<A, B>(pub A, pub B); // `A: B`
pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>; pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>;
pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>; pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>;
@ -899,7 +899,7 @@ pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<'tcx, TypeOutlivesPredicat
/// whether the `a` type is the type that we should label as "expected" when /// whether the `a` type is the type that we should label as "expected" when
/// presenting user diagnostics. /// presenting user diagnostics.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct SubtypePredicate<'tcx> { pub struct SubtypePredicate<'tcx> {
pub a_is_expected: bool, pub a_is_expected: bool,
pub a: Ty<'tcx>, pub a: Ty<'tcx>,
@ -909,7 +909,7 @@ pub type PolySubtypePredicate<'tcx> = ty::Binder<'tcx, SubtypePredicate<'tcx>>;
/// Encodes that we have to coerce *from* the `a` type to the `b` type. /// Encodes that we have to coerce *from* the `a` type to the `b` type.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct CoercePredicate<'tcx> { pub struct CoercePredicate<'tcx> {
pub a: Ty<'tcx>, pub a: Ty<'tcx>,
pub b: Ty<'tcx>, pub b: Ty<'tcx>,
@ -1058,7 +1058,7 @@ impl<'tcx> TermKind<'tcx> {
/// Form #2 eventually yields one of these `ProjectionPredicate` /// Form #2 eventually yields one of these `ProjectionPredicate`
/// instances to normalize the LHS. /// instances to normalize the LHS.
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct ProjectionPredicate<'tcx> { pub struct ProjectionPredicate<'tcx> {
pub projection_ty: ProjectionTy<'tcx>, pub projection_ty: ProjectionTy<'tcx>,
pub term: Term<'tcx>, pub term: Term<'tcx>,
@ -1526,7 +1526,7 @@ impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> {
Ok(ParamEnv::new( Ok(ParamEnv::new(
self.caller_bounds().try_fold_with(folder)?, self.caller_bounds().try_fold_with(folder)?,
self.reveal().try_fold_with(folder)?, self.reveal().try_fold_with(folder)?,
self.constness().try_fold_with(folder)?, self.constness(),
)) ))
} }
} }
@ -1534,8 +1534,7 @@ impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> {
impl<'tcx> TypeVisitable<'tcx> for ParamEnv<'tcx> { impl<'tcx> TypeVisitable<'tcx> for ParamEnv<'tcx> {
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> {
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)
} }
} }
@ -1692,7 +1691,7 @@ impl<'tcx> PolyTraitRef<'tcx> {
} }
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)]
#[derive(HashStable)] #[derive(HashStable, Lift)]
pub struct ParamEnvAnd<'tcx, T> { pub struct ParamEnvAnd<'tcx, T> {
pub param_env: ParamEnv<'tcx>, pub param_env: ParamEnv<'tcx>,
pub value: T, pub value: T,

View File

@ -9,7 +9,6 @@ use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
use crate::ty::{self, InferConst, Lift, Term, TermKind, Ty, TyCtxt}; use crate::ty::{self, InferConst, Lift, Term, TermKind, Ty, TyCtxt};
use rustc_data_structures::functor::IdFunctor; use rustc_data_structures::functor::IdFunctor;
use rustc_hir as hir;
use rustc_hir::def::Namespace; use rustc_hir::def::Namespace;
use rustc_index::vec::{Idx, IndexVec}; use rustc_index::vec::{Idx, IndexVec};
@ -238,12 +237,24 @@ TrivialTypeTraversalAndLiftImpls! {
crate::ty::Variance, crate::ty::Variance,
::rustc_span::Span, ::rustc_span::Span,
::rustc_errors::ErrorGuaranteed, ::rustc_errors::ErrorGuaranteed,
Field,
interpret::Scalar,
rustc_target::abi::Size,
ty::DelaySpanBugEmitted,
rustc_type_ir::DebruijnIndex,
ty::BoundVar,
ty::Placeholder<ty::BoundVar>,
}
TrivialTypeTraversalAndLiftImpls! {
for<'tcx> {
ty::ValTree<'tcx>,
}
} }
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Lift implementations // 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) { impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) {
type Lifted = (A::Lifted, B::Lifted); type Lifted = (A::Lifted, B::Lifted);
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
@ -261,10 +272,7 @@ impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>, C: Lift<'tcx>> Lift<'tcx> for (A, B, C)
impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> { impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> {
type Lifted = Option<T::Lifted>; type Lifted = Option<T::Lifted>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
match self { tcx.lift(self?).map(Some)
Some(x) => tcx.lift(x).map(Some),
None => Some(None),
}
} }
} }
@ -281,21 +289,21 @@ impl<'tcx, T: Lift<'tcx>, E: Lift<'tcx>> Lift<'tcx> for Result<T, E> {
impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Box<T> { impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Box<T> {
type Lifted = Box<T::Lifted>; type Lifted = Box<T::Lifted>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
tcx.lift(*self).map(Box::new) Some(Box::new(tcx.lift(*self)?))
} }
} }
impl<'tcx, T: Lift<'tcx> + Clone> Lift<'tcx> for Rc<T> { impl<'tcx, T: Lift<'tcx> + Clone> Lift<'tcx> for Rc<T> {
type Lifted = Rc<T::Lifted>; type Lifted = Rc<T::Lifted>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
tcx.lift(self.as_ref().clone()).map(Rc::new) Some(Rc::new(tcx.lift(self.as_ref().clone())?))
} }
} }
impl<'tcx, T: Lift<'tcx> + Clone> Lift<'tcx> for Arc<T> { impl<'tcx, T: Lift<'tcx> + Clone> Lift<'tcx> for Arc<T> {
type Lifted = Arc<T::Lifted>; type Lifted = Arc<T::Lifted>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
tcx.lift(self.as_ref().clone()).map(Arc::new) Some(Arc::new(tcx.lift(self.as_ref().clone())?))
} }
} }
impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Vec<T> { impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Vec<T> {
@ -312,35 +320,6 @@ impl<'tcx, I: Idx, T: Lift<'tcx>> Lift<'tcx> for IndexVec<I, T> {
} }
} }
impl<'a, 'tcx> Lift<'tcx> for ty::TraitRef<'a> {
type Lifted = ty::TraitRef<'tcx>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
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<Self::Lifted> {
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<Self::Lifted> {
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> { impl<'a, 'tcx> Lift<'tcx> for Term<'a> {
type Lifted = ty::Term<'tcx>; type Lifted = ty::Term<'tcx>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
@ -353,121 +332,6 @@ impl<'a, 'tcx> Lift<'tcx> for Term<'a> {
) )
} }
} }
impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
type Lifted = ty::TraitPredicate<'tcx>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::TraitPredicate<'tcx>> {
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<ty::SubtypePredicate<'tcx>> {
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<ty::CoercePredicate<'tcx>> {
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<A, B> {
type Lifted = ty::OutlivesPredicate<A::Lifted, B::Lifted>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
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<ty::ProjectionTy<'tcx>> {
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<ty::ProjectionPredicate<'tcx>> {
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<Self::Lifted> {
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<Self::Lifted> {
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
<T as Lift<'tcx>>::Lifted: TypeVisitable<'tcx>,
{
type Lifted = ty::Binder<'tcx, T::Lifted>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
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> { impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
type Lifted = ty::ParamEnv<'tcx>; type Lifted = ty::ParamEnv<'tcx>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
@ -476,192 +340,6 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
} }
} }
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<Self::Lifted> {
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<Self::Lifted> {
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<Self::Lifted> {
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<Self::Lifted> {
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<Self::Lifted> {
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<Self::Lifted> {
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<Self::Lifted> {
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<Self::Lifted> {
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<Self::Lifted> {
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<T> {
type Lifted = ty::error::ExpectedFound<T::Lifted>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
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<Self::Lifted> {
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<Self::Lifted> {
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)?))
}
}
}
}
impl<'tcx> Lift<'tcx> for Field {
type Lifted = Field;
fn lift_to_tcx(self, _tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
Some(self)
}
}
impl<'tcx> Lift<'tcx> for crate::mir::ReturnConstraint {
type Lifted = crate::mir::ReturnConstraint;
fn lift_to_tcx(self, _tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
Some(self)
}
}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// TypeFoldable implementations. // TypeFoldable implementations.
@ -924,88 +602,12 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Binder<'tcx, ty::Existentia
} }
} }
impl<'tcx> TypeVisitable<'tcx>
for &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>
{
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
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_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> {
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projs(v)) ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projs(v))
} }
} }
impl<'tcx> TypeVisitable<'tcx> for &'tcx ty::List<ProjectionKind> {
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.iter().try_for_each(|t| t.visit_with(visitor))
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
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<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
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<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
Ok(Self { instance: self.instance.try_fold_with(folder)?, promoted: self.promoted })
}
}
impl<'tcx> TypeVisitable<'tcx> for interpret::GlobalId<'tcx> {
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
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> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
folder.try_fold_ty(self) folder.try_fold_ty(self)
@ -1181,12 +783,6 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
} }
} }
impl<'tcx> TypeVisitable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
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_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> {
self.try_map_id(|x| x.try_fold_with(folder)) self.try_map_id(|x| x.try_fold_with(folder))
@ -1233,34 +829,6 @@ impl<'tcx> TypeSuperVisitable<'tcx> for ty::Const<'tcx> {
} }
} }
impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
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<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
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> { impl<'tcx> TypeFoldable<'tcx> for InferConst<'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> {
Ok(self) Ok(self)
@ -1315,15 +883,3 @@ impl<'tcx> TypeVisitable<'tcx> for ty::Unevaluated<'tcx, ()> {
self.expand().visit_with(visitor) self.expand().visit_with(visitor)
} }
} }
impl<'tcx> TypeFoldable<'tcx> for hir::Constness {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
Ok(self)
}
}
impl<'tcx> TypeVisitable<'tcx> for hir::Constness {
fn visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
ControlFlow::CONTINUE
}
}

View File

@ -202,7 +202,7 @@ static_assert_size!(TyKind<'_>, 32);
/// * `GR`: The "return type", which is the type of value returned upon /// * `GR`: The "return type", which is the type of value returned upon
/// completion of the generator. /// completion of the generator.
/// * `GW`: The "generator witness". /// * `GW`: The "generator witness".
#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)] #[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift)]
pub struct ClosureSubsts<'tcx> { pub struct ClosureSubsts<'tcx> {
/// Lifetime and type parameters from the enclosing function, /// Lifetime and type parameters from the enclosing function,
/// concatenated with a tuple containing the types of the upvars. /// concatenated with a tuple containing the types of the upvars.
@ -333,7 +333,7 @@ impl<'tcx> ClosureSubsts<'tcx> {
} }
/// Similar to `ClosureSubsts`; see the above documentation for more. /// Similar to `ClosureSubsts`; see the above documentation for more.
#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)] #[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift)]
pub struct GeneratorSubsts<'tcx> { pub struct GeneratorSubsts<'tcx> {
pub substs: SubstsRef<'tcx>, pub substs: SubstsRef<'tcx>,
} }
@ -660,7 +660,7 @@ impl<'tcx> InlineConstSubsts<'tcx> {
} }
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, TyEncodable, TyDecodable)] #[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub enum ExistentialPredicate<'tcx> { pub enum ExistentialPredicate<'tcx> {
/// E.g., `Iterator`. /// E.g., `Iterator`.
Trait(ExistentialTraitRef<'tcx>), Trait(ExistentialTraitRef<'tcx>),
@ -789,7 +789,7 @@ impl<'tcx> List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>> {
/// Trait references also appear in object types like `Foo<U>`, but in /// Trait references also appear in object types like `Foo<U>`, but in
/// that case the `Self` parameter is absent from the substitutions. /// that case the `Self` parameter is absent from the substitutions.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct TraitRef<'tcx> { pub struct TraitRef<'tcx> {
pub def_id: DefId, pub def_id: DefId,
pub substs: SubstsRef<'tcx>, pub substs: SubstsRef<'tcx>,
@ -867,7 +867,7 @@ impl rustc_errors::IntoDiagnosticArg for PolyTraitRef<'_> {
/// The substitutions don't include the erased `Self`, only trait /// The substitutions don't include the erased `Self`, only trait
/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above). /// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above).
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct ExistentialTraitRef<'tcx> { pub struct ExistentialTraitRef<'tcx> {
pub def_id: DefId, pub def_id: DefId,
pub substs: SubstsRef<'tcx>, pub substs: SubstsRef<'tcx>,
@ -1023,7 +1023,7 @@ impl BoundVariableKind {
/// ///
/// `Decodable` and `Encodable` are implemented for `Binder<T>` using the `impl_binder_encode_decode!` macro. /// `Decodable` and `Encodable` are implemented for `Binder<T>` using the `impl_binder_encode_decode!` macro.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[derive(HashStable)] #[derive(HashStable, Lift)]
pub struct Binder<'tcx, T>(T, &'tcx List<BoundVariableKind>); pub struct Binder<'tcx, T>(T, &'tcx List<BoundVariableKind>);
impl<'tcx, T> Binder<'tcx, T> impl<'tcx, T> Binder<'tcx, T>
@ -1185,7 +1185,7 @@ impl<'tcx, T> Binder<'tcx, Option<T>> {
/// Represents the projection of an associated type. In explicit UFCS /// Represents the projection of an associated type. In explicit UFCS
/// form this would be written `<T as Trait<..>>::N`. /// form this would be written `<T as Trait<..>>::N`.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct ProjectionTy<'tcx> { pub struct ProjectionTy<'tcx> {
/// The parameters of the associated item. /// The parameters of the associated item.
pub substs: SubstsRef<'tcx>, pub substs: SubstsRef<'tcx>,
@ -1237,7 +1237,7 @@ impl<'tcx> ProjectionTy<'tcx> {
} }
} }
#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)] #[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift)]
pub struct GenSig<'tcx> { pub struct GenSig<'tcx> {
pub resume_ty: Ty<'tcx>, pub resume_ty: Ty<'tcx>,
pub yield_ty: Ty<'tcx>, pub yield_ty: Ty<'tcx>,
@ -1253,7 +1253,7 @@ pub type PolyGenSig<'tcx> = Binder<'tcx, GenSig<'tcx>>;
/// - `output`: is the return type. /// - `output`: is the return type.
/// - `c_variadic`: indicates whether this is a C-variadic function. /// - `c_variadic`: indicates whether this is a C-variadic function.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct FnSig<'tcx> { pub struct FnSig<'tcx> {
pub inputs_and_output: &'tcx List<Ty<'tcx>>, pub inputs_and_output: &'tcx List<Ty<'tcx>>,
pub c_variadic: bool, pub c_variadic: bool,
@ -1435,7 +1435,7 @@ impl From<BoundVar> for BoundTy {
/// A `ProjectionPredicate` for an `ExistentialTraitRef`. /// A `ProjectionPredicate` for an `ExistentialTraitRef`.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct ExistentialProjection<'tcx> { pub struct ExistentialProjection<'tcx> {
pub item_def_id: DefId, pub item_def_id: DefId,
pub substs: SubstsRef<'tcx>, pub substs: SubstsRef<'tcx>,

View File

@ -459,12 +459,6 @@ impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> {
} }
} }
impl<'tcx> TypeVisitable<'tcx> for SubstsRef<'tcx> {
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
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_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> {
// This code is fairly hot, though not as hot as `SubstsRef`. // This code is fairly hot, though not as hot as `SubstsRef`.
@ -497,7 +491,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
} }
} }
impl<'tcx> TypeVisitable<'tcx> for &'tcx ty::List<Ty<'tcx>> { impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for &'tcx ty::List<T> {
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> {
self.iter().try_for_each(|t| t.visit_with(visitor)) self.iter().try_for_each(|t| t.visit_with(visitor))
} }