1 //! `TypeFoldable` implementations for MIR types
5 use rustc_data_structures::functor::IdFunctor;
7 TrivialTypeTraversalAndLiftImpls! {
15 UserTypeAnnotationIndex,
18 impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
19 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
20 use crate::mir::TerminatorKind::*;
22 let kind = match self.kind {
23 Goto { target } => Goto { target },
24 SwitchInt { discr, switch_ty, targets } => SwitchInt {
25 discr: discr.try_fold_with(folder)?,
26 switch_ty: switch_ty.try_fold_with(folder)?,
29 Drop { place, target, unwind } => {
30 Drop { place: place.try_fold_with(folder)?, target, unwind }
32 DropAndReplace { place, value, target, unwind } => DropAndReplace {
33 place: place.try_fold_with(folder)?,
34 value: value.try_fold_with(folder)?,
38 Yield { value, resume, resume_arg, drop } => Yield {
39 value: value.try_fold_with(folder)?,
41 resume_arg: resume_arg.try_fold_with(folder)?,
44 Call { func, args, destination, target, cleanup, from_hir_call, fn_span } => Call {
45 func: func.try_fold_with(folder)?,
46 args: args.try_fold_with(folder)?,
47 destination: destination.try_fold_with(folder)?,
53 Assert { cond, expected, msg, target, cleanup } => {
56 BoundsCheck { len, index } => BoundsCheck {
57 len: len.try_fold_with(folder)?,
58 index: index.try_fold_with(folder)?,
60 Overflow(op, l, r) => {
61 Overflow(op, l.try_fold_with(folder)?, r.try_fold_with(folder)?)
63 OverflowNeg(op) => OverflowNeg(op.try_fold_with(folder)?),
64 DivisionByZero(op) => DivisionByZero(op.try_fold_with(folder)?),
65 RemainderByZero(op) => RemainderByZero(op.try_fold_with(folder)?),
66 ResumedAfterReturn(_) | ResumedAfterPanic(_) => msg,
68 Assert { cond: cond.try_fold_with(folder)?, expected, msg, target, cleanup }
70 GeneratorDrop => GeneratorDrop,
74 Unreachable => Unreachable,
75 FalseEdge { real_target, imaginary_target } => {
76 FalseEdge { real_target, imaginary_target }
78 FalseUnwind { real_target, unwind } => FalseUnwind { real_target, unwind },
79 InlineAsm { template, operands, options, line_spans, destination, cleanup } => {
82 operands: operands.try_fold_with(folder)?,
90 Ok(Terminator { source_info: self.source_info, kind })
94 impl<'tcx> TypeFoldable<'tcx> for GeneratorKind {
95 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
100 impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
101 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
103 local: self.local.try_fold_with(folder)?,
104 projection: self.projection.try_fold_with(folder)?,
109 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
110 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
111 ty::util::fold_list(self, folder, |tcx, v| tcx.intern_place_elems(v))
115 impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
116 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
117 use crate::mir::Rvalue::*;
119 Use(op) => Use(op.try_fold_with(folder)?),
120 Repeat(op, len) => Repeat(op.try_fold_with(folder)?, len.try_fold_with(folder)?),
121 ThreadLocalRef(did) => ThreadLocalRef(did.try_fold_with(folder)?),
122 Ref(region, bk, place) => {
123 Ref(region.try_fold_with(folder)?, bk, place.try_fold_with(folder)?)
125 CopyForDeref(place) => CopyForDeref(place.try_fold_with(folder)?),
126 AddressOf(mutability, place) => AddressOf(mutability, place.try_fold_with(folder)?),
127 Len(place) => Len(place.try_fold_with(folder)?),
128 Cast(kind, op, ty) => Cast(kind, op.try_fold_with(folder)?, ty.try_fold_with(folder)?),
129 BinaryOp(op, box (rhs, lhs)) => {
130 BinaryOp(op, Box::new((rhs.try_fold_with(folder)?, lhs.try_fold_with(folder)?)))
132 CheckedBinaryOp(op, box (rhs, lhs)) => CheckedBinaryOp(
134 Box::new((rhs.try_fold_with(folder)?, lhs.try_fold_with(folder)?)),
136 UnaryOp(op, val) => UnaryOp(op, val.try_fold_with(folder)?),
137 Discriminant(place) => Discriminant(place.try_fold_with(folder)?),
138 NullaryOp(op, ty) => NullaryOp(op, ty.try_fold_with(folder)?),
139 Aggregate(kind, fields) => {
140 let kind = kind.try_map_id(|kind| {
142 AggregateKind::Array(ty) => AggregateKind::Array(ty.try_fold_with(folder)?),
143 AggregateKind::Tuple => AggregateKind::Tuple,
144 AggregateKind::Adt(def, v, substs, user_ty, n) => AggregateKind::Adt(
147 substs.try_fold_with(folder)?,
148 user_ty.try_fold_with(folder)?,
151 AggregateKind::Closure(id, substs) => {
152 AggregateKind::Closure(id, substs.try_fold_with(folder)?)
154 AggregateKind::Generator(id, substs, movablity) => {
155 AggregateKind::Generator(id, substs.try_fold_with(folder)?, movablity)
159 Aggregate(kind, fields.try_fold_with(folder)?)
161 ShallowInitBox(op, ty) => {
162 ShallowInitBox(op.try_fold_with(folder)?, ty.try_fold_with(folder)?)
168 impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
169 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
171 Operand::Copy(place) => Operand::Copy(place.try_fold_with(folder)?),
172 Operand::Move(place) => Operand::Move(place.try_fold_with(folder)?),
173 Operand::Constant(c) => Operand::Constant(c.try_fold_with(folder)?),
178 impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> {
179 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
180 use crate::mir::ProjectionElem::*;
184 Field(f, ty) => Field(f, ty.try_fold_with(folder)?),
185 Index(v) => Index(v.try_fold_with(folder)?),
186 Downcast(symbol, variantidx) => Downcast(symbol, variantidx),
187 ConstantIndex { offset, min_length, from_end } => {
188 ConstantIndex { offset, min_length, from_end }
190 Subslice { from, to, from_end } => Subslice { from, to, from_end },
195 impl<'tcx> TypeFoldable<'tcx> for Field {
196 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
201 impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal {
202 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
207 impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix<R, C> {
208 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
213 impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
214 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
217 user_ty: self.user_ty.try_fold_with(folder)?,
218 literal: self.literal.try_fold_with(folder)?,
223 impl<'tcx> TypeFoldable<'tcx> for ConstantKind<'tcx> {
225 fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
226 folder.try_fold_mir_const(self)
230 impl<'tcx> TypeSuperFoldable<'tcx> for ConstantKind<'tcx> {
231 fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
234 ) -> Result<Self, F::Error> {
236 ConstantKind::Ty(c) => Ok(ConstantKind::Ty(c.try_fold_with(folder)?)),
237 ConstantKind::Val(v, t) => Ok(ConstantKind::Val(v, t.try_fold_with(folder)?)),