1 //! `TypeFoldable` implementations for MIR types
6 CloneTypeFoldableAndLiftImpls! {
15 UserTypeAnnotationIndex,
18 impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
19 fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
20 use crate::mir::TerminatorKind::*;
22 let kind = match self.kind {
23 Goto { target } => Goto { target },
24 SwitchInt { ref discr, switch_ty, ref targets } => SwitchInt {
25 discr: discr.fold_with(folder),
26 switch_ty: switch_ty.fold_with(folder),
27 targets: targets.clone(),
29 Drop { ref place, target, unwind } => {
30 Drop { place: place.fold_with(folder), target, unwind }
32 DropAndReplace { ref place, ref value, target, unwind } => DropAndReplace {
33 place: place.fold_with(folder),
34 value: value.fold_with(folder),
38 Yield { ref value, resume, ref resume_arg, drop } => Yield {
39 value: value.fold_with(folder),
41 resume_arg: resume_arg.fold_with(folder),
44 Call { ref func, ref args, ref destination, cleanup, from_hir_call, fn_span } => {
46 destination.as_ref().map(|&(ref loc, dest)| (loc.fold_with(folder), dest));
49 func: func.fold_with(folder),
50 args: args.fold_with(folder),
57 Assert { ref cond, expected, ref msg, target, cleanup } => {
60 BoundsCheck { len, index } => {
61 BoundsCheck { len: len.fold_with(folder), index: index.fold_with(folder) }
63 Overflow(op, l, r) => Overflow(*op, l.fold_with(folder), r.fold_with(folder)),
64 OverflowNeg(op) => OverflowNeg(op.fold_with(folder)),
65 DivisionByZero(op) => DivisionByZero(op.fold_with(folder)),
66 RemainderByZero(op) => RemainderByZero(op.fold_with(folder)),
67 ResumedAfterReturn(_) | ResumedAfterPanic(_) => msg.clone(),
69 Assert { cond: cond.fold_with(folder), expected, msg, target, cleanup }
71 GeneratorDrop => GeneratorDrop,
75 Unreachable => Unreachable,
76 FalseEdge { real_target, imaginary_target } => {
77 FalseEdge { real_target, imaginary_target }
79 FalseUnwind { real_target, unwind } => FalseUnwind { real_target, unwind },
80 InlineAsm { template, ref operands, options, line_spans, destination } => InlineAsm {
82 operands: operands.fold_with(folder),
88 Terminator { source_info: self.source_info, kind }
91 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
92 use crate::mir::TerminatorKind::*;
95 SwitchInt { ref discr, switch_ty, .. } => {
96 discr.visit_with(visitor) || switch_ty.visit_with(visitor)
98 Drop { ref place, .. } => place.visit_with(visitor),
99 DropAndReplace { ref place, ref value, .. } => {
100 place.visit_with(visitor) || value.visit_with(visitor)
102 Yield { ref value, .. } => value.visit_with(visitor),
103 Call { ref func, ref args, ref destination, .. } => {
104 let dest = if let Some((ref loc, _)) = *destination {
105 loc.visit_with(visitor)
109 dest || func.visit_with(visitor) || args.visit_with(visitor)
111 Assert { ref cond, ref msg, .. } => {
112 if cond.visit_with(visitor) {
115 BoundsCheck { ref len, ref index } => {
116 len.visit_with(visitor) || index.visit_with(visitor)
118 Overflow(_, l, r) => l.visit_with(visitor) || r.visit_with(visitor),
119 OverflowNeg(op) | DivisionByZero(op) | RemainderByZero(op) => {
120 op.visit_with(visitor)
122 ResumedAfterReturn(_) | ResumedAfterPanic(_) => false,
128 InlineAsm { ref operands, .. } => operands.visit_with(visitor),
136 | FalseUnwind { .. } => false,
141 impl<'tcx> TypeFoldable<'tcx> for GeneratorKind {
142 fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
146 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
151 impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
152 fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
153 Place { local: self.local.fold_with(folder), projection: self.projection.fold_with(folder) }
156 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
157 self.local.visit_with(visitor) || self.projection.visit_with(visitor)
161 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
162 fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
163 let v = self.iter().map(|t| t.fold_with(folder)).collect::<Vec<_>>();
164 folder.tcx().intern_place_elems(&v)
167 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
168 self.iter().any(|t| t.visit_with(visitor))
172 impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
173 fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
174 use crate::mir::Rvalue::*;
176 Use(ref op) => Use(op.fold_with(folder)),
177 Repeat(ref op, len) => Repeat(op.fold_with(folder), len.fold_with(folder)),
178 ThreadLocalRef(did) => ThreadLocalRef(did.fold_with(folder)),
179 Ref(region, bk, ref place) => {
180 Ref(region.fold_with(folder), bk, place.fold_with(folder))
182 AddressOf(mutability, ref place) => AddressOf(mutability, place.fold_with(folder)),
183 Len(ref place) => Len(place.fold_with(folder)),
184 Cast(kind, ref op, ty) => Cast(kind, op.fold_with(folder), ty.fold_with(folder)),
185 BinaryOp(op, ref rhs, ref lhs) => {
186 BinaryOp(op, rhs.fold_with(folder), lhs.fold_with(folder))
188 CheckedBinaryOp(op, ref rhs, ref lhs) => {
189 CheckedBinaryOp(op, rhs.fold_with(folder), lhs.fold_with(folder))
191 UnaryOp(op, ref val) => UnaryOp(op, val.fold_with(folder)),
192 Discriminant(ref place) => Discriminant(place.fold_with(folder)),
193 NullaryOp(op, ty) => NullaryOp(op, ty.fold_with(folder)),
194 Aggregate(ref kind, ref fields) => {
195 let kind = box match **kind {
196 AggregateKind::Array(ty) => AggregateKind::Array(ty.fold_with(folder)),
197 AggregateKind::Tuple => AggregateKind::Tuple,
198 AggregateKind::Adt(def, v, substs, user_ty, n) => AggregateKind::Adt(
201 substs.fold_with(folder),
202 user_ty.fold_with(folder),
205 AggregateKind::Closure(id, substs) => {
206 AggregateKind::Closure(id, substs.fold_with(folder))
208 AggregateKind::Generator(id, substs, movablity) => {
209 AggregateKind::Generator(id, substs.fold_with(folder), movablity)
212 Aggregate(kind, fields.fold_with(folder))
217 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
218 use crate::mir::Rvalue::*;
220 Use(ref op) => op.visit_with(visitor),
221 Repeat(ref op, _) => op.visit_with(visitor),
222 ThreadLocalRef(did) => did.visit_with(visitor),
223 Ref(region, _, ref place) => region.visit_with(visitor) || place.visit_with(visitor),
224 AddressOf(_, ref place) => place.visit_with(visitor),
225 Len(ref place) => place.visit_with(visitor),
226 Cast(_, ref op, ty) => op.visit_with(visitor) || ty.visit_with(visitor),
227 BinaryOp(_, ref rhs, ref lhs) | CheckedBinaryOp(_, ref rhs, ref lhs) => {
228 rhs.visit_with(visitor) || lhs.visit_with(visitor)
230 UnaryOp(_, ref val) => val.visit_with(visitor),
231 Discriminant(ref place) => place.visit_with(visitor),
232 NullaryOp(_, ty) => ty.visit_with(visitor),
233 Aggregate(ref kind, ref fields) => {
235 AggregateKind::Array(ty) => ty.visit_with(visitor),
236 AggregateKind::Tuple => false,
237 AggregateKind::Adt(_, _, substs, user_ty, _) => {
238 substs.visit_with(visitor) || user_ty.visit_with(visitor)
240 AggregateKind::Closure(_, substs) => substs.visit_with(visitor),
241 AggregateKind::Generator(_, substs, _) => substs.visit_with(visitor),
242 }) || fields.visit_with(visitor)
248 impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
249 fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
251 Operand::Copy(ref place) => Operand::Copy(place.fold_with(folder)),
252 Operand::Move(ref place) => Operand::Move(place.fold_with(folder)),
253 Operand::Constant(ref c) => Operand::Constant(c.fold_with(folder)),
257 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
259 Operand::Copy(ref place) | Operand::Move(ref place) => place.visit_with(visitor),
260 Operand::Constant(ref c) => c.visit_with(visitor),
265 impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> {
266 fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
267 use crate::mir::ProjectionElem::*;
271 Field(f, ty) => Field(f, ty.fold_with(folder)),
272 Index(v) => Index(v.fold_with(folder)),
273 Downcast(symbol, variantidx) => Downcast(symbol, variantidx),
274 ConstantIndex { offset, min_length, from_end } => {
275 ConstantIndex { offset, min_length, from_end }
277 Subslice { from, to, from_end } => Subslice { from, to, from_end },
281 fn super_visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> bool {
282 use crate::mir::ProjectionElem::*;
285 Field(_, ty) => ty.visit_with(visitor),
286 Index(v) => v.visit_with(visitor),
292 impl<'tcx> TypeFoldable<'tcx> for Field {
293 fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
296 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
301 impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal {
302 fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
305 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
310 impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix<R, C> {
311 fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
314 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
319 impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
320 fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
323 user_ty: self.user_ty.fold_with(folder),
324 literal: self.literal.fold_with(folder),
327 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
328 self.literal.visit_with(visitor)