Rollup merge of #117745 - ouz-a:emit_smir, r=celinval
Emit smir This adds ability to `-Zunpretty=smir` and get smir output of a Rust file, this is obliviously pretty basic compared to `mir` output but I think we could iteratively improve it, and even at this state this is useful for us. r? ``@celinval``
This commit is contained in:
commit
6227455345
@ -3815,6 +3815,7 @@ dependencies = [
|
|||||||
"rustc_query_system",
|
"rustc_query_system",
|
||||||
"rustc_resolve",
|
"rustc_resolve",
|
||||||
"rustc_session",
|
"rustc_session",
|
||||||
|
"rustc_smir",
|
||||||
"rustc_span",
|
"rustc_span",
|
||||||
"rustc_symbol_mangling",
|
"rustc_symbol_mangling",
|
||||||
"rustc_target",
|
"rustc_target",
|
||||||
|
@ -43,6 +43,7 @@ rustc_privacy = { path = "../rustc_privacy" }
|
|||||||
rustc_query_system = { path = "../rustc_query_system" }
|
rustc_query_system = { path = "../rustc_query_system" }
|
||||||
rustc_resolve = { path = "../rustc_resolve" }
|
rustc_resolve = { path = "../rustc_resolve" }
|
||||||
rustc_session = { path = "../rustc_session" }
|
rustc_session = { path = "../rustc_session" }
|
||||||
|
rustc_smir ={ path = "../rustc_smir" }
|
||||||
rustc_span = { path = "../rustc_span" }
|
rustc_span = { path = "../rustc_span" }
|
||||||
rustc_symbol_mangling = { path = "../rustc_symbol_mangling" }
|
rustc_symbol_mangling = { path = "../rustc_symbol_mangling" }
|
||||||
rustc_target = { path = "../rustc_target" }
|
rustc_target = { path = "../rustc_target" }
|
||||||
|
@ -9,6 +9,7 @@ use rustc_middle::mir::{write_mir_graphviz, write_mir_pretty};
|
|||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
use rustc_session::config::{OutFileName, PpHirMode, PpMode, PpSourceMode};
|
use rustc_session::config::{OutFileName, PpHirMode, PpMode, PpSourceMode};
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
|
use rustc_smir::rustc_internal::pretty::write_smir_pretty;
|
||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::Ident;
|
||||||
use rustc_span::FileName;
|
use rustc_span::FileName;
|
||||||
|
|
||||||
@ -325,6 +326,11 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) {
|
|||||||
write_mir_graphviz(ex.tcx(), None, &mut out).unwrap();
|
write_mir_graphviz(ex.tcx(), None, &mut out).unwrap();
|
||||||
String::from_utf8(out).unwrap()
|
String::from_utf8(out).unwrap()
|
||||||
}
|
}
|
||||||
|
StableMir => {
|
||||||
|
let mut out = Vec::new();
|
||||||
|
write_smir_pretty(ex.tcx(), &mut out).unwrap();
|
||||||
|
String::from_utf8(out).unwrap()
|
||||||
|
}
|
||||||
ThirTree => {
|
ThirTree => {
|
||||||
let tcx = ex.tcx();
|
let tcx = ex.tcx();
|
||||||
let mut out = String::new();
|
let mut out = String::new();
|
||||||
|
@ -2926,12 +2926,13 @@ fn parse_pretty(handler: &EarlyErrorHandler, unstable_opts: &UnstableOptions) ->
|
|||||||
"thir-tree" => ThirTree,
|
"thir-tree" => ThirTree,
|
||||||
"thir-flat" => ThirFlat,
|
"thir-flat" => ThirFlat,
|
||||||
"mir" => Mir,
|
"mir" => Mir,
|
||||||
|
"stable-mir" => StableMir,
|
||||||
"mir-cfg" => MirCFG,
|
"mir-cfg" => MirCFG,
|
||||||
name => handler.early_error(format!(
|
name => handler.early_error(format!(
|
||||||
"argument to `unpretty` must be one of `normal`, `identified`, \
|
"argument to `unpretty` must be one of `normal`, `identified`, \
|
||||||
`expanded`, `expanded,identified`, `expanded,hygiene`, \
|
`expanded`, `expanded,identified`, `expanded,hygiene`, \
|
||||||
`ast-tree`, `ast-tree,expanded`, `hir`, `hir,identified`, \
|
`ast-tree`, `ast-tree,expanded`, `hir`, `hir,identified`, \
|
||||||
`hir,typed`, `hir-tree`, `thir-tree`, `thir-flat`, `mir` or \
|
`hir,typed`, `hir-tree`, `thir-tree`, `thir-flat`, `mir`, `stable-mir`, or \
|
||||||
`mir-cfg`; got {name}"
|
`mir-cfg`; got {name}"
|
||||||
)),
|
)),
|
||||||
};
|
};
|
||||||
@ -3106,6 +3107,8 @@ pub enum PpMode {
|
|||||||
Mir,
|
Mir,
|
||||||
/// `-Zunpretty=mir-cfg`
|
/// `-Zunpretty=mir-cfg`
|
||||||
MirCFG,
|
MirCFG,
|
||||||
|
/// `-Zunpretty=stable-mir`
|
||||||
|
StableMir,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PpMode {
|
impl PpMode {
|
||||||
@ -3122,7 +3125,8 @@ impl PpMode {
|
|||||||
| ThirTree
|
| ThirTree
|
||||||
| ThirFlat
|
| ThirFlat
|
||||||
| Mir
|
| Mir
|
||||||
| MirCFG => true,
|
| MirCFG
|
||||||
|
| StableMir => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn needs_hir(&self) -> bool {
|
pub fn needs_hir(&self) -> bool {
|
||||||
@ -3130,13 +3134,13 @@ impl PpMode {
|
|||||||
match *self {
|
match *self {
|
||||||
Source(_) | AstTree | AstTreeExpanded => false,
|
Source(_) | AstTree | AstTreeExpanded => false,
|
||||||
|
|
||||||
Hir(_) | HirTree | ThirTree | ThirFlat | Mir | MirCFG => true,
|
Hir(_) | HirTree | ThirTree | ThirFlat | Mir | MirCFG | StableMir => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn needs_analysis(&self) -> bool {
|
pub fn needs_analysis(&self) -> bool {
|
||||||
use PpMode::*;
|
use PpMode::*;
|
||||||
matches!(*self, Hir(PpHirMode::Typed) | Mir | MirCFG | ThirTree | ThirFlat)
|
matches!(*self, Hir(PpHirMode::Typed) | Mir | StableMir | MirCFG | ThirTree | ThirFlat)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ use std::hash::Hash;
|
|||||||
use std::ops::Index;
|
use std::ops::Index;
|
||||||
|
|
||||||
mod internal;
|
mod internal;
|
||||||
|
pub mod pretty;
|
||||||
|
|
||||||
pub fn stable<'tcx, S: Stable<'tcx>>(item: S) -> S::T {
|
pub fn stable<'tcx, S: Stable<'tcx>>(item: S) -> S::T {
|
||||||
with_tables(|tables| item.stable(tables))
|
with_tables(|tables| item.stable(tables))
|
||||||
|
20
compiler/rustc_smir/src/rustc_internal/pretty.rs
Normal file
20
compiler/rustc_smir/src/rustc_internal/pretty.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use std::io;
|
||||||
|
|
||||||
|
use super::run;
|
||||||
|
use rustc_middle::ty::TyCtxt;
|
||||||
|
|
||||||
|
pub fn write_smir_pretty<'tcx, W: io::Write>(tcx: TyCtxt<'tcx>, w: &mut W) -> io::Result<()> {
|
||||||
|
writeln!(
|
||||||
|
w,
|
||||||
|
"// WARNING: This is highly experimental output it's intended for stable-mir developers only."
|
||||||
|
)?;
|
||||||
|
writeln!(
|
||||||
|
w,
|
||||||
|
"// If you find a bug or want to improve the output open a issue at https://github.com/rust-lang/project-stable-mir."
|
||||||
|
)?;
|
||||||
|
let _ = run(tcx, || {
|
||||||
|
let items = stable_mir::all_local_items();
|
||||||
|
let _ = items.iter().map(|item| -> io::Result<()> { item.dump(w) }).collect::<Vec<_>>();
|
||||||
|
});
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -7,7 +7,7 @@
|
|||||||
//!
|
//!
|
||||||
//! For now, we are developing everything inside `rustc`, thus, we keep this module private.
|
//! For now, we are developing everything inside `rustc`, thus, we keep this module private.
|
||||||
|
|
||||||
use crate::rustc_internal::{IndexMap, RustcInternal};
|
use crate::rustc_internal::{internal, IndexMap, RustcInternal};
|
||||||
use crate::rustc_smir::stable_mir::ty::{BoundRegion, Region};
|
use crate::rustc_smir::stable_mir::ty::{BoundRegion, Region};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
@ -105,6 +105,10 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
|
|||||||
tables.tcx.type_of(item.internal(&mut *tables)).instantiate_identity().stable(&mut *tables)
|
tables.tcx.type_of(item.internal(&mut *tables)).instantiate_identity().stable(&mut *tables)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn const_literal(&self, cnst: &stable_mir::ty::Const) -> String {
|
||||||
|
internal(cnst).to_string()
|
||||||
|
}
|
||||||
|
|
||||||
fn span_of_an_item(&self, def_id: stable_mir::DefId) -> Span {
|
fn span_of_an_item(&self, def_id: stable_mir::DefId) -> Span {
|
||||||
let mut tables = self.0.borrow_mut();
|
let mut tables = self.0.borrow_mut();
|
||||||
tables.tcx.def_span(tables[def_id]).stable(&mut *tables)
|
tables.tcx.def_span(tables[def_id]).stable(&mut *tables)
|
||||||
@ -404,6 +408,7 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
|
|||||||
.map(|decl| stable_mir::mir::LocalDecl {
|
.map(|decl| stable_mir::mir::LocalDecl {
|
||||||
ty: decl.ty.stable(tables),
|
ty: decl.ty.stable(tables),
|
||||||
span: decl.source_info.span.stable(tables),
|
span: decl.source_info.span.stable(tables),
|
||||||
|
mutability: decl.mutability.stable(tables),
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
self.arg_count,
|
self.arg_count,
|
||||||
|
@ -19,9 +19,9 @@
|
|||||||
|
|
||||||
use crate::mir::mono::InstanceDef;
|
use crate::mir::mono::InstanceDef;
|
||||||
use crate::mir::Body;
|
use crate::mir::Body;
|
||||||
use std::cell::Cell;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
use std::{cell::Cell, io};
|
||||||
|
|
||||||
use self::ty::{
|
use self::ty::{
|
||||||
GenericPredicates, Generics, ImplDef, ImplTrait, IndexedVal, LineInfo, Span, TraitDecl,
|
GenericPredicates, Generics, ImplDef, ImplTrait, IndexedVal, LineInfo, Span, TraitDecl,
|
||||||
@ -36,10 +36,12 @@ pub mod mir;
|
|||||||
pub mod ty;
|
pub mod ty;
|
||||||
pub mod visitor;
|
pub mod visitor;
|
||||||
|
|
||||||
|
use crate::mir::pretty::function_name;
|
||||||
|
use crate::mir::Mutability;
|
||||||
use crate::ty::{AdtDef, AdtKind, ClosureDef, ClosureKind};
|
use crate::ty::{AdtDef, AdtKind, ClosureDef, ClosureKind};
|
||||||
pub use error::*;
|
pub use error::*;
|
||||||
use mir::mono::Instance;
|
use mir::mono::Instance;
|
||||||
use ty::{FnDef, GenericArgs};
|
use ty::{Const, FnDef, GenericArgs};
|
||||||
|
|
||||||
/// Use String for now but we should replace it.
|
/// Use String for now but we should replace it.
|
||||||
pub type Symbol = String;
|
pub type Symbol = String;
|
||||||
@ -137,6 +139,11 @@ impl CrateItem {
|
|||||||
pub fn ty(&self) -> Ty {
|
pub fn ty(&self) -> Ty {
|
||||||
with(|cx| cx.def_ty(self.0))
|
with(|cx| cx.def_ty(self.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn dump<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
|
||||||
|
writeln!(w, "{}", function_name(*self))?;
|
||||||
|
self.body().dump(w)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the function where execution starts if the current
|
/// Return the function where execution starts if the current
|
||||||
@ -223,6 +230,9 @@ pub trait Context {
|
|||||||
/// Returns the type of given crate item.
|
/// Returns the type of given crate item.
|
||||||
fn def_ty(&self, item: DefId) -> Ty;
|
fn def_ty(&self, item: DefId) -> Ty;
|
||||||
|
|
||||||
|
/// Returns literal value of a const as a string.
|
||||||
|
fn const_literal(&self, cnst: &Const) -> String;
|
||||||
|
|
||||||
/// `Span` of an item
|
/// `Span` of an item
|
||||||
fn span_of_an_item(&self, def_id: DefId) -> Span;
|
fn span_of_an_item(&self, def_id: DefId) -> Span;
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
mod body;
|
mod body;
|
||||||
pub mod mono;
|
pub mod mono;
|
||||||
|
pub mod pretty;
|
||||||
pub mod visit;
|
pub mod visit;
|
||||||
|
|
||||||
pub use body::*;
|
pub use body::*;
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
|
use crate::mir::pretty::{function_body, pretty_statement};
|
||||||
use crate::ty::{AdtDef, ClosureDef, Const, CoroutineDef, GenericArgs, Movability, Region, Ty};
|
use crate::ty::{AdtDef, ClosureDef, Const, CoroutineDef, GenericArgs, Movability, Region, Ty};
|
||||||
use crate::Opaque;
|
use crate::Opaque;
|
||||||
use crate::Span;
|
use crate::Span;
|
||||||
|
use std::io;
|
||||||
/// The SMIR representation of a single function.
|
/// The SMIR representation of a single function.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Body {
|
pub struct Body {
|
||||||
@ -56,6 +57,28 @@ impl Body {
|
|||||||
pub fn locals(&self) -> &[LocalDecl] {
|
pub fn locals(&self) -> &[LocalDecl] {
|
||||||
&self.locals
|
&self.locals
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn dump<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
|
||||||
|
writeln!(w, "{}", function_body(self))?;
|
||||||
|
self.blocks
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(index, block)| -> io::Result<()> {
|
||||||
|
writeln!(w, " bb{}: {{", index)?;
|
||||||
|
let _ = block
|
||||||
|
.statements
|
||||||
|
.iter()
|
||||||
|
.map(|statement| -> io::Result<()> {
|
||||||
|
writeln!(w, "{}", pretty_statement(&statement.kind))?;
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
writeln!(w, " }}").unwrap();
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type LocalDecls = Vec<LocalDecl>;
|
type LocalDecls = Vec<LocalDecl>;
|
||||||
@ -64,6 +87,7 @@ type LocalDecls = Vec<LocalDecl>;
|
|||||||
pub struct LocalDecl {
|
pub struct LocalDecl {
|
||||||
pub ty: Ty,
|
pub ty: Ty,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
pub mutability: Mutability,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
258
compiler/stable_mir/src/mir/pretty.rs
Normal file
258
compiler/stable_mir/src/mir/pretty.rs
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
use crate::mir::{Operand, Rvalue, StatementKind};
|
||||||
|
use crate::ty::{DynKind, FloatTy, IntTy, RigidTy, TyKind, UintTy};
|
||||||
|
use crate::{with, Body, CrateItem, Mutability};
|
||||||
|
|
||||||
|
pub fn function_name(item: CrateItem) -> String {
|
||||||
|
let mut pretty_name = String::new();
|
||||||
|
let body = item.body();
|
||||||
|
pretty_name.push_str("fn ");
|
||||||
|
pretty_name.push_str(item.name().as_str());
|
||||||
|
if body.arg_locals().is_empty() {
|
||||||
|
pretty_name.push_str("()");
|
||||||
|
} else {
|
||||||
|
pretty_name.push_str("(");
|
||||||
|
}
|
||||||
|
body.arg_locals().iter().enumerate().for_each(|(index, local)| {
|
||||||
|
pretty_name.push_str(format!("_{}: ", index).as_str());
|
||||||
|
pretty_name.push_str(&pretty_ty(local.ty.kind()));
|
||||||
|
});
|
||||||
|
if !body.arg_locals().is_empty() {
|
||||||
|
pretty_name.push_str(")");
|
||||||
|
}
|
||||||
|
let return_local = body.ret_local();
|
||||||
|
pretty_name.push_str(" -> ");
|
||||||
|
pretty_name.push_str(&pretty_ty(return_local.ty.kind()));
|
||||||
|
pretty_name.push_str(" {");
|
||||||
|
pretty_name
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn function_body(body: &Body) -> String {
|
||||||
|
let mut pretty_body = String::new();
|
||||||
|
body.inner_locals().iter().enumerate().for_each(|(index, local)| {
|
||||||
|
pretty_body.push_str(" ");
|
||||||
|
pretty_body.push_str(format!("let {}", ret_mutability(&local.mutability)).as_str());
|
||||||
|
pretty_body.push_str(format!("_{}: ", index).as_str());
|
||||||
|
pretty_body.push_str(format!("{}", pretty_ty(local.ty.kind())).as_str());
|
||||||
|
pretty_body.push_str(";\n");
|
||||||
|
});
|
||||||
|
pretty_body.push_str("}");
|
||||||
|
pretty_body
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ret_mutability(mutability: &Mutability) -> String {
|
||||||
|
match mutability {
|
||||||
|
Mutability::Not => "".to_string(),
|
||||||
|
Mutability::Mut => "mut ".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pretty_statement(statement: &StatementKind) -> String {
|
||||||
|
let mut pretty = String::new();
|
||||||
|
match statement {
|
||||||
|
StatementKind::Assign(place, rval) => {
|
||||||
|
pretty.push_str(format!(" _{} = ", place.local).as_str());
|
||||||
|
pretty.push_str(format!("{}", &pretty_rvalue(rval)).as_str());
|
||||||
|
}
|
||||||
|
StatementKind::FakeRead(_, _) => todo!(),
|
||||||
|
StatementKind::SetDiscriminant { .. } => todo!(),
|
||||||
|
StatementKind::Deinit(_) => todo!(),
|
||||||
|
StatementKind::StorageLive(_) => todo!(),
|
||||||
|
StatementKind::StorageDead(_) => todo!(),
|
||||||
|
StatementKind::Retag(_, _) => todo!(),
|
||||||
|
StatementKind::PlaceMention(_) => todo!(),
|
||||||
|
StatementKind::AscribeUserType { .. } => todo!(),
|
||||||
|
StatementKind::Coverage(_) => todo!(),
|
||||||
|
StatementKind::Intrinsic(_) => todo!(),
|
||||||
|
StatementKind::ConstEvalCounter => (),
|
||||||
|
StatementKind::Nop => (),
|
||||||
|
}
|
||||||
|
pretty
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pretty_operand(operand: &Operand) -> String {
|
||||||
|
let mut pretty = String::new();
|
||||||
|
match operand {
|
||||||
|
Operand::Copy(copy) => {
|
||||||
|
pretty.push_str("");
|
||||||
|
pretty.push_str(format!("{}", copy.local).as_str());
|
||||||
|
}
|
||||||
|
Operand::Move(mv) => {
|
||||||
|
pretty.push_str("move ");
|
||||||
|
pretty.push_str(format!("_{}", mv.local).as_str());
|
||||||
|
}
|
||||||
|
Operand::Constant(cnst) => {
|
||||||
|
pretty.push_str("const ");
|
||||||
|
pretty.push_str(with(|cx| cx.const_literal(&cnst.literal)).as_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pretty
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pretty_rvalue(rval: &Rvalue) -> String {
|
||||||
|
let mut pretty = String::new();
|
||||||
|
match rval {
|
||||||
|
Rvalue::AddressOf(muta, addr) => {
|
||||||
|
pretty.push_str("&raw ");
|
||||||
|
pretty.push_str(&ret_mutability(&muta));
|
||||||
|
pretty.push_str(format!("(*_{})", addr.local).as_str());
|
||||||
|
}
|
||||||
|
Rvalue::Aggregate(aggregatekind, operands) => {
|
||||||
|
pretty.push_str(format!("{:#?}", aggregatekind).as_str());
|
||||||
|
pretty.push_str("(");
|
||||||
|
operands.iter().enumerate().for_each(|(i, op)| {
|
||||||
|
pretty.push_str(&pretty_operand(op));
|
||||||
|
if i != operands.len() - 1 {
|
||||||
|
pretty.push_str(", ");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
pretty.push_str(")");
|
||||||
|
}
|
||||||
|
Rvalue::BinaryOp(bin, op, op2) => {
|
||||||
|
pretty.push_str(&pretty_operand(op));
|
||||||
|
pretty.push_str(" ");
|
||||||
|
pretty.push_str(format!("{:#?}", bin).as_str());
|
||||||
|
pretty.push_str(" ");
|
||||||
|
pretty.push_str(&pretty_operand(op2));
|
||||||
|
}
|
||||||
|
Rvalue::Cast(_, op, ty) => {
|
||||||
|
pretty.push_str(&pretty_operand(op));
|
||||||
|
pretty.push_str(" as ");
|
||||||
|
pretty.push_str(&pretty_ty(ty.kind()));
|
||||||
|
}
|
||||||
|
Rvalue::CheckedBinaryOp(bin, op1, op2) => {
|
||||||
|
pretty.push_str(&pretty_operand(op1));
|
||||||
|
pretty.push_str(" ");
|
||||||
|
pretty.push_str(format!("{:#?}", bin).as_str());
|
||||||
|
pretty.push_str(" ");
|
||||||
|
pretty.push_str(&pretty_operand(op2));
|
||||||
|
}
|
||||||
|
Rvalue::CopyForDeref(deref) => {
|
||||||
|
pretty.push_str("CopyForDeref");
|
||||||
|
pretty.push_str(format!("{}", deref.local).as_str());
|
||||||
|
}
|
||||||
|
Rvalue::Discriminant(place) => {
|
||||||
|
pretty.push_str("discriminant");
|
||||||
|
pretty.push_str(format!("{}", place.local).as_str());
|
||||||
|
}
|
||||||
|
Rvalue::Len(len) => {
|
||||||
|
pretty.push_str("len");
|
||||||
|
pretty.push_str(format!("{}", len.local).as_str());
|
||||||
|
}
|
||||||
|
Rvalue::Ref(_, borrowkind, place) => {
|
||||||
|
pretty.push_str("ref");
|
||||||
|
pretty.push_str(format!("{:#?}", borrowkind).as_str());
|
||||||
|
pretty.push_str(format!("{}", place.local).as_str());
|
||||||
|
}
|
||||||
|
Rvalue::Repeat(op, cnst) => {
|
||||||
|
pretty.push_str(&pretty_operand(op));
|
||||||
|
pretty.push_str(" ");
|
||||||
|
pretty.push_str(&pretty_ty(cnst.ty().kind()));
|
||||||
|
}
|
||||||
|
Rvalue::ShallowInitBox(_, _) => todo!(),
|
||||||
|
Rvalue::ThreadLocalRef(item) => {
|
||||||
|
pretty.push_str("thread_local_ref");
|
||||||
|
pretty.push_str(format!("{:#?}", item).as_str());
|
||||||
|
}
|
||||||
|
Rvalue::NullaryOp(nul, ty) => {
|
||||||
|
pretty.push_str(format!("{:#?}", nul).as_str());
|
||||||
|
pretty.push_str(&&pretty_ty(ty.kind()));
|
||||||
|
pretty.push_str(" ");
|
||||||
|
}
|
||||||
|
Rvalue::UnaryOp(un, op) => {
|
||||||
|
pretty.push_str(&pretty_operand(op));
|
||||||
|
pretty.push_str(" ");
|
||||||
|
pretty.push_str(format!("{:#?}", un).as_str());
|
||||||
|
}
|
||||||
|
Rvalue::Use(op) => pretty.push_str(&pretty_operand(op)),
|
||||||
|
}
|
||||||
|
pretty
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pretty_ty(ty: TyKind) -> String {
|
||||||
|
let mut pretty = String::new();
|
||||||
|
pretty.push_str("");
|
||||||
|
match ty {
|
||||||
|
TyKind::RigidTy(rigid_ty) => match rigid_ty {
|
||||||
|
RigidTy::Bool => "bool".to_string(),
|
||||||
|
RigidTy::Char => "char".to_string(),
|
||||||
|
RigidTy::Int(i) => match i {
|
||||||
|
IntTy::Isize => "isize".to_string(),
|
||||||
|
IntTy::I8 => "i8".to_string(),
|
||||||
|
IntTy::I16 => "i16".to_string(),
|
||||||
|
IntTy::I32 => "i32".to_string(),
|
||||||
|
IntTy::I64 => "i64".to_string(),
|
||||||
|
IntTy::I128 => "i128".to_string(),
|
||||||
|
},
|
||||||
|
RigidTy::Uint(u) => match u {
|
||||||
|
UintTy::Usize => "usize".to_string(),
|
||||||
|
UintTy::U8 => "u8".to_string(),
|
||||||
|
UintTy::U16 => "u16".to_string(),
|
||||||
|
UintTy::U32 => "u32".to_string(),
|
||||||
|
UintTy::U64 => "u64".to_string(),
|
||||||
|
UintTy::U128 => "u128".to_string(),
|
||||||
|
},
|
||||||
|
RigidTy::Float(f) => match f {
|
||||||
|
FloatTy::F32 => "f32".to_string(),
|
||||||
|
FloatTy::F64 => "f64".to_string(),
|
||||||
|
},
|
||||||
|
RigidTy::Adt(def, _) => {
|
||||||
|
format!("{:#?}", with(|cx| cx.def_ty(def.0)))
|
||||||
|
}
|
||||||
|
RigidTy::Str => "str".to_string(),
|
||||||
|
RigidTy::Array(ty, len) => {
|
||||||
|
format!("[{}; {}]", pretty_ty(ty.kind()), with(|cx| cx.const_literal(&len)))
|
||||||
|
}
|
||||||
|
RigidTy::Slice(ty) => {
|
||||||
|
format!("[{}]", pretty_ty(ty.kind()))
|
||||||
|
}
|
||||||
|
RigidTy::RawPtr(ty, mutability) => {
|
||||||
|
pretty.push_str("*");
|
||||||
|
match mutability {
|
||||||
|
Mutability::Not => pretty.push_str("const "),
|
||||||
|
Mutability::Mut => pretty.push_str("mut "),
|
||||||
|
}
|
||||||
|
pretty.push_str(&pretty_ty(ty.kind()));
|
||||||
|
pretty
|
||||||
|
}
|
||||||
|
RigidTy::Ref(_, ty, _) => pretty_ty(ty.kind()),
|
||||||
|
RigidTy::FnDef(_, _) => format!("{:#?}", rigid_ty),
|
||||||
|
RigidTy::FnPtr(_) => format!("{:#?}", rigid_ty),
|
||||||
|
RigidTy::Closure(_, _) => format!("{:#?}", rigid_ty),
|
||||||
|
RigidTy::Coroutine(_, _, _) => format!("{:#?}", rigid_ty),
|
||||||
|
RigidTy::Dynamic(data, region, repr) => {
|
||||||
|
// FIXME: Fix binder printing, it looks ugly now
|
||||||
|
pretty.push_str("(");
|
||||||
|
match repr {
|
||||||
|
DynKind::Dyn => pretty.push_str("dyn "),
|
||||||
|
DynKind::DynStar => pretty.push_str("dyn* "),
|
||||||
|
}
|
||||||
|
pretty.push_str(format!("{:#?}", data).as_str());
|
||||||
|
pretty.push_str(format!(" + {:#?} )", region).as_str());
|
||||||
|
pretty
|
||||||
|
}
|
||||||
|
RigidTy::Never => "!".to_string(),
|
||||||
|
RigidTy::Tuple(tuple) => {
|
||||||
|
if tuple.is_empty() {
|
||||||
|
"()".to_string()
|
||||||
|
} else {
|
||||||
|
let mut tuple_str = String::new();
|
||||||
|
tuple_str.push_str("(");
|
||||||
|
tuple.iter().enumerate().for_each(|(i, ty)| {
|
||||||
|
tuple_str.push_str(&pretty_ty(ty.kind()));
|
||||||
|
if i != tuple.len() - 1 {
|
||||||
|
tuple_str.push_str(", ");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tuple_str.push_str(")");
|
||||||
|
tuple_str
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => format!("{:#?}", rigid_ty),
|
||||||
|
},
|
||||||
|
TyKind::Alias(_, _) => format!("{:#?}", ty),
|
||||||
|
TyKind::Param(param_ty) => {
|
||||||
|
format!("{:#?}", param_ty.name)
|
||||||
|
}
|
||||||
|
TyKind::Bound(_, _) => format!("{:#?}", ty),
|
||||||
|
}
|
||||||
|
}
|
@ -157,7 +157,7 @@ pub trait MirVisitor {
|
|||||||
|
|
||||||
fn super_local_decl(&mut self, local: Local, decl: &LocalDecl) {
|
fn super_local_decl(&mut self, local: Local, decl: &LocalDecl) {
|
||||||
let _ = local;
|
let _ = local;
|
||||||
let LocalDecl { ty, span } = decl;
|
let LocalDecl { ty, span, .. } = decl;
|
||||||
self.visit_ty(ty, Location(*span));
|
self.visit_ty(ty, Location(*span));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user