]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/mir/type_visitable.rs
derive various Lift impl instead of hand rolling them
[rust.git] / compiler / rustc_middle / src / mir / type_visitable.rs
1 //! `TypeVisitable` implementations for MIR types
2
3 use super::*;
4 use crate::ty;
5
6 impl<'tcx> TypeVisitable<'tcx> for Terminator<'tcx> {
7     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
8         use crate::mir::TerminatorKind::*;
9
10         match self.kind {
11             SwitchInt { ref discr, switch_ty, .. } => {
12                 discr.visit_with(visitor)?;
13                 switch_ty.visit_with(visitor)
14             }
15             Drop { ref place, .. } => place.visit_with(visitor),
16             DropAndReplace { ref place, ref value, .. } => {
17                 place.visit_with(visitor)?;
18                 value.visit_with(visitor)
19             }
20             Yield { ref value, .. } => value.visit_with(visitor),
21             Call { ref func, ref args, ref destination, .. } => {
22                 destination.visit_with(visitor)?;
23                 func.visit_with(visitor)?;
24                 args.visit_with(visitor)
25             }
26             Assert { ref cond, ref msg, .. } => {
27                 cond.visit_with(visitor)?;
28                 use AssertKind::*;
29                 match msg {
30                     BoundsCheck { ref len, ref index } => {
31                         len.visit_with(visitor)?;
32                         index.visit_with(visitor)
33                     }
34                     Overflow(_, l, r) => {
35                         l.visit_with(visitor)?;
36                         r.visit_with(visitor)
37                     }
38                     OverflowNeg(op) | DivisionByZero(op) | RemainderByZero(op) => {
39                         op.visit_with(visitor)
40                     }
41                     ResumedAfterReturn(_) | ResumedAfterPanic(_) => ControlFlow::CONTINUE,
42                 }
43             }
44             InlineAsm { ref operands, .. } => operands.visit_with(visitor),
45             Goto { .. }
46             | Resume
47             | Abort
48             | Return
49             | GeneratorDrop
50             | Unreachable
51             | FalseEdge { .. }
52             | FalseUnwind { .. } => ControlFlow::CONTINUE,
53         }
54     }
55 }
56
57 impl<'tcx> TypeVisitable<'tcx> for GeneratorKind {
58     fn visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
59         ControlFlow::CONTINUE
60     }
61 }
62
63 impl<'tcx> TypeVisitable<'tcx> for Place<'tcx> {
64     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
65         self.local.visit_with(visitor)?;
66         self.projection.visit_with(visitor)
67     }
68 }
69
70 impl<'tcx> TypeVisitable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
71     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
72         self.iter().try_for_each(|t| t.visit_with(visitor))
73     }
74 }
75
76 impl<'tcx> TypeVisitable<'tcx> for Rvalue<'tcx> {
77     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
78         use crate::mir::Rvalue::*;
79         match *self {
80             Use(ref op) => op.visit_with(visitor),
81             CopyForDeref(ref place) => {
82                 let op = &Operand::Copy(*place);
83                 op.visit_with(visitor)
84             }
85             Repeat(ref op, _) => op.visit_with(visitor),
86             ThreadLocalRef(did) => did.visit_with(visitor),
87             Ref(region, _, ref place) => {
88                 region.visit_with(visitor)?;
89                 place.visit_with(visitor)
90             }
91             AddressOf(_, ref place) => place.visit_with(visitor),
92             Len(ref place) => place.visit_with(visitor),
93             Cast(_, ref op, ty) => {
94                 op.visit_with(visitor)?;
95                 ty.visit_with(visitor)
96             }
97             BinaryOp(_, box (ref rhs, ref lhs)) | CheckedBinaryOp(_, box (ref rhs, ref lhs)) => {
98                 rhs.visit_with(visitor)?;
99                 lhs.visit_with(visitor)
100             }
101             UnaryOp(_, ref val) => val.visit_with(visitor),
102             Discriminant(ref place) => place.visit_with(visitor),
103             NullaryOp(_, ty) => ty.visit_with(visitor),
104             Aggregate(ref kind, ref fields) => {
105                 match **kind {
106                     AggregateKind::Array(ty) => {
107                         ty.visit_with(visitor)?;
108                     }
109                     AggregateKind::Tuple => {}
110                     AggregateKind::Adt(_, _, substs, user_ty, _) => {
111                         substs.visit_with(visitor)?;
112                         user_ty.visit_with(visitor)?;
113                     }
114                     AggregateKind::Closure(_, substs) => {
115                         substs.visit_with(visitor)?;
116                     }
117                     AggregateKind::Generator(_, substs, _) => {
118                         substs.visit_with(visitor)?;
119                     }
120                 }
121                 fields.visit_with(visitor)
122             }
123             ShallowInitBox(ref op, ty) => {
124                 op.visit_with(visitor)?;
125                 ty.visit_with(visitor)
126             }
127         }
128     }
129 }
130
131 impl<'tcx> TypeVisitable<'tcx> for Operand<'tcx> {
132     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
133         match *self {
134             Operand::Copy(ref place) | Operand::Move(ref place) => place.visit_with(visitor),
135             Operand::Constant(ref c) => c.visit_with(visitor),
136         }
137     }
138 }
139
140 impl<'tcx> TypeVisitable<'tcx> for PlaceElem<'tcx> {
141     fn visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> ControlFlow<Vs::BreakTy> {
142         use crate::mir::ProjectionElem::*;
143
144         match self {
145             Field(_, ty) => ty.visit_with(visitor),
146             Index(v) => v.visit_with(visitor),
147             _ => ControlFlow::CONTINUE,
148         }
149     }
150 }
151
152 impl<'tcx> TypeVisitable<'tcx> for GeneratorSavedLocal {
153     fn visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
154         ControlFlow::CONTINUE
155     }
156 }
157
158 impl<'tcx, R: Idx, C: Idx> TypeVisitable<'tcx> for BitMatrix<R, C> {
159     fn visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
160         ControlFlow::CONTINUE
161     }
162 }
163
164 impl<'tcx> TypeVisitable<'tcx> for Constant<'tcx> {
165     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
166         self.literal.visit_with(visitor)?;
167         self.user_ty.visit_with(visitor)
168     }
169 }
170
171 impl<'tcx> TypeVisitable<'tcx> for ConstantKind<'tcx> {
172     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
173         visitor.visit_mir_const(*self)
174     }
175 }
176
177 impl<'tcx> TypeSuperVisitable<'tcx> for ConstantKind<'tcx> {
178     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
179         match *self {
180             ConstantKind::Ty(c) => c.visit_with(visitor),
181             ConstantKind::Val(_, t) => t.visit_with(visitor),
182         }
183     }
184 }