stable_mir/
visitor.rs
1use std::ops::ControlFlow;
2
3use super::ty::{
4 Allocation, Binder, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs,
5 MirConst, Promoted, Region, RigidTy, TermKind, Ty, UnevaluatedConst,
6};
7use crate::Opaque;
8use crate::ty::TyConst;
9
10pub trait Visitor: Sized {
11 type Break;
12 fn visit_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break> {
13 ty.super_visit(self)
14 }
15 fn visit_const(&mut self, c: &TyConst) -> ControlFlow<Self::Break> {
16 c.super_visit(self)
17 }
18 fn visit_reg(&mut self, reg: &Region) -> ControlFlow<Self::Break> {
19 reg.super_visit(self)
20 }
21}
22
23pub trait Visitable {
24 fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
25 self.super_visit(visitor)
26 }
27 fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break>;
28}
29
30impl Visitable for Ty {
31 fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
32 visitor.visit_ty(self)
33 }
34 fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
35 match self.kind() {
36 super::ty::TyKind::RigidTy(ty) => ty.visit(visitor)?,
37 super::ty::TyKind::Alias(_, alias) => alias.args.visit(visitor)?,
38 super::ty::TyKind::Param(_) | super::ty::TyKind::Bound(_, _) => {}
39 }
40 ControlFlow::Continue(())
41 }
42}
43
44impl Visitable for TyConst {
45 fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
46 visitor.visit_const(self)
47 }
48 fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
49 match &self.kind {
50 crate::ty::TyConstKind::Param(_) | crate::ty::TyConstKind::Bound(_, _) => {}
51 crate::ty::TyConstKind::Unevaluated(_, args) => args.visit(visitor)?,
52 crate::ty::TyConstKind::Value(ty, alloc) => {
53 alloc.visit(visitor)?;
54 ty.visit(visitor)?;
55 }
56 crate::ty::TyConstKind::ZSTValue(ty) => ty.visit(visitor)?,
57 }
58 ControlFlow::Continue(())
59 }
60}
61
62impl Visitable for MirConst {
63 fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
64 self.super_visit(visitor)
65 }
66 fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
67 match &self.kind() {
68 super::ty::ConstantKind::Ty(ct) => ct.visit(visitor)?,
69 super::ty::ConstantKind::Allocated(alloc) => alloc.visit(visitor)?,
70 super::ty::ConstantKind::Unevaluated(uv) => uv.visit(visitor)?,
71 super::ty::ConstantKind::Param(_) | super::ty::ConstantKind::ZeroSized => {}
72 }
73 self.ty().visit(visitor)
74 }
75}
76
77impl Visitable for Opaque {
78 fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
79 ControlFlow::Continue(())
80 }
81}
82
83impl Visitable for Allocation {
84 fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
85 ControlFlow::Continue(())
86 }
87}
88
89impl Visitable for UnevaluatedConst {
90 fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
91 let UnevaluatedConst { def, args, promoted } = self;
92 def.visit(visitor)?;
93 args.visit(visitor)?;
94 promoted.visit(visitor)
95 }
96}
97
98impl Visitable for ConstDef {
99 fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
100 ControlFlow::Continue(())
101 }
102}
103
104impl<T: Visitable> Visitable for Option<T> {
105 fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
106 match self {
107 Some(val) => val.visit(visitor),
108 None => ControlFlow::Continue(()),
109 }
110 }
111}
112
113impl Visitable for Promoted {
114 fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
115 ControlFlow::Continue(())
116 }
117}
118
119impl Visitable for GenericArgs {
120 fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
121 self.0.visit(visitor)
122 }
123}
124
125impl Visitable for Region {
126 fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
127 visitor.visit_reg(self)
128 }
129
130 fn super_visit<V: Visitor>(&self, _: &mut V) -> ControlFlow<V::Break> {
131 ControlFlow::Continue(())
132 }
133}
134
135impl Visitable for GenericArgKind {
136 fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
137 match self {
138 GenericArgKind::Lifetime(lt) => lt.visit(visitor),
139 GenericArgKind::Type(t) => t.visit(visitor),
140 GenericArgKind::Const(c) => c.visit(visitor),
141 }
142 }
143}
144
145impl Visitable for RigidTy {
146 fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
147 match self {
148 RigidTy::Bool
149 | RigidTy::Char
150 | RigidTy::Int(_)
151 | RigidTy::Uint(_)
152 | RigidTy::Float(_)
153 | RigidTy::Never
154 | RigidTy::Foreign(_)
155 | RigidTy::Str => ControlFlow::Continue(()),
156 RigidTy::Array(t, c) => {
157 t.visit(visitor)?;
158 c.visit(visitor)
159 }
160 RigidTy::Pat(t, _p) => t.visit(visitor),
161 RigidTy::Slice(inner) => inner.visit(visitor),
162 RigidTy::RawPtr(ty, _) => ty.visit(visitor),
163 RigidTy::Ref(reg, ty, _) => {
164 reg.visit(visitor);
165 ty.visit(visitor)
166 }
167 RigidTy::Adt(_, args)
168 | RigidTy::Closure(_, args)
169 | RigidTy::Coroutine(_, args, _)
170 | RigidTy::CoroutineWitness(_, args)
171 | RigidTy::CoroutineClosure(_, args)
172 | RigidTy::FnDef(_, args) => args.visit(visitor),
173 RigidTy::FnPtr(sig) => sig.visit(visitor),
174 RigidTy::Dynamic(pred, r, _) => {
175 pred.visit(visitor)?;
176 r.visit(visitor)
177 }
178 RigidTy::Tuple(fields) => fields.visit(visitor),
179 }
180 }
181}
182
183impl<T: Visitable> Visitable for Vec<T> {
184 fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
185 for arg in self {
186 arg.visit(visitor)?;
187 }
188 ControlFlow::Continue(())
189 }
190}
191
192impl<T: Visitable> Visitable for Binder<T> {
193 fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
194 self.value.visit(visitor)
195 }
196}
197
198impl Visitable for ExistentialPredicate {
199 fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
200 match self {
201 ExistentialPredicate::Trait(tr) => tr.generic_args.visit(visitor),
202 ExistentialPredicate::Projection(p) => {
203 p.term.visit(visitor)?;
204 p.generic_args.visit(visitor)
205 }
206 ExistentialPredicate::AutoTrait(_) => ControlFlow::Continue(()),
207 }
208 }
209}
210
211impl Visitable for TermKind {
212 fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
213 match self {
214 TermKind::Type(t) => t.visit(visitor),
215 TermKind::Const(c) => c.visit(visitor),
216 }
217 }
218}
219
220impl Visitable for FnSig {
221 fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
222 self.inputs_and_output.visit(visitor)
223 }
224}