]>
Commit | Line | Data |
---|---|---|
ba9703b0 XL |
1 | //! `TypeFoldable` implementations for MIR types |
2 | ||
3 | use super::*; | |
4 | use crate::ty; | |
fc512014 | 5 | use rustc_data_structures::functor::IdFunctor; |
ba9703b0 | 6 | |
fc512014 | 7 | TrivialTypeFoldableAndLiftImpls! { |
ba9703b0 XL |
8 | BlockTailInfo, |
9 | MirPhase, | |
10 | SourceInfo, | |
11 | FakeReadCause, | |
12 | RetagKind, | |
13 | SourceScope, | |
ba9703b0 XL |
14 | SourceScopeLocalData, |
15 | UserTypeAnnotationIndex, | |
16 | } | |
17 | ||
18 | impl<'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 | ||
142 | impl<'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 | ||
152 | impl<'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 | ||
163 | impl<'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 | ||
173 | impl<'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 | 184 | BinaryOp(op, box (rhs, lhs)) => { |
94222f64 | 185 | BinaryOp(op, Box::new((rhs.fold_with(folder), lhs.fold_with(folder)))) |
6a06907d XL |
186 | } |
187 | CheckedBinaryOp(op, box (rhs, lhs)) => { | |
94222f64 | 188 | CheckedBinaryOp(op, Box::new((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 | ||
262 | impl<'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 | ||
279 | impl<'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 | ||
309 | impl<'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 | ||
318 | impl<'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 | ||
327 | impl<'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 | ||
336 | impl<'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 | ||
350 | impl<'tcx> TypeFoldable<'tcx> for ConstantKind<'tcx> { | |
cdc7bbd5 XL |
351 | #[inline(always)] |
352 | fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self { | |
353 | folder.fold_mir_const(self) | |
354 | } | |
355 | ||
6a06907d XL |
356 | fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self { |
357 | match self { | |
358 | ConstantKind::Ty(c) => ConstantKind::Ty(c.fold_with(folder)), | |
359 | ConstantKind::Val(v, t) => ConstantKind::Val(v, t.fold_with(folder)), | |
360 | } | |
361 | } | |
362 | ||
363 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { | |
364 | match *self { | |
365 | ConstantKind::Ty(c) => c.visit_with(visitor), | |
366 | ConstantKind::Val(_, t) => t.visit_with(visitor), | |
367 | } | |
ba9703b0 XL |
368 | } |
369 | } |