1 //! `TypeFoldable` implementations for MIR types
5 use rustc_data_structures
::functor
::IdFunctor
;
7 TrivialTypeFoldableAndLiftImpls
! {
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 { discr, switch_ty, targets }
=> SwitchInt
{
25 discr
: discr
.fold_with(folder
),
26 switch_ty
: switch_ty
.fold_with(folder
),
29 Drop { place, target, unwind }
=> {
30 Drop { place: place.fold_with(folder), target, unwind }
32 DropAndReplace { place, value, target, unwind }
=> DropAndReplace
{
33 place
: place
.fold_with(folder
),
34 value
: value
.fold_with(folder
),
38 Yield { value, resume, resume_arg, drop }
=> Yield
{
39 value
: value
.fold_with(folder
),
41 resume_arg
: resume_arg
.fold_with(folder
),
44 Call { func, args, destination, cleanup, from_hir_call, fn_span }
=> {
45 let dest
= destination
.map(|(loc
, dest
)| (loc
.fold_with(folder
), dest
));
48 func
: func
.fold_with(folder
),
49 args
: args
.fold_with(folder
),
56 Assert { cond, expected, msg, target, cleanup }
=> {
59 BoundsCheck { len, index }
=> {
60 BoundsCheck { len: len.fold_with(folder), index: index.fold_with(folder) }
62 Overflow(op
, l
, r
) => Overflow(op
, l
.fold_with(folder
), r
.fold_with(folder
)),
63 OverflowNeg(op
) => OverflowNeg(op
.fold_with(folder
)),
64 DivisionByZero(op
) => DivisionByZero(op
.fold_with(folder
)),
65 RemainderByZero(op
) => RemainderByZero(op
.fold_with(folder
)),
66 ResumedAfterReturn(_
) | ResumedAfterPanic(_
) => msg
,
68 Assert { cond: cond.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 }
=> InlineAsm
{
81 operands
: operands
.fold_with(folder
),
87 Terminator { source_info: self.source_info, kind }
90 fn super_visit_with
<V
: TypeVisitor
<'tcx
>>(&self, visitor
: &mut V
) -> ControlFlow
<V
::BreakTy
> {
91 use crate::mir
::TerminatorKind
::*;
94 SwitchInt { ref discr, switch_ty, .. }
=> {
95 discr
.visit_with(visitor
)?
;
96 switch_ty
.visit_with(visitor
)
98 Drop { ref place, .. }
=> place
.visit_with(visitor
),
99 DropAndReplace { ref place, ref value, .. }
=> {
100 place
.visit_with(visitor
)?
;
101 value
.visit_with(visitor
)
103 Yield { ref value, .. }
=> value
.visit_with(visitor
),
104 Call { ref func, ref args, ref destination, .. }
=> {
105 if let Some((ref loc
, _
)) = *destination
{
106 loc
.visit_with(visitor
)?
;
108 func
.visit_with(visitor
)?
;
109 args
.visit_with(visitor
)
111 Assert { ref cond, ref msg, .. }
=> {
112 cond
.visit_with(visitor
)?
;
115 BoundsCheck { ref len, ref index }
=> {
116 len
.visit_with(visitor
)?
;
117 index
.visit_with(visitor
)
119 Overflow(_
, l
, r
) => {
120 l
.visit_with(visitor
)?
;
121 r
.visit_with(visitor
)
123 OverflowNeg(op
) | DivisionByZero(op
) | RemainderByZero(op
) => {
124 op
.visit_with(visitor
)
126 ResumedAfterReturn(_
) | ResumedAfterPanic(_
) => ControlFlow
::CONTINUE
,
129 InlineAsm { ref operands, .. }
=> operands
.visit_with(visitor
),
137 | FalseUnwind { .. }
=> ControlFlow
::CONTINUE
,
142 impl<'tcx
> TypeFoldable
<'tcx
> for GeneratorKind
{
143 fn super_fold_with
<F
: TypeFolder
<'tcx
>>(self, _
: &mut F
) -> Self {
147 fn super_visit_with
<V
: TypeVisitor
<'tcx
>>(&self, _
: &mut V
) -> ControlFlow
<V
::BreakTy
> {
148 ControlFlow
::CONTINUE
152 impl<'tcx
> TypeFoldable
<'tcx
> for Place
<'tcx
> {
153 fn super_fold_with
<F
: TypeFolder
<'tcx
>>(self, folder
: &mut F
) -> Self {
154 Place { local: self.local.fold_with(folder), projection: self.projection.fold_with(folder) }
157 fn super_visit_with
<V
: TypeVisitor
<'tcx
>>(&self, visitor
: &mut V
) -> ControlFlow
<V
::BreakTy
> {
158 self.local
.visit_with(visitor
)?
;
159 self.projection
.visit_with(visitor
)
163 impl<'tcx
> TypeFoldable
<'tcx
> for &'tcx ty
::List
<PlaceElem
<'tcx
>> {
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
))
168 fn super_visit_with
<V
: TypeVisitor
<'tcx
>>(&self, visitor
: &mut V
) -> ControlFlow
<V
::BreakTy
> {
169 self.iter().try_for_each(|t
| t
.visit_with(visitor
))
173 impl<'tcx
> TypeFoldable
<'tcx
> for Rvalue
<'tcx
> {
174 fn super_fold_with
<F
: TypeFolder
<'tcx
>>(self, folder
: &mut F
) -> Self {
175 use crate::mir
::Rvalue
::*;
177 Use(op
) => Use(op
.fold_with(folder
)),
178 Repeat(op
, len
) => Repeat(op
.fold_with(folder
), len
.fold_with(folder
)),
179 ThreadLocalRef(did
) => ThreadLocalRef(did
.fold_with(folder
)),
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
)),
184 BinaryOp(op
, box (rhs
, lhs
)) => {
185 BinaryOp(op
, Box
::new((rhs
.fold_with(folder
), lhs
.fold_with(folder
))))
187 CheckedBinaryOp(op
, box (rhs
, lhs
)) => {
188 CheckedBinaryOp(op
, Box
::new((rhs
.fold_with(folder
), lhs
.fold_with(folder
))))
190 UnaryOp(op
, val
) => UnaryOp(op
, val
.fold_with(folder
)),
191 Discriminant(place
) => Discriminant(place
.fold_with(folder
)),
192 NullaryOp(op
, ty
) => NullaryOp(op
, ty
.fold_with(folder
)),
193 Aggregate(kind
, fields
) => {
194 let kind
= kind
.map_id(|kind
| match kind
{
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(
200 substs
.fold_with(folder
),
201 user_ty
.fold_with(folder
),
204 AggregateKind
::Closure(id
, substs
) => {
205 AggregateKind
::Closure(id
, substs
.fold_with(folder
))
207 AggregateKind
::Generator(id
, substs
, movablity
) => {
208 AggregateKind
::Generator(id
, substs
.fold_with(folder
), movablity
)
211 Aggregate(kind
, fields
.fold_with(folder
))
216 fn super_visit_with
<V
: TypeVisitor
<'tcx
>>(&self, visitor
: &mut V
) -> ControlFlow
<V
::BreakTy
> {
217 use crate::mir
::Rvalue
::*;
219 Use(ref op
) => op
.visit_with(visitor
),
220 Repeat(ref op
, _
) => op
.visit_with(visitor
),
221 ThreadLocalRef(did
) => did
.visit_with(visitor
),
222 Ref(region
, _
, ref place
) => {
223 region
.visit_with(visitor
)?
;
224 place
.visit_with(visitor
)
226 AddressOf(_
, ref place
) => place
.visit_with(visitor
),
227 Len(ref place
) => place
.visit_with(visitor
),
228 Cast(_
, ref op
, ty
) => {
229 op
.visit_with(visitor
)?
;
230 ty
.visit_with(visitor
)
232 BinaryOp(_
, box (ref rhs
, ref lhs
)) | CheckedBinaryOp(_
, box (ref rhs
, ref lhs
)) => {
233 rhs
.visit_with(visitor
)?
;
234 lhs
.visit_with(visitor
)
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
) => {
241 AggregateKind
::Array(ty
) => {
242 ty
.visit_with(visitor
)?
;
244 AggregateKind
::Tuple
=> {}
245 AggregateKind
::Adt(_
, _
, substs
, user_ty
, _
) => {
246 substs
.visit_with(visitor
)?
;
247 user_ty
.visit_with(visitor
)?
;
249 AggregateKind
::Closure(_
, substs
) => {
250 substs
.visit_with(visitor
)?
;
252 AggregateKind
::Generator(_
, substs
, _
) => {
253 substs
.visit_with(visitor
)?
;
256 fields
.visit_with(visitor
)
262 impl<'tcx
> TypeFoldable
<'tcx
> for Operand
<'tcx
> {
263 fn super_fold_with
<F
: TypeFolder
<'tcx
>>(self, folder
: &mut F
) -> 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
)),
271 fn super_visit_with
<V
: TypeVisitor
<'tcx
>>(&self, visitor
: &mut V
) -> ControlFlow
<V
::BreakTy
> {
273 Operand
::Copy(ref place
) | Operand
::Move(ref place
) => place
.visit_with(visitor
),
274 Operand
::Constant(ref c
) => c
.visit_with(visitor
),
279 impl<'tcx
> TypeFoldable
<'tcx
> for PlaceElem
<'tcx
> {
280 fn super_fold_with
<F
: TypeFolder
<'tcx
>>(self, folder
: &mut F
) -> Self {
281 use crate::mir
::ProjectionElem
::*;
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 }
291 Subslice { from, to, from_end }
=> Subslice { from, to, from_end }
,
295 fn super_visit_with
<Vs
: TypeVisitor
<'tcx
>>(
298 ) -> ControlFlow
<Vs
::BreakTy
> {
299 use crate::mir
::ProjectionElem
::*;
302 Field(_
, ty
) => ty
.visit_with(visitor
),
303 Index(v
) => v
.visit_with(visitor
),
304 _
=> ControlFlow
::CONTINUE
,
309 impl<'tcx
> TypeFoldable
<'tcx
> for Field
{
310 fn super_fold_with
<F
: TypeFolder
<'tcx
>>(self, _
: &mut F
) -> Self {
313 fn super_visit_with
<V
: TypeVisitor
<'tcx
>>(&self, _
: &mut V
) -> ControlFlow
<V
::BreakTy
> {
314 ControlFlow
::CONTINUE
318 impl<'tcx
> TypeFoldable
<'tcx
> for GeneratorSavedLocal
{
319 fn super_fold_with
<F
: TypeFolder
<'tcx
>>(self, _
: &mut F
) -> Self {
322 fn super_visit_with
<V
: TypeVisitor
<'tcx
>>(&self, _
: &mut V
) -> ControlFlow
<V
::BreakTy
> {
323 ControlFlow
::CONTINUE
327 impl<'tcx
, R
: Idx
, C
: Idx
> TypeFoldable
<'tcx
> for BitMatrix
<R
, C
> {
328 fn super_fold_with
<F
: TypeFolder
<'tcx
>>(self, _
: &mut F
) -> Self {
331 fn super_visit_with
<V
: TypeVisitor
<'tcx
>>(&self, _
: &mut V
) -> ControlFlow
<V
::BreakTy
> {
332 ControlFlow
::CONTINUE
336 impl<'tcx
> TypeFoldable
<'tcx
> for Constant
<'tcx
> {
337 fn super_fold_with
<F
: TypeFolder
<'tcx
>>(self, folder
: &mut F
) -> Self {
340 user_ty
: self.user_ty
.fold_with(folder
),
341 literal
: self.literal
.fold_with(folder
),
344 fn super_visit_with
<V
: TypeVisitor
<'tcx
>>(&self, visitor
: &mut V
) -> ControlFlow
<V
::BreakTy
> {
345 self.literal
.visit_with(visitor
)?
;
346 self.user_ty
.visit_with(visitor
)
350 impl<'tcx
> TypeFoldable
<'tcx
> for ConstantKind
<'tcx
> {
352 fn fold_with
<F
: TypeFolder
<'tcx
>>(self, folder
: &mut F
) -> Self {
353 folder
.fold_mir_const(self)
356 fn super_fold_with
<F
: TypeFolder
<'tcx
>>(self, folder
: &mut F
) -> Self {
358 ConstantKind
::Ty(c
) => ConstantKind
::Ty(c
.fold_with(folder
)),
359 ConstantKind
::Val(v
, t
) => ConstantKind
::Val(v
, t
.fold_with(folder
)),
363 fn super_visit_with
<V
: TypeVisitor
<'tcx
>>(&self, visitor
: &mut V
) -> ControlFlow
<V
::BreakTy
> {
365 ConstantKind
::Ty(c
) => c
.visit_with(visitor
),
366 ConstantKind
::Val(_
, t
) => t
.visit_with(visitor
),