Skip to content

Commit cdc8aa3

Browse files
authored
Rollup merge of #115444 - oli-obk:smir_visitor, r=spastorino
Create a SMIR visitor r? ``@spastorino`` Doesn't have tests or examples yet, but I think we could land it and implement it for the rest of the types.
2 parents 43e1561 + 85a1679 commit cdc8aa3

File tree

3 files changed

+202
-3
lines changed

3 files changed

+202
-3
lines changed

compiler/rustc_smir/src/rustc_internal/mod.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
66
use std::fmt::Debug;
77
use std::ops::Index;
8-
use std::string::ToString;
98

109
use crate::rustc_internal;
1110
use crate::{
@@ -156,10 +155,23 @@ pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
156155
}
157156

158157
/// A type that provides internal information but that can still be used for debug purpose.
159-
pub type Opaque = impl Debug + ToString + Clone;
158+
#[derive(Clone)]
159+
pub struct Opaque(String);
160+
161+
impl std::fmt::Display for Opaque {
162+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
163+
write!(f, "{}", self.0)
164+
}
165+
}
166+
167+
impl std::fmt::Debug for Opaque {
168+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
169+
write!(f, "{:?}", self.0)
170+
}
171+
}
160172

161173
pub(crate) fn opaque<T: Debug>(value: &T) -> Opaque {
162-
format!("{value:?}")
174+
Opaque(format!("{value:?}"))
163175
}
164176

165177
pub struct StableMir {

compiler/rustc_smir/src/stable_mir/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use crate::rustc_smir::Tables;
2020

2121
pub mod mir;
2222
pub mod ty;
23+
pub mod visitor;
2324

2425
/// Use String for now but we should replace it.
2526
pub type Symbol = String;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
use std::ops::ControlFlow;
2+
3+
use crate::rustc_internal::Opaque;
4+
5+
use super::ty::{
6+
Allocation, Binder, Const, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs,
7+
Promoted, RigidTy, TermKind, Ty, UnevaluatedConst,
8+
};
9+
10+
pub 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: &Const) -> ControlFlow<Self::Break> {
16+
c.super_visit(self)
17+
}
18+
}
19+
20+
pub trait Visitable {
21+
fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
22+
self.super_visit(visitor)
23+
}
24+
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break>;
25+
}
26+
27+
impl Visitable for Ty {
28+
fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
29+
visitor.visit_ty(self)
30+
}
31+
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
32+
match self.kind() {
33+
super::ty::TyKind::RigidTy(ty) => ty.visit(visitor),
34+
super::ty::TyKind::Alias(_, alias) => alias.args.visit(visitor),
35+
super::ty::TyKind::Param(_) => todo!(),
36+
super::ty::TyKind::Bound(_, _) => todo!(),
37+
}
38+
}
39+
}
40+
41+
impl Visitable for Const {
42+
fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
43+
visitor.visit_const(self)
44+
}
45+
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
46+
match &self.literal {
47+
super::ty::ConstantKind::Allocated(alloc) => alloc.visit(visitor),
48+
super::ty::ConstantKind::Unevaluated(uv) => uv.visit(visitor),
49+
super::ty::ConstantKind::ParamCt(param) => param.visit(visitor),
50+
}
51+
}
52+
}
53+
54+
impl Visitable for Opaque {
55+
fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
56+
ControlFlow::Continue(())
57+
}
58+
}
59+
60+
impl Visitable for Allocation {
61+
fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
62+
ControlFlow::Continue(())
63+
}
64+
}
65+
66+
impl Visitable for UnevaluatedConst {
67+
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
68+
let UnevaluatedConst { ty, def, args, promoted } = self;
69+
ty.visit(visitor)?;
70+
def.visit(visitor)?;
71+
args.visit(visitor)?;
72+
promoted.visit(visitor)
73+
}
74+
}
75+
76+
impl Visitable for ConstDef {
77+
fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
78+
ControlFlow::Continue(())
79+
}
80+
}
81+
82+
impl<T: Visitable> Visitable for Option<T> {
83+
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
84+
match self {
85+
Some(val) => val.visit(visitor),
86+
None => ControlFlow::Continue(()),
87+
}
88+
}
89+
}
90+
91+
impl Visitable for Promoted {
92+
fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
93+
ControlFlow::Continue(())
94+
}
95+
}
96+
97+
impl Visitable for GenericArgs {
98+
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
99+
self.0.visit(visitor)
100+
}
101+
}
102+
103+
impl Visitable for GenericArgKind {
104+
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
105+
match self {
106+
GenericArgKind::Lifetime(lt) => lt.visit(visitor),
107+
GenericArgKind::Type(t) => t.visit(visitor),
108+
GenericArgKind::Const(c) => c.visit(visitor),
109+
}
110+
}
111+
}
112+
113+
impl Visitable for RigidTy {
114+
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
115+
match self {
116+
RigidTy::Bool
117+
| RigidTy::Char
118+
| RigidTy::Int(_)
119+
| RigidTy::Uint(_)
120+
| RigidTy::Float(_)
121+
| RigidTy::Never
122+
| RigidTy::Foreign(_)
123+
| RigidTy::Str => ControlFlow::Continue(()),
124+
RigidTy::Array(t, c) => {
125+
t.visit(visitor)?;
126+
c.visit(visitor)
127+
}
128+
RigidTy::Slice(inner) => inner.visit(visitor),
129+
RigidTy::RawPtr(ty, _) => ty.visit(visitor),
130+
RigidTy::Ref(_, ty, _) => ty.visit(visitor),
131+
RigidTy::FnDef(_, args) => args.visit(visitor),
132+
RigidTy::FnPtr(sig) => sig.visit(visitor),
133+
RigidTy::Closure(_, args) => args.visit(visitor),
134+
RigidTy::Generator(_, args, _) => args.visit(visitor),
135+
RigidTy::Dynamic(pred, r, _) => {
136+
pred.visit(visitor)?;
137+
r.visit(visitor)
138+
}
139+
RigidTy::Tuple(fields) => fields.visit(visitor),
140+
RigidTy::Adt(_, args) => args.visit(visitor),
141+
}
142+
}
143+
}
144+
145+
impl<T: Visitable> Visitable for Vec<T> {
146+
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
147+
for arg in self {
148+
arg.visit(visitor)?;
149+
}
150+
ControlFlow::Continue(())
151+
}
152+
}
153+
154+
impl<T: Visitable> Visitable for Binder<T> {
155+
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
156+
self.value.visit(visitor)
157+
}
158+
}
159+
160+
impl Visitable for ExistentialPredicate {
161+
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
162+
match self {
163+
ExistentialPredicate::Trait(tr) => tr.generic_args.visit(visitor),
164+
ExistentialPredicate::Projection(p) => {
165+
p.term.visit(visitor)?;
166+
p.generic_args.visit(visitor)
167+
}
168+
ExistentialPredicate::AutoTrait(_) => ControlFlow::Continue(()),
169+
}
170+
}
171+
}
172+
173+
impl Visitable for TermKind {
174+
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
175+
match self {
176+
TermKind::Type(t) => t.visit(visitor),
177+
TermKind::Const(c) => c.visit(visitor),
178+
}
179+
}
180+
}
181+
182+
impl Visitable for FnSig {
183+
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
184+
self.inputs_and_output.visit(visitor)
185+
}
186+
}

0 commit comments

Comments
 (0)