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 values, ref targets }
=> SwitchInt
{
25 discr
: discr
.fold_with(folder
),
26 switch_ty
: switch_ty
.fold_with(folder
),
27 values
: values
.clone(),
28 targets
: targets
.clone(),
30 Drop { ref place, target, unwind }
=> {
31 Drop { place: place.fold_with(folder), target, unwind }
33 DropAndReplace { ref place, ref value, target, unwind }
=> DropAndReplace
{
34 place
: place
.fold_with(folder
),
35 value
: value
.fold_with(folder
),
39 Yield { ref value, resume, ref resume_arg, drop }
=> Yield
{
40 value
: value
.fold_with(folder
),
42 resume_arg
: resume_arg
.fold_with(folder
),
45 Call { ref func, ref args, ref destination, cleanup, from_hir_call, fn_span }
=> {
47 destination
.as_ref().map(|&(ref loc
, dest
)| (loc
.fold_with(folder
), dest
));
50 func
: func
.fold_with(folder
),
51 args
: args
.fold_with(folder
),
58 Assert { ref cond, expected, ref msg, target, cleanup }
=> {
61 BoundsCheck { len, index }
=> {
62 BoundsCheck { len: len.fold_with(folder), index: index.fold_with(folder) }
64 Overflow(op
, l
, r
) => Overflow(*op
, l
.fold_with(folder
), r
.fold_with(folder
)),
65 OverflowNeg(op
) => OverflowNeg(op
.fold_with(folder
)),
66 DivisionByZero(op
) => DivisionByZero(op
.fold_with(folder
)),
67 RemainderByZero(op
) => RemainderByZero(op
.fold_with(folder
)),
68 ResumedAfterReturn(_
) | ResumedAfterPanic(_
) => msg
.clone(),
70 Assert { cond: cond.fold_with(folder), expected, msg, target, cleanup }
72 GeneratorDrop
=> GeneratorDrop
,
76 Unreachable
=> Unreachable
,
77 FalseEdge { real_target, imaginary_target }
=> {
78 FalseEdge { real_target, imaginary_target }
80 FalseUnwind { real_target, unwind }
=> FalseUnwind { real_target, unwind }
,
81 InlineAsm { template, ref operands, options, line_spans, destination }
=> InlineAsm
{
83 operands
: operands
.fold_with(folder
),
89 Terminator { source_info: self.source_info, kind }
92 fn super_visit_with
<V
: TypeVisitor
<'tcx
>>(&self, visitor
: &mut V
) -> bool
{
93 use crate::mir
::TerminatorKind
::*;
96 SwitchInt { ref discr, switch_ty, .. }
=> {
97 discr
.visit_with(visitor
) || switch_ty
.visit_with(visitor
)
99 Drop { ref place, .. }
=> place
.visit_with(visitor
),
100 DropAndReplace { ref place, ref value, .. }
=> {
101 place
.visit_with(visitor
) || value
.visit_with(visitor
)
103 Yield { ref value, .. }
=> value
.visit_with(visitor
),
104 Call { ref func, ref args, ref destination, .. }
=> {
105 let dest
= if let Some((ref loc
, _
)) = *destination
{
106 loc
.visit_with(visitor
)
110 dest
|| func
.visit_with(visitor
) || args
.visit_with(visitor
)
112 Assert { ref cond, ref msg, .. }
=> {
113 if cond
.visit_with(visitor
) {
116 BoundsCheck { ref len, ref index }
=> {
117 len
.visit_with(visitor
) || index
.visit_with(visitor
)
119 Overflow(_
, l
, r
) => l
.visit_with(visitor
) || r
.visit_with(visitor
),
120 OverflowNeg(op
) | DivisionByZero(op
) | RemainderByZero(op
) => {
121 op
.visit_with(visitor
)
123 ResumedAfterReturn(_
) | ResumedAfterPanic(_
) => false,
129 InlineAsm { ref operands, .. }
=> operands
.visit_with(visitor
),
137 | FalseUnwind { .. }
=> false,
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
) -> bool
{
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
) -> bool
{
158 self.local
.visit_with(visitor
) || self.projection
.visit_with(visitor
)
162 impl<'tcx
> TypeFoldable
<'tcx
> for &'tcx ty
::List
<PlaceElem
<'tcx
>> {
163 fn super_fold_with
<F
: TypeFolder
<'tcx
>>(&self, folder
: &mut F
) -> Self {
164 let v
= self.iter().map(|t
| t
.fold_with(folder
)).collect
::<Vec
<_
>>();
165 folder
.tcx().intern_place_elems(&v
)
168 fn super_visit_with
<V
: TypeVisitor
<'tcx
>>(&self, visitor
: &mut V
) -> bool
{
169 self.iter().any(|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(ref op
) => Use(op
.fold_with(folder
)),
178 Repeat(ref op
, len
) => Repeat(op
.fold_with(folder
), len
),
179 ThreadLocalRef(did
) => ThreadLocalRef(did
.fold_with(folder
)),
180 Ref(region
, bk
, ref place
) => {
181 Ref(region
.fold_with(folder
), bk
, place
.fold_with(folder
))
183 AddressOf(mutability
, ref place
) => AddressOf(mutability
, place
.fold_with(folder
)),
184 Len(ref place
) => Len(place
.fold_with(folder
)),
185 Cast(kind
, ref op
, ty
) => Cast(kind
, op
.fold_with(folder
), ty
.fold_with(folder
)),
186 BinaryOp(op
, ref rhs
, ref lhs
) => {
187 BinaryOp(op
, rhs
.fold_with(folder
), lhs
.fold_with(folder
))
189 CheckedBinaryOp(op
, ref rhs
, ref lhs
) => {
190 CheckedBinaryOp(op
, rhs
.fold_with(folder
), lhs
.fold_with(folder
))
192 UnaryOp(op
, ref val
) => UnaryOp(op
, val
.fold_with(folder
)),
193 Discriminant(ref place
) => Discriminant(place
.fold_with(folder
)),
194 NullaryOp(op
, ty
) => NullaryOp(op
, ty
.fold_with(folder
)),
195 Aggregate(ref kind
, ref fields
) => {
196 let kind
= box match **kind
{
197 AggregateKind
::Array(ty
) => AggregateKind
::Array(ty
.fold_with(folder
)),
198 AggregateKind
::Tuple
=> AggregateKind
::Tuple
,
199 AggregateKind
::Adt(def
, v
, substs
, user_ty
, n
) => AggregateKind
::Adt(
202 substs
.fold_with(folder
),
203 user_ty
.fold_with(folder
),
206 AggregateKind
::Closure(id
, substs
) => {
207 AggregateKind
::Closure(id
, substs
.fold_with(folder
))
209 AggregateKind
::Generator(id
, substs
, movablity
) => {
210 AggregateKind
::Generator(id
, substs
.fold_with(folder
), movablity
)
213 Aggregate(kind
, fields
.fold_with(folder
))
218 fn super_visit_with
<V
: TypeVisitor
<'tcx
>>(&self, visitor
: &mut V
) -> bool
{
219 use crate::mir
::Rvalue
::*;
221 Use(ref op
) => op
.visit_with(visitor
),
222 Repeat(ref op
, _
) => op
.visit_with(visitor
),
223 ThreadLocalRef(did
) => did
.visit_with(visitor
),
224 Ref(region
, _
, ref place
) => region
.visit_with(visitor
) || place
.visit_with(visitor
),
225 AddressOf(_
, ref place
) => place
.visit_with(visitor
),
226 Len(ref place
) => place
.visit_with(visitor
),
227 Cast(_
, ref op
, ty
) => op
.visit_with(visitor
) || ty
.visit_with(visitor
),
228 BinaryOp(_
, ref rhs
, ref lhs
) | CheckedBinaryOp(_
, ref rhs
, ref lhs
) => {
229 rhs
.visit_with(visitor
) || lhs
.visit_with(visitor
)
231 UnaryOp(_
, ref val
) => val
.visit_with(visitor
),
232 Discriminant(ref place
) => place
.visit_with(visitor
),
233 NullaryOp(_
, ty
) => ty
.visit_with(visitor
),
234 Aggregate(ref kind
, ref fields
) => {
236 AggregateKind
::Array(ty
) => ty
.visit_with(visitor
),
237 AggregateKind
::Tuple
=> false,
238 AggregateKind
::Adt(_
, _
, substs
, user_ty
, _
) => {
239 substs
.visit_with(visitor
) || user_ty
.visit_with(visitor
)
241 AggregateKind
::Closure(_
, substs
) => substs
.visit_with(visitor
),
242 AggregateKind
::Generator(_
, substs
, _
) => substs
.visit_with(visitor
),
243 }) || fields
.visit_with(visitor
)
249 impl<'tcx
> TypeFoldable
<'tcx
> for Operand
<'tcx
> {
250 fn super_fold_with
<F
: TypeFolder
<'tcx
>>(&self, folder
: &mut F
) -> Self {
252 Operand
::Copy(ref place
) => Operand
::Copy(place
.fold_with(folder
)),
253 Operand
::Move(ref place
) => Operand
::Move(place
.fold_with(folder
)),
254 Operand
::Constant(ref c
) => Operand
::Constant(c
.fold_with(folder
)),
258 fn super_visit_with
<V
: TypeVisitor
<'tcx
>>(&self, visitor
: &mut V
) -> bool
{
260 Operand
::Copy(ref place
) | Operand
::Move(ref place
) => place
.visit_with(visitor
),
261 Operand
::Constant(ref c
) => c
.visit_with(visitor
),
266 impl<'tcx
> TypeFoldable
<'tcx
> for PlaceElem
<'tcx
> {
267 fn super_fold_with
<F
: TypeFolder
<'tcx
>>(&self, folder
: &mut F
) -> Self {
268 use crate::mir
::ProjectionElem
::*;
272 Field(f
, ty
) => Field(f
, ty
.fold_with(folder
)),
273 Index(v
) => Index(v
.fold_with(folder
)),
274 Downcast(symbol
, variantidx
) => Downcast(symbol
, variantidx
),
275 ConstantIndex { offset, min_length, from_end }
=> {
276 ConstantIndex { offset, min_length, from_end }
278 Subslice { from, to, from_end }
=> Subslice { from, to, from_end }
,
282 fn super_visit_with
<Vs
: TypeVisitor
<'tcx
>>(&self, visitor
: &mut Vs
) -> bool
{
283 use crate::mir
::ProjectionElem
::*;
286 Field(_
, ty
) => ty
.visit_with(visitor
),
287 Index(v
) => v
.visit_with(visitor
),
293 impl<'tcx
> TypeFoldable
<'tcx
> for Field
{
294 fn super_fold_with
<F
: TypeFolder
<'tcx
>>(&self, _
: &mut F
) -> Self {
297 fn super_visit_with
<V
: TypeVisitor
<'tcx
>>(&self, _
: &mut V
) -> bool
{
302 impl<'tcx
> TypeFoldable
<'tcx
> for GeneratorSavedLocal
{
303 fn super_fold_with
<F
: TypeFolder
<'tcx
>>(&self, _
: &mut F
) -> Self {
306 fn super_visit_with
<V
: TypeVisitor
<'tcx
>>(&self, _
: &mut V
) -> bool
{
311 impl<'tcx
, R
: Idx
, C
: Idx
> TypeFoldable
<'tcx
> for BitMatrix
<R
, C
> {
312 fn super_fold_with
<F
: TypeFolder
<'tcx
>>(&self, _
: &mut F
) -> Self {
315 fn super_visit_with
<V
: TypeVisitor
<'tcx
>>(&self, _
: &mut V
) -> bool
{
320 impl<'tcx
> TypeFoldable
<'tcx
> for Constant
<'tcx
> {
321 fn super_fold_with
<F
: TypeFolder
<'tcx
>>(&self, folder
: &mut F
) -> Self {
324 user_ty
: self.user_ty
.fold_with(folder
),
325 literal
: self.literal
.fold_with(folder
),
328 fn super_visit_with
<V
: TypeVisitor
<'tcx
>>(&self, visitor
: &mut V
) -> bool
{
329 self.literal
.visit_with(visitor
)