Skip to content

Commit 5516b32

Browse files
committed
emit basic smir
1 parent d42d73b commit 5516b32

File tree

7 files changed

+160
-5
lines changed

7 files changed

+160
-5
lines changed

compiler/rustc_driver_impl/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ rustc_query_system = { path = "../rustc_query_system" }
4444
rustc_resolve = { path = "../rustc_resolve" }
4545
rustc_session = { path = "../rustc_session" }
4646
rustc_span = { path = "../rustc_span" }
47+
rustc_smir ={ path = "../rustc_smir" }
4748
rustc_symbol_mangling = { path = "../rustc_symbol_mangling" }
4849
rustc_target = { path = "../rustc_target" }
4950
rustc_trait_selection = { path = "../rustc_trait_selection" }

compiler/rustc_driver_impl/src/pretty.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use rustc_middle::mir::{write_mir_graphviz, write_mir_pretty};
99
use rustc_middle::ty::{self, TyCtxt};
1010
use rustc_session::config::{OutFileName, PpHirMode, PpMode, PpSourceMode};
1111
use rustc_session::Session;
12+
use rustc_smir::rustc_internal::pretty::write_smir_pretty;
1213
use rustc_span::symbol::Ident;
1314
use rustc_span::FileName;
1415

@@ -325,6 +326,11 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) {
325326
write_mir_graphviz(ex.tcx(), None, &mut out).unwrap();
326327
String::from_utf8(out).unwrap()
327328
}
329+
Smir => {
330+
let mut out = Vec::new();
331+
write_smir_pretty(ex.tcx(), &mut out).unwrap();
332+
String::from_utf8(out).unwrap()
333+
}
328334
ThirTree => {
329335
let tcx = ex.tcx();
330336
let mut out = String::new();

compiler/rustc_session/src/config.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2926,6 +2926,7 @@ fn parse_pretty(handler: &EarlyErrorHandler, unstable_opts: &UnstableOptions) ->
29262926
"thir-tree" => ThirTree,
29272927
"thir-flat" => ThirFlat,
29282928
"mir" => Mir,
2929+
"smir" => Smir,
29292930
"mir-cfg" => MirCFG,
29302931
name => handler.early_error(format!(
29312932
"argument to `unpretty` must be one of `normal`, `identified`, \
@@ -3106,6 +3107,8 @@ pub enum PpMode {
31063107
Mir,
31073108
/// `-Zunpretty=mir-cfg`
31083109
MirCFG,
3110+
/// `-Zunpretty=smir`
3111+
Smir,
31093112
}
31103113

31113114
impl PpMode {
@@ -3122,21 +3125,22 @@ impl PpMode {
31223125
| ThirTree
31233126
| ThirFlat
31243127
| Mir
3125-
| MirCFG => true,
3128+
| MirCFG
3129+
| Smir => true,
31263130
}
31273131
}
31283132
pub fn needs_hir(&self) -> bool {
31293133
use PpMode::*;
31303134
match *self {
31313135
Source(_) | AstTree | AstTreeExpanded => false,
31323136

3133-
Hir(_) | HirTree | ThirTree | ThirFlat | Mir | MirCFG => true,
3137+
Hir(_) | HirTree | ThirTree | ThirFlat | Mir | MirCFG | Smir => true,
31343138
}
31353139
}
31363140

31373141
pub fn needs_analysis(&self) -> bool {
31383142
use PpMode::*;
3139-
matches!(*self, Hir(PpHirMode::Typed) | Mir | MirCFG | ThirTree | ThirFlat)
3143+
matches!(*self, Hir(PpHirMode::Typed) | Mir | Smir | MirCFG | ThirTree | ThirFlat)
31403144
}
31413145
}
31423146

compiler/rustc_smir/src/rustc_internal/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use std::hash::Hash;
2020
use std::ops::Index;
2121

2222
mod internal;
23+
pub mod pretty;
2324

2425
pub fn stable<'tcx, S: Stable<'tcx>>(item: &S) -> S::T {
2526
with_tables(|tables| item.stable(tables))
@@ -289,4 +290,10 @@ impl<K: PartialEq + Hash + Eq, V: Copy + Debug + PartialEq + IndexedVal> Index<V
289290
pub trait RustcInternal<'tcx> {
290291
type T;
291292
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T;
293+
294+
/// Use this when you want to convert to a rustc counterpart in user-code.
295+
/// Do not use this within the smir crates themselves.
296+
fn internal_via_tls(&self) -> Self::T {
297+
with_tables(|tables| self.internal(tables))
298+
}
292299
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
use std::io;
2+
3+
use rustc_middle::ty::TyCtxt;
4+
use stable_mir::{
5+
ty::{RigidTy, TyKind},
6+
CrateItem, mir::Mutability,
7+
};
8+
9+
10+
use super::{run, RustcInternal};
11+
12+
pub fn write_smir_pretty<'tcx>(tcx: TyCtxt<'tcx>, w: &mut dyn io::Write) -> io::Result<()> {
13+
run(tcx, || {
14+
let items = stable_mir::all_local_items();
15+
items.iter().for_each(|item| {
16+
// Because we can't return a Result from a closure, we have to unwrap here.
17+
writeln!(w, "{}", function_name(*item,tcx)).unwrap();
18+
writeln!(w, "{}", function_body(*item,tcx)).unwrap();
19+
})
20+
});
21+
Ok(())
22+
}
23+
24+
pub fn function_name(item: CrateItem,tcx: TyCtxt<'_>) -> String {
25+
let mut name = String::new();
26+
let body = item.body();
27+
name.push_str("fn ");
28+
name.push_str(item.name().as_str());
29+
if body.arg_locals().is_empty() {
30+
name.push_str("()");
31+
}else{
32+
name.push_str("(");
33+
}
34+
body.arg_locals().iter().for_each(|local| {
35+
name.push_str(format!("_{}: ",local.local).as_str());
36+
name.push_str(&pretty_ty(local.ty.kind(), tcx));
37+
});
38+
if !body.arg_locals().is_empty() {
39+
name.push_str(")");
40+
}
41+
let return_local = body.ret_local();
42+
name.push_str(" -> ");
43+
name.push_str(&pretty_ty(return_local.ty.kind(), tcx));
44+
name.push_str(" {");
45+
name
46+
}
47+
48+
pub fn function_body(item: CrateItem,_tcx: TyCtxt<'_>) -> String {
49+
let mut body_str = String::new();
50+
let body = item.body();
51+
body.inner_locals().iter().for_each(|local| {
52+
body_str.push_str(" ");
53+
body_str.push_str(format!("let {}",ret_mutability(&local.mutability)).as_str());
54+
body_str.push_str(format!("_{}: ",local.local).as_str());
55+
body_str.push_str(format!("{}",pretty_ty(local.ty.kind(), _tcx)).as_str());
56+
body_str.push_str(";\n");
57+
58+
});
59+
body_str.push_str("}");
60+
body_str
61+
62+
}
63+
64+
pub fn ret_mutability(mutability: &Mutability) -> String {
65+
match mutability {
66+
Mutability::Not => "".to_string(),
67+
Mutability::Mut => "mut ".to_string(),
68+
}
69+
}
70+
71+
pub fn pretty_ty<'tcx>(ty: TyKind,tcx: TyCtxt<'tcx>) -> String {
72+
let mut pretty = String::new();
73+
pretty.push_str("");
74+
match ty {
75+
TyKind::RigidTy(rigid_ty) => match rigid_ty {
76+
RigidTy::Bool => "bool".to_string(),
77+
RigidTy::Char => "char".to_string(),
78+
RigidTy::Int(i) => match i {
79+
stable_mir::ty::IntTy::Isize => "isize".to_string(),
80+
stable_mir::ty::IntTy::I8 => "i8".to_string(),
81+
stable_mir::ty::IntTy::I16 => "i16".to_string(),
82+
stable_mir::ty::IntTy::I32 => "i32".to_string(),
83+
stable_mir::ty::IntTy::I64 => "i64".to_string(),
84+
stable_mir::ty::IntTy::I128 => "i128".to_string(),
85+
},
86+
RigidTy::Uint(u) => match u {
87+
stable_mir::ty::UintTy::Usize => "usize".to_string(),
88+
stable_mir::ty::UintTy::U8 => "u8".to_string(),
89+
stable_mir::ty::UintTy::U16 => "u16".to_string(),
90+
stable_mir::ty::UintTy::U32 => "u32".to_string(),
91+
stable_mir::ty::UintTy::U64 => "u64".to_string(),
92+
stable_mir::ty::UintTy::U128 => "u128".to_string(),
93+
},
94+
RigidTy::Float(f) => match f {
95+
stable_mir::ty::FloatTy::F32 => "f32".to_string(),
96+
stable_mir::ty::FloatTy::F64 => "f64".to_string(),
97+
},
98+
RigidTy::Adt(def, _) => format!("{:#?}", tcx.type_of(def.0.internal_via_tls()).instantiate_identity()),
99+
RigidTy::Foreign(_) => format!("{:#?}", rigid_ty),
100+
RigidTy::Str => "str".to_string(),
101+
RigidTy::Array(_ty, len) => {
102+
format!("[{};{:#?}]", 1,len.internal_via_tls())},
103+
RigidTy::Slice(ty) => pretty_ty(ty.kind(),tcx),
104+
RigidTy::RawPtr(_, _) => format!("{:#?}", rigid_ty),
105+
RigidTy::Ref(_, ty, _) => pretty_ty(ty.kind(),tcx),
106+
RigidTy::FnDef(_, _) => format!("{:#?}", rigid_ty),
107+
RigidTy::FnPtr(_) => format!("{:#?}", rigid_ty),
108+
RigidTy::Closure(_, _) => format!("{:#?}", rigid_ty),
109+
RigidTy::Coroutine(_, _, _) => format!("{:#?}", rigid_ty),
110+
RigidTy::Dynamic(_, _, _) => format!("{:#?}", rigid_ty),
111+
RigidTy::Never => "!".to_string(),
112+
RigidTy::Tuple(tuple) => {
113+
if tuple.is_empty(){
114+
"()".to_string()
115+
}else {
116+
let mut tuple_str = String::new();
117+
tuple_str.push_str("(");
118+
tuple.iter().enumerate().for_each(|(i,ty)| {
119+
tuple_str.push_str(&pretty_ty(ty.kind(),tcx));
120+
if i != tuple.len() - 1 {
121+
tuple_str.push_str(", ");
122+
}
123+
});
124+
tuple_str.push_str(")");
125+
tuple_str
126+
}
127+
},
128+
},
129+
TyKind::Alias(_, _) => format!("{:#?}", ty),
130+
TyKind::Param(_) => format!("{:#?}", ty),
131+
TyKind::Bound(_, _) => format!("{:#?}", ty),
132+
}
133+
}

compiler/rustc_smir/src/rustc_smir/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,10 +306,12 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
306306
})
307307
.collect(),
308308
self.local_decls
309-
.iter()
310-
.map(|decl| stable_mir::mir::LocalDecl {
309+
.iter_enumerated()
310+
.map(|(local, decl)| stable_mir::mir::LocalDecl {
311311
ty: decl.ty.stable(tables),
312312
span: decl.source_info.span.stable(tables),
313+
local: local.as_usize(),
314+
mutability: decl.mutability.stable(tables),
313315
})
314316
.collect(),
315317
self.arg_count,

compiler/stable_mir/src/mir/body.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ type LocalDecls = Vec<LocalDecl>;
6464
pub struct LocalDecl {
6565
pub ty: Ty,
6666
pub span: Span,
67+
pub local: Local,
68+
pub mutability: Mutability,
6769
}
6870

6971
#[derive(Clone, Debug)]

0 commit comments

Comments
 (0)