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