]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_middle/src/mir/type_foldable.rs
New upstream version 1.52.0~beta.3+dfsg1
[rustc.git] / compiler / rustc_middle / src / mir / type_foldable.rs
CommitLineData
ba9703b0
XL
1//! `TypeFoldable` implementations for MIR types
2
3use super::*;
4use crate::ty;
fc512014 5use rustc_data_structures::functor::IdFunctor;
ba9703b0 6
fc512014 7TrivialTypeFoldableAndLiftImpls! {
ba9703b0
XL
8 BlockTailInfo,
9 MirPhase,
10 SourceInfo,
11 FakeReadCause,
12 RetagKind,
13 SourceScope,
ba9703b0
XL
14 SourceScopeLocalData,
15 UserTypeAnnotationIndex,
16}
17
18impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
fc512014 19 fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
ba9703b0
XL
20 use crate::mir::TerminatorKind::*;
21
22 let kind = match self.kind {
23 Goto { target } => Goto { target },
fc512014 24 SwitchInt { discr, switch_ty, targets } => SwitchInt {
ba9703b0
XL
25 discr: discr.fold_with(folder),
26 switch_ty: switch_ty.fold_with(folder),
fc512014 27 targets,
ba9703b0 28 },
fc512014 29 Drop { place, target, unwind } => {
f035d41b 30 Drop { place: place.fold_with(folder), target, unwind }
ba9703b0 31 }
fc512014 32 DropAndReplace { place, value, target, unwind } => DropAndReplace {
f035d41b 33 place: place.fold_with(folder),
ba9703b0
XL
34 value: value.fold_with(folder),
35 target,
36 unwind,
37 },
fc512014 38 Yield { value, resume, resume_arg, drop } => Yield {
ba9703b0
XL
39 value: value.fold_with(folder),
40 resume,
41 resume_arg: resume_arg.fold_with(folder),
42 drop,
43 },
fc512014
XL
44 Call { func, args, destination, cleanup, from_hir_call, fn_span } => {
45 let dest = destination.map(|(loc, dest)| (loc.fold_with(folder), dest));
ba9703b0
XL
46
47 Call {
48 func: func.fold_with(folder),
49 args: args.fold_with(folder),
50 destination: dest,
51 cleanup,
52 from_hir_call,
f035d41b 53 fn_span,
ba9703b0
XL
54 }
55 }
fc512014 56 Assert { cond, expected, msg, target, cleanup } => {
ba9703b0
XL
57 use AssertKind::*;
58 let msg = match msg {
f035d41b 59 BoundsCheck { len, index } => {
ba9703b0
XL
60 BoundsCheck { len: len.fold_with(folder), index: index.fold_with(folder) }
61 }
fc512014 62 Overflow(op, l, r) => Overflow(op, l.fold_with(folder), r.fold_with(folder)),
f035d41b
XL
63 OverflowNeg(op) => OverflowNeg(op.fold_with(folder)),
64 DivisionByZero(op) => DivisionByZero(op.fold_with(folder)),
65 RemainderByZero(op) => RemainderByZero(op.fold_with(folder)),
fc512014 66 ResumedAfterReturn(_) | ResumedAfterPanic(_) => msg,
ba9703b0
XL
67 };
68 Assert { cond: cond.fold_with(folder), expected, msg, target, cleanup }
69 }
70 GeneratorDrop => GeneratorDrop,
71 Resume => Resume,
72 Abort => Abort,
73 Return => Return,
74 Unreachable => Unreachable,
f035d41b
XL
75 FalseEdge { real_target, imaginary_target } => {
76 FalseEdge { real_target, imaginary_target }
ba9703b0
XL
77 }
78 FalseUnwind { real_target, unwind } => FalseUnwind { real_target, unwind },
fc512014 79 InlineAsm { template, operands, options, line_spans, destination } => InlineAsm {
f9f354fc
XL
80 template,
81 operands: operands.fold_with(folder),
82 options,
83 line_spans,
84 destination,
85 },
ba9703b0
XL
86 };
87 Terminator { source_info: self.source_info, kind }
88 }
89
fc512014 90 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
ba9703b0
XL
91 use crate::mir::TerminatorKind::*;
92
93 match self.kind {
94 SwitchInt { ref discr, switch_ty, .. } => {
29967ef6
XL
95 discr.visit_with(visitor)?;
96 switch_ty.visit_with(visitor)
ba9703b0 97 }
f035d41b
XL
98 Drop { ref place, .. } => place.visit_with(visitor),
99 DropAndReplace { ref place, ref value, .. } => {
29967ef6
XL
100 place.visit_with(visitor)?;
101 value.visit_with(visitor)
ba9703b0
XL
102 }
103 Yield { ref value, .. } => value.visit_with(visitor),
104 Call { ref func, ref args, ref destination, .. } => {
29967ef6
XL
105 if let Some((ref loc, _)) = *destination {
106 loc.visit_with(visitor)?;
ba9703b0 107 };
29967ef6
XL
108 func.visit_with(visitor)?;
109 args.visit_with(visitor)
ba9703b0
XL
110 }
111 Assert { ref cond, ref msg, .. } => {
29967ef6
XL
112 cond.visit_with(visitor)?;
113 use AssertKind::*;
114 match msg {
115 BoundsCheck { ref len, ref index } => {
116 len.visit_with(visitor)?;
117 index.visit_with(visitor)
118 }
119 Overflow(_, l, r) => {
120 l.visit_with(visitor)?;
121 r.visit_with(visitor)
122 }
123 OverflowNeg(op) | DivisionByZero(op) | RemainderByZero(op) => {
124 op.visit_with(visitor)
ba9703b0 125 }
29967ef6 126 ResumedAfterReturn(_) | ResumedAfterPanic(_) => ControlFlow::CONTINUE,
ba9703b0
XL
127 }
128 }
f9f354fc 129 InlineAsm { ref operands, .. } => operands.visit_with(visitor),
ba9703b0
XL
130 Goto { .. }
131 | Resume
132 | Abort
133 | Return
134 | GeneratorDrop
135 | Unreachable
f035d41b 136 | FalseEdge { .. }
29967ef6 137 | FalseUnwind { .. } => ControlFlow::CONTINUE,
ba9703b0
XL
138 }
139 }
140}
141
142impl<'tcx> TypeFoldable<'tcx> for GeneratorKind {
fc512014
XL
143 fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Self {
144 self
ba9703b0
XL
145 }
146
fc512014 147 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
29967ef6 148 ControlFlow::CONTINUE
ba9703b0
XL
149 }
150}
151
152impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
fc512014 153 fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
ba9703b0
XL
154 Place { local: self.local.fold_with(folder), projection: self.projection.fold_with(folder) }
155 }
156
fc512014 157 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
29967ef6
XL
158 self.local.visit_with(visitor)?;
159 self.projection.visit_with(visitor)
ba9703b0
XL
160 }
161}
162
163impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
fc512014
XL
164 fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
165 ty::util::fold_list(self, folder, |tcx, v| tcx.intern_place_elems(v))
ba9703b0
XL
166 }
167
fc512014 168 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
29967ef6 169 self.iter().try_for_each(|t| t.visit_with(visitor))
ba9703b0
XL
170 }
171}
172
173impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
fc512014 174 fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
ba9703b0 175 use crate::mir::Rvalue::*;
fc512014
XL
176 match self {
177 Use(op) => Use(op.fold_with(folder)),
178 Repeat(op, len) => Repeat(op.fold_with(folder), len.fold_with(folder)),
f9f354fc 179 ThreadLocalRef(did) => ThreadLocalRef(did.fold_with(folder)),
fc512014
XL
180 Ref(region, bk, place) => Ref(region.fold_with(folder), bk, place.fold_with(folder)),
181 AddressOf(mutability, place) => AddressOf(mutability, place.fold_with(folder)),
182 Len(place) => Len(place.fold_with(folder)),
183 Cast(kind, op, ty) => Cast(kind, op.fold_with(folder), ty.fold_with(folder)),
6a06907d
XL
184 BinaryOp(op, box (rhs, lhs)) => {
185 BinaryOp(op, box (rhs.fold_with(folder), lhs.fold_with(folder)))
186 }
187 CheckedBinaryOp(op, box (rhs, lhs)) => {
188 CheckedBinaryOp(op, box (rhs.fold_with(folder), lhs.fold_with(folder)))
ba9703b0 189 }
fc512014
XL
190 UnaryOp(op, val) => UnaryOp(op, val.fold_with(folder)),
191 Discriminant(place) => Discriminant(place.fold_with(folder)),
ba9703b0 192 NullaryOp(op, ty) => NullaryOp(op, ty.fold_with(folder)),
fc512014
XL
193 Aggregate(kind, fields) => {
194 let kind = kind.map_id(|kind| match kind {
ba9703b0
XL
195 AggregateKind::Array(ty) => AggregateKind::Array(ty.fold_with(folder)),
196 AggregateKind::Tuple => AggregateKind::Tuple,
197 AggregateKind::Adt(def, v, substs, user_ty, n) => AggregateKind::Adt(
198 def,
199 v,
200 substs.fold_with(folder),
201 user_ty.fold_with(folder),
202 n,
203 ),
204 AggregateKind::Closure(id, substs) => {
205 AggregateKind::Closure(id, substs.fold_with(folder))
206 }
207 AggregateKind::Generator(id, substs, movablity) => {
208 AggregateKind::Generator(id, substs.fold_with(folder), movablity)
209 }
fc512014 210 });
ba9703b0
XL
211 Aggregate(kind, fields.fold_with(folder))
212 }
213 }
214 }
215
fc512014 216 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
ba9703b0
XL
217 use crate::mir::Rvalue::*;
218 match *self {
219 Use(ref op) => op.visit_with(visitor),
220 Repeat(ref op, _) => op.visit_with(visitor),
f9f354fc 221 ThreadLocalRef(did) => did.visit_with(visitor),
29967ef6
XL
222 Ref(region, _, ref place) => {
223 region.visit_with(visitor)?;
224 place.visit_with(visitor)
225 }
ba9703b0
XL
226 AddressOf(_, ref place) => place.visit_with(visitor),
227 Len(ref place) => place.visit_with(visitor),
29967ef6
XL
228 Cast(_, ref op, ty) => {
229 op.visit_with(visitor)?;
230 ty.visit_with(visitor)
231 }
6a06907d 232 BinaryOp(_, box (ref rhs, ref lhs)) | CheckedBinaryOp(_, box (ref rhs, ref lhs)) => {
29967ef6
XL
233 rhs.visit_with(visitor)?;
234 lhs.visit_with(visitor)
ba9703b0
XL
235 }
236 UnaryOp(_, ref val) => val.visit_with(visitor),
237 Discriminant(ref place) => place.visit_with(visitor),
238 NullaryOp(_, ty) => ty.visit_with(visitor),
239 Aggregate(ref kind, ref fields) => {
29967ef6
XL
240 match **kind {
241 AggregateKind::Array(ty) => {
242 ty.visit_with(visitor)?;
243 }
244 AggregateKind::Tuple => {}
ba9703b0 245 AggregateKind::Adt(_, _, substs, user_ty, _) => {
29967ef6
XL
246 substs.visit_with(visitor)?;
247 user_ty.visit_with(visitor)?;
248 }
249 AggregateKind::Closure(_, substs) => {
250 substs.visit_with(visitor)?;
ba9703b0 251 }
29967ef6
XL
252 AggregateKind::Generator(_, substs, _) => {
253 substs.visit_with(visitor)?;
254 }
255 }
256 fields.visit_with(visitor)
ba9703b0
XL
257 }
258 }
259 }
260}
261
262impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
fc512014
XL
263 fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
264 match self {
265 Operand::Copy(place) => Operand::Copy(place.fold_with(folder)),
266 Operand::Move(place) => Operand::Move(place.fold_with(folder)),
267 Operand::Constant(c) => Operand::Constant(c.fold_with(folder)),
ba9703b0
XL
268 }
269 }
270
fc512014 271 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
ba9703b0
XL
272 match *self {
273 Operand::Copy(ref place) | Operand::Move(ref place) => place.visit_with(visitor),
274 Operand::Constant(ref c) => c.visit_with(visitor),
275 }
276 }
277}
278
279impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> {
fc512014 280 fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
ba9703b0
XL
281 use crate::mir::ProjectionElem::*;
282
fc512014 283 match self {
ba9703b0
XL
284 Deref => Deref,
285 Field(f, ty) => Field(f, ty.fold_with(folder)),
286 Index(v) => Index(v.fold_with(folder)),
287 Downcast(symbol, variantidx) => Downcast(symbol, variantidx),
288 ConstantIndex { offset, min_length, from_end } => {
289 ConstantIndex { offset, min_length, from_end }
290 }
291 Subslice { from, to, from_end } => Subslice { from, to, from_end },
292 }
293 }
294
fc512014
XL
295 fn super_visit_with<Vs: TypeVisitor<'tcx>>(
296 &self,
297 visitor: &mut Vs,
298 ) -> ControlFlow<Vs::BreakTy> {
ba9703b0
XL
299 use crate::mir::ProjectionElem::*;
300
301 match self {
302 Field(_, ty) => ty.visit_with(visitor),
303 Index(v) => v.visit_with(visitor),
29967ef6 304 _ => ControlFlow::CONTINUE,
ba9703b0
XL
305 }
306 }
307}
308
309impl<'tcx> TypeFoldable<'tcx> for Field {
fc512014
XL
310 fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Self {
311 self
ba9703b0 312 }
fc512014 313 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
29967ef6 314 ControlFlow::CONTINUE
ba9703b0
XL
315 }
316}
317
318impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal {
fc512014
XL
319 fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Self {
320 self
ba9703b0 321 }
fc512014 322 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
29967ef6 323 ControlFlow::CONTINUE
ba9703b0
XL
324 }
325}
326
327impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix<R, C> {
fc512014
XL
328 fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Self {
329 self
ba9703b0 330 }
fc512014 331 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
29967ef6 332 ControlFlow::CONTINUE
ba9703b0
XL
333 }
334}
335
336impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
fc512014 337 fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
ba9703b0
XL
338 Constant {
339 span: self.span,
340 user_ty: self.user_ty.fold_with(folder),
341 literal: self.literal.fold_with(folder),
342 }
343 }
fc512014 344 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
6a06907d
XL
345 self.literal.visit_with(visitor)?;
346 self.user_ty.visit_with(visitor)
347 }
348}
349
350impl<'tcx> TypeFoldable<'tcx> for ConstantKind<'tcx> {
351 fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
352 match self {
353 ConstantKind::Ty(c) => ConstantKind::Ty(c.fold_with(folder)),
354 ConstantKind::Val(v, t) => ConstantKind::Val(v, t.fold_with(folder)),
355 }
356 }
357
358 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
359 match *self {
360 ConstantKind::Ty(c) => c.visit_with(visitor),
361 ConstantKind::Val(_, t) => t.visit_with(visitor),
362 }
ba9703b0
XL
363 }
364}