diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index e467ca13c8e50..d3cf519b633c7 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -44,6 +44,15 @@ pub struct Canonical<'tcx, V> { pub type CanonicalVarInfos<'tcx> = &'tcx List>; +impl<'tcx> ty::TypeFoldable<'tcx> for CanonicalVarInfos<'tcx> { + fn try_fold_with>( + self, + folder: &mut F, + ) -> Result { + 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 /// `Canonical`. You can give these values to /// `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, /// with fresh inference variables replacing the canonical values. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable, HashStable)] +#[derive(TypeFoldable, TypeVisitable)] pub struct CanonicalVarInfo<'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 /// that analyzes type-like values. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable, HashStable)] +#[derive(TypeFoldable, TypeVisitable)] pub enum CanonicalVarKind<'tcx> { /// Some kind of type inference variable. Ty(CanonicalTyVarKind), @@ -299,14 +310,7 @@ pub type QueryOutlivesConstraint<'tcx> = ( TrivialTypeTraversalAndLiftImpls! { for <'tcx> { crate::infer::canonical::Certainty, - crate::infer::canonical::CanonicalVarInfo<'tcx>, - crate::infer::canonical::CanonicalVarKind<'tcx>, - } -} - -TrivialTypeTraversalImpls! { - for <'tcx> { - crate::infer::canonical::CanonicalVarInfos<'tcx>, + crate::infer::canonical::CanonicalTyVarKind, } } diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 0fc1217d57196..5e3dfcbcc4962 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -137,7 +137,7 @@ pub use self::pointer::{Pointer, PointerArithmetic, Provenance}; /// - A constant /// - A static #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, Lift)] +#[derive(HashStable, Lift, TypeFoldable, TypeVisitable)] pub struct GlobalId<'tcx> { /// For a constant or static, the `Instance` of the item itself. /// For a promoted global, the `Instance` of the function they belong to. diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index d4fad7f1ecdd9..ac5fddb7ad1eb 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -8,7 +8,7 @@ use rustc_apfloat::{ use rustc_macros::HashStable; use rustc_target::abi::{HasDataLayout, Size}; -use crate::ty::{Lift, ParamEnv, ScalarInt, Ty, TyCtxt}; +use crate::ty::{ParamEnv, ScalarInt, Ty, TyCtxt}; use super::{ 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 /// array length computations, enum discriminants and the pattern matching logic. #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)] -#[derive(HashStable)] +#[derive(HashStable, Lift)] pub enum ConstValue<'tcx> { /// 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"))] 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> { - 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> { #[inline] pub fn try_to_scalar(&self) -> Option> { diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 526bb5d728599..af00118fcbeba 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2028,6 +2028,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { /// particular, one must be wary of `NaN`! #[derive(Clone, Copy, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)] +#[derive(TypeFoldable, TypeVisitable)] pub struct Constant<'tcx> { pub span: Span, @@ -2551,8 +2552,6 @@ impl UserTypeProjection { } } -TrivialTypeTraversalAndLiftImpls! { ProjectionKind, } - impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection { fn try_fold_with>(self, folder: &mut F) -> Result { Ok(UserTypeProjection { diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index d2bb897b5b676..c7d0283aac9ba 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -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 /// still an error to have such an edge in the CFG even if it's known that it won't be taken at /// runtime. -#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)] +#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, TypeFoldable, TypeVisitable)] pub enum TerminatorKind<'tcx> { /// Block has one successor; we continue execution there. Goto { target: BasicBlock }, @@ -741,7 +741,7 @@ pub enum TerminatorKind<'tcx> { } /// Information about an assertion failure. -#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)] +#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, TypeFoldable, TypeVisitable)] pub enum AssertKind { BoundsCheck { len: O, index: O }, Overflow(BinOp, O, O), @@ -863,7 +863,7 @@ pub type AssertMessage<'tcx> = AssertKind>; /// /// 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. -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, HashStable)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, HashStable, TypeFoldable, TypeVisitable)] pub struct Place<'tcx> { pub local: Local, @@ -872,7 +872,7 @@ pub struct Place<'tcx> { } #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[derive(TyEncodable, TyDecodable, HashStable)] +#[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] pub enum ProjectionElem { Deref, Field(Field, T), @@ -955,7 +955,7 @@ pub type PlaceElem<'tcx> = ProjectionElem>; /// **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 /// validator. -#[derive(Clone, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)] +#[derive(Clone, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)] pub enum Operand<'tcx> { /// 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 /// clarification**: Which order?). These are then used to produce a "value" - the same kind of /// 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> { /// Yields the operand unchanged Use(Operand<'tcx>), @@ -1146,6 +1146,7 @@ pub enum CastKind { } #[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)] +#[derive(TypeFoldable, TypeVisitable)] pub enum AggregateKind<'tcx> { /// The type is of the element Array(Ty<'tcx>), diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index 02a9958525b22..4ea333cff7d9d 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -102,7 +102,7 @@ impl<'a> Iterator 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 source_info: SourceInfo, pub kind: TerminatorKind<'tcx>, diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index 82a6b0c506f58..b8f8f697a9c05 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -1,8 +1,9 @@ //! `TypeFoldable` implementations for MIR types +use rustc_ast::InlineAsmTemplatePiece; + use super::*; use crate::ty; -use rustc_data_structures::functor::IdFunctor; TrivialTypeTraversalAndLiftImpls! { BlockTailInfo, @@ -13,96 +14,27 @@ TrivialTypeTraversalAndLiftImpls! { SourceScope, SourceScopeLocalData, UserTypeAnnotationIndex, + BorrowKind, + CastKind, + BinOp, + NullOp, + UnOp, + hir::Movability, + BasicBlock, + SwitchTargets, + GeneratorKind, + GeneratorSavedLocal, } -impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { - fn try_fold_with>(self, folder: &mut F) -> Result { - 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>(self, _: &mut F) -> Result { +impl<'tcx> TypeFoldable<'tcx> for &'tcx [InlineAsmTemplatePiece] { + fn try_fold_with>(self, _folder: &mut F) -> Result { Ok(self) } } -impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> { - fn try_fold_with>(self, folder: &mut F) -> Result { - Ok(Place { - local: self.local.try_fold_with(folder)?, - projection: self.projection.try_fold_with(folder)?, - }) +impl<'tcx> TypeFoldable<'tcx> for &'tcx [Span] { + fn try_fold_with>(self, _folder: &mut F) -> Result { + Ok(self) } } @@ -112,114 +44,12 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { } } -impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> { - fn try_fold_with>(self, folder: &mut F) -> Result { - 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>(self, folder: &mut F) -> Result { - 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>(self, folder: &mut F) -> Result { - 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>(self, _: &mut F) -> Result { - Ok(self) - } -} - -impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal { - fn try_fold_with>(self, _: &mut F) -> Result { - Ok(self) - } -} - impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix { fn try_fold_with>(self, _: &mut F) -> Result { Ok(self) } } -impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> { - fn try_fold_with>(self, folder: &mut F) -> Result { - 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> { #[inline(always)] fn try_fold_with>(self, folder: &mut F) -> Result { diff --git a/compiler/rustc_middle/src/mir/type_visitable.rs b/compiler/rustc_middle/src/mir/type_visitable.rs index 6a0801cb0dd25..27a251f2f56f8 100644 --- a/compiler/rustc_middle/src/mir/type_visitable.rs +++ b/compiler/rustc_middle/src/mir/type_visitable.rs @@ -1,165 +1,6 @@ //! `TypeVisitable` implementations for MIR types use super::*; -use crate::ty; - -impl<'tcx> TypeVisitable<'tcx> for Terminator<'tcx> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - use crate::mir::TerminatorKind::*; - - match self.kind { - SwitchInt { ref discr, switch_ty, .. } => { - discr.visit_with(visitor)?; - switch_ty.visit_with(visitor) - } - Drop { ref place, .. } => place.visit_with(visitor), - DropAndReplace { ref place, ref value, .. } => { - place.visit_with(visitor)?; - value.visit_with(visitor) - } - Yield { ref value, .. } => value.visit_with(visitor), - Call { ref func, ref args, ref destination, .. } => { - destination.visit_with(visitor)?; - func.visit_with(visitor)?; - args.visit_with(visitor) - } - Assert { ref cond, ref msg, .. } => { - cond.visit_with(visitor)?; - use AssertKind::*; - match msg { - BoundsCheck { ref len, ref index } => { - len.visit_with(visitor)?; - index.visit_with(visitor) - } - Overflow(_, l, r) => { - l.visit_with(visitor)?; - r.visit_with(visitor) - } - OverflowNeg(op) | DivisionByZero(op) | RemainderByZero(op) => { - op.visit_with(visitor) - } - ResumedAfterReturn(_) | ResumedAfterPanic(_) => ControlFlow::CONTINUE, - } - } - InlineAsm { ref operands, .. } => operands.visit_with(visitor), - Goto { .. } - | Resume - | Abort - | Return - | GeneratorDrop - | Unreachable - | FalseEdge { .. } - | FalseUnwind { .. } => ControlFlow::CONTINUE, - } - } -} - -impl<'tcx> TypeVisitable<'tcx> for GeneratorKind { - fn visit_with>(&self, _: &mut V) -> ControlFlow { - ControlFlow::CONTINUE - } -} - -impl<'tcx> TypeVisitable<'tcx> for Place<'tcx> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - self.local.visit_with(visitor)?; - self.projection.visit_with(visitor) - } -} - -impl<'tcx> TypeVisitable<'tcx> for &'tcx ty::List> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - self.iter().try_for_each(|t| t.visit_with(visitor)) - } -} - -impl<'tcx> TypeVisitable<'tcx> for Rvalue<'tcx> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - use crate::mir::Rvalue::*; - match *self { - Use(ref op) => op.visit_with(visitor), - 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>(&self, visitor: &mut V) -> ControlFlow { - match *self { - Operand::Copy(ref place) | Operand::Move(ref place) => place.visit_with(visitor), - Operand::Constant(ref c) => c.visit_with(visitor), - } - } -} - -impl<'tcx> TypeVisitable<'tcx> for PlaceElem<'tcx> { - fn visit_with>(&self, visitor: &mut Vs) -> ControlFlow { - use crate::mir::ProjectionElem::*; - - match self { - Field(_, ty) => ty.visit_with(visitor), - Index(v) => v.visit_with(visitor), - _ => ControlFlow::CONTINUE, - } - } -} - -impl<'tcx> TypeVisitable<'tcx> for Field { - fn visit_with>(&self, _: &mut V) -> ControlFlow { - ControlFlow::CONTINUE - } -} - -impl<'tcx> TypeVisitable<'tcx> for GeneratorSavedLocal { - fn visit_with>(&self, _: &mut V) -> ControlFlow { - ControlFlow::CONTINUE - } -} impl<'tcx, R: Idx, C: Idx> TypeVisitable<'tcx> for BitMatrix { fn visit_with>(&self, _: &mut V) -> ControlFlow { @@ -167,13 +8,6 @@ impl<'tcx, R: Idx, C: Idx> TypeVisitable<'tcx> for BitMatrix { } } -impl<'tcx> TypeVisitable<'tcx> for Constant<'tcx> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - self.literal.visit_with(visitor)?; - self.user_ty.visit_with(visitor) - } -} - impl<'tcx> TypeVisitable<'tcx> for ConstantKind<'tcx> { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { visitor.visit_mir_const(*self) diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index d36cf2fe3f8d0..b809f176760d6 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -77,7 +77,7 @@ pub enum PointerCast { /// 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]>` -> /// `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 kind: Adjust<'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> { /// Go from ! to any type. NeverToAny, @@ -108,7 +108,7 @@ pub enum Adjust<'tcx> { /// The target type is `U` in both cases, with the region and mutability /// being those shared by both the receiver and the returned reference. #[derive(Copy, Clone, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)] -#[derive(TypeFoldable, TypeVisitable)] +#[derive(TypeFoldable, TypeVisitable, Lift)] pub struct OverloadedDeref<'tcx> { pub region: ty::Region<'tcx>, pub mutbl: hir::Mutability, @@ -167,7 +167,7 @@ impl From for hir::Mutability { } #[derive(Copy, Clone, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)] -#[derive(TypeFoldable, TypeVisitable)] +#[derive(TypeFoldable, TypeVisitable, Lift)] pub enum AutoBorrow<'tcx> { /// Converts from T to &T. Ref(ty::Region<'tcx>, AutoBorrowMutability), diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index ff20da65c016d..2f7352e0aff24 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -50,7 +50,7 @@ impl<'tcx, P: Default> Unevaluated<'tcx, P> { /// Represents a constant in Rust. #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)] -#[derive(Hash, HashStable)] +#[derive(Hash, HashStable, TypeFoldable, TypeVisitable)] pub enum ConstKind<'tcx> { /// A const generic parameter. Param(ty::ParamConst), diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index c70478d0daa1a..4a9fbc5511c1d 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1820,7 +1820,9 @@ nop_list_lift! {bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariable // This is the impl for `&'a InternalSubsts<'a>`. 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 { use super::{ptr_eq, GlobalCtxt, TyCtxt}; diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index 279c8c8d6d16d..01e1e97b21a0b 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -14,7 +14,7 @@ use rustc_target::spec::abi; use std::borrow::Cow; use std::fmt; -#[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable, TypeVisitable)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable, TypeVisitable, Lift)] pub struct ExpectedFound { pub expected: T, pub found: T, @@ -31,7 +31,7 @@ impl ExpectedFound { } // Data structures used in type unification -#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)] +#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift)] #[rustc_pass_by_value] pub enum TypeError<'tcx> { Mismatch, diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 53218225d53b8..9afd662075620 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -20,14 +20,14 @@ use std::fmt; /// simply couples a potentially generic `InstanceDef` with some substs, and codegen and const eval /// will do all required substitution as they run. #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] -#[derive(HashStable, Lift)] +#[derive(HashStable, Lift, TypeFoldable, TypeVisitable)] pub struct Instance<'tcx> { pub def: InstanceDef<'tcx>, pub substs: SubstsRef<'tcx>, } #[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> { /// A user-defined callable item. /// diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 6641ab9b75636..e8fe37e7dab73 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -636,7 +636,7 @@ impl rustc_errors::IntoDiagnosticArg for Predicate<'_> { } #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable)] +#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] pub enum PredicateKind<'tcx> { /// Corresponds to `where Foo: Bar`. `Foo` here would be /// 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(HashStable, TypeFoldable, TypeVisitable)] +#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] pub struct TraitPredicate<'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(HashStable, TypeFoldable, TypeVisitable)] +#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] pub struct OutlivesPredicate(pub A, pub B); // `A: B` pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate, ty::Region<'tcx>>; pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate, 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 /// presenting user diagnostics. #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable)] +#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] pub struct SubtypePredicate<'tcx> { pub a_is_expected: bool, 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. #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable)] +#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] pub struct CoercePredicate<'tcx> { pub a: Ty<'tcx>, pub b: Ty<'tcx>, @@ -1058,7 +1058,7 @@ impl<'tcx> TermKind<'tcx> { /// Form #2 eventually yields one of these `ProjectionPredicate` /// instances to normalize the LHS. #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable)] +#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] pub struct ProjectionPredicate<'tcx> { pub projection_ty: ProjectionTy<'tcx>, pub term: Term<'tcx>, @@ -1526,7 +1526,7 @@ impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> { Ok(ParamEnv::new( self.caller_bounds().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> { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.caller_bounds().visit_with(visitor)?; - self.reveal().visit_with(visitor)?; - self.constness().visit_with(visitor) + self.reveal().visit_with(visitor) } } @@ -1692,7 +1691,7 @@ impl<'tcx> PolyTraitRef<'tcx> { } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)] -#[derive(HashStable)] +#[derive(HashStable, Lift)] pub struct ParamEnvAnd<'tcx, T> { pub param_env: ParamEnv<'tcx>, pub value: T, diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index d7e74d675de56..f5fd1f6ffafce 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -9,7 +9,6 @@ use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer}; use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; use crate::ty::{self, InferConst, Lift, Term, TermKind, Ty, TyCtxt}; use rustc_data_structures::functor::IdFunctor; -use rustc_hir as hir; use rustc_hir::def::Namespace; use rustc_index::vec::{Idx, IndexVec}; @@ -238,12 +237,24 @@ TrivialTypeTraversalAndLiftImpls! { crate::ty::Variance, ::rustc_span::Span, ::rustc_errors::ErrorGuaranteed, + Field, + interpret::Scalar, + rustc_target::abi::Size, + ty::DelaySpanBugEmitted, + rustc_type_ir::DebruijnIndex, + ty::BoundVar, + ty::Placeholder, +} + +TrivialTypeTraversalAndLiftImpls! { + for<'tcx> { + ty::ValTree<'tcx>, + } } /////////////////////////////////////////////////////////////////////////// // 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 { @@ -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 { type Lifted = Option; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { - match self { - Some(x) => tcx.lift(x).map(Some), - None => Some(None), - } + tcx.lift(self?).map(Some) } } @@ -281,21 +289,21 @@ impl<'tcx, T: Lift<'tcx>, E: Lift<'tcx>> Lift<'tcx> for Result { 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) + Some(Box::new(tcx.lift(*self)?)) } } 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) + Some(Rc::new(tcx.lift(self.as_ref().clone())?)) } } 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) + Some(Arc::new(tcx.lift(self.as_ref().clone())?)) } } impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Vec { @@ -312,35 +320,6 @@ impl<'tcx, I: Idx, T: Lift<'tcx>> Lift<'tcx> for IndexVec { } } -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 { @@ -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> { - 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 { @@ -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 { - 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)?)) - } - } - } -} - -impl<'tcx> Lift<'tcx> for Field { - type Lifted = Field; - fn lift_to_tcx(self, _tcx: TyCtxt<'tcx>) -> Option { - Some(self) - } -} - -impl<'tcx> Lift<'tcx> for crate::mir::ReturnConstraint { - type Lifted = crate::mir::ReturnConstraint; - fn lift_to_tcx(self, _tcx: TyCtxt<'tcx>) -> Option { - Some(self) - } -} - /////////////////////////////////////////////////////////////////////////// // TypeFoldable implementations. @@ -924,88 +602,12 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List 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) @@ -1181,12 +783,6 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { } } -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)) @@ -1233,34 +829,6 @@ impl<'tcx> TypeSuperVisitable<'tcx> for ty::Const<'tcx> { } } -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) @@ -1315,15 +883,3 @@ impl<'tcx> TypeVisitable<'tcx> for ty::Unevaluated<'tcx, ()> { 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 - } -} diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 18169045c901c..36e5608503904 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -202,7 +202,7 @@ static_assert_size!(TyKind<'_>, 32); /// * `GR`: The "return type", which is the type of value returned upon /// completion of the generator. /// * `GW`: The "generator witness". -#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)] +#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift)] pub struct ClosureSubsts<'tcx> { /// Lifetime and type parameters from the enclosing function, /// 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. -#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)] +#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift)] pub struct GeneratorSubsts<'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(HashStable, TypeFoldable, TypeVisitable)] +#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] pub enum ExistentialPredicate<'tcx> { /// E.g., `Iterator`. Trait(ExistentialTraitRef<'tcx>), @@ -789,7 +789,7 @@ impl<'tcx> List>> { /// Trait references also appear in object types like `Foo`, but in /// that case the `Self` parameter is absent from the substitutions. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable)] +#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] pub struct TraitRef<'tcx> { pub def_id: DefId, pub substs: SubstsRef<'tcx>, @@ -867,7 +867,7 @@ impl rustc_errors::IntoDiagnosticArg for PolyTraitRef<'_> { /// The substitutions don't include the erased `Self`, only trait /// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above). #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable)] +#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] pub struct ExistentialTraitRef<'tcx> { pub def_id: DefId, pub substs: SubstsRef<'tcx>, @@ -1023,7 +1023,7 @@ impl BoundVariableKind { /// /// `Decodable` and `Encodable` are implemented for `Binder` using the `impl_binder_encode_decode!` macro. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -#[derive(HashStable)] +#[derive(HashStable, Lift)] pub struct Binder<'tcx, T>(T, &'tcx List); impl<'tcx, T> Binder<'tcx, T> @@ -1185,7 +1185,7 @@ impl<'tcx, T> Binder<'tcx, Option> { /// Represents the projection of an associated type. In explicit UFCS /// form this would be written `>::N`. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable)] +#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] pub struct ProjectionTy<'tcx> { /// The parameters of the associated item. 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 resume_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. /// - `c_variadic`: indicates whether this is a C-variadic function. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable)] +#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] pub struct FnSig<'tcx> { pub inputs_and_output: &'tcx List>, pub c_variadic: bool, @@ -1435,7 +1435,7 @@ impl From for BoundTy { /// A `ProjectionPredicate` for an `ExistentialTraitRef`. #[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 item_def_id: DefId, pub substs: SubstsRef<'tcx>, diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 6262aa1807577..8e69bf067d08e 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -459,12 +459,6 @@ impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> { } } -impl<'tcx> TypeVisitable<'tcx> for SubstsRef<'tcx> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - self.iter().try_for_each(|t| t.visit_with(visitor)) - } -} - impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { fn try_fold_with>(self, folder: &mut F) -> Result { // This code is fairly hot, though not as hot as `SubstsRef`. @@ -497,7 +491,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { } } -impl<'tcx> TypeVisitable<'tcx> for &'tcx ty::List> { +impl<'tcx, T: TypeVisitable<'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)) }