about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-11-17 22:58:19 +0000
committerbors <bors@rust-lang.org>2023-11-17 22:58:19 +0000
commit82b804c74433a233914f604bb0ba385719605e5e (patch)
tree716c6703b2d98395895c54e6fd710ea1940176af /compiler
parent2831701757eb7b3105eda26a306c2f3a97e2664b (diff)
parent8acb27c165ce6b0af2705e653d3506ce607a9c0b (diff)
downloadrust-82b804c74433a233914f604bb0ba385719605e5e.tar.gz
rust-82b804c74433a233914f604bb0ba385719605e5e.zip
Auto merge of #118023 - matthiaskrgr:rollup-i9skwic, r=matthiaskrgr
Rollup of 7 pull requests

Successful merges:

 - #117338 (Remove asmjs)
 - #117549 (Use `copied` instead of manual `map`)
 - #117745 (Emit smir)
 - #117964 (When using existing fn as module, don't claim it doesn't exist)
 - #118006 (clarify `fn discriminant` guarantees: only free lifetimes may get erased)
 - #118016 (Add stable mir members to triagebot config)
 - #118022 (Miri subtree update)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs3
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs6
-rw-r--r--compiler/rustc_driver_impl/Cargo.toml1
-rw-r--r--compiler/rustc_driver_impl/src/pretty.rs6
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs2
-rw-r--r--compiler/rustc_lint/src/context.rs2
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs2
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs14
-rw-r--r--compiler/rustc_session/src/config.rs12
-rw-r--r--compiler/rustc_smir/src/rustc_internal/mod.rs1
-rw-r--r--compiler/rustc_smir/src/rustc_internal/pretty.rs20
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs7
-rw-r--r--compiler/rustc_target/src/abi/call/mod.rs1
-rw-r--r--compiler/rustc_target/src/spec/mod.rs5
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs4
-rw-r--r--compiler/stable_mir/src/lib.rs14
-rw-r--r--compiler/stable_mir/src/mir.rs1
-rw-r--r--compiler/stable_mir/src/mir/body.rs26
-rw-r--r--compiler/stable_mir/src/mir/pretty.rs258
-rw-r--r--compiler/stable_mir/src/mir/visit.rs2
22 files changed, 364 insertions, 33 deletions
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index c07dbbc9d67..2c13e1523f1 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -42,8 +42,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     }
                     // Merge attributes into the inner expression.
                     if !e.attrs.is_empty() {
-                        let old_attrs =
-                            self.attrs.get(&ex.hir_id.local_id).map(|la| *la).unwrap_or(&[]);
+                        let old_attrs = self.attrs.get(&ex.hir_id.local_id).copied().unwrap_or(&[]);
                         self.attrs.insert(
                             ex.hir_id.local_id,
                             &*self.arena.alloc_from_iter(
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index b8e18d3434a..3db9d0b31e0 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -499,7 +499,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name
     /// resolver (if any).
     fn orig_opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {
-        self.resolver.node_id_to_def_id.get(&node).map(|local_def_id| *local_def_id)
+        self.resolver.node_id_to_def_id.get(&node).copied()
     }
 
     /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name
@@ -542,7 +542,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         self.generics_def_id_map
             .iter()
             .rev()
-            .find_map(|map| map.get(&local_def_id).map(|local_def_id| *local_def_id))
+            .find_map(|map| map.get(&local_def_id).copied())
             .unwrap_or(local_def_id)
     }
 
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 9d5204034de..8d335ff1718 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -990,11 +990,7 @@ unsafe fn embed_bitcode(
     // reason (see issue #90326 for historical background).
     let is_aix = target_is_aix(cgcx);
     let is_apple = target_is_apple(cgcx);
-    if is_apple
-        || is_aix
-        || cgcx.opts.target_triple.triple().starts_with("wasm")
-        || cgcx.opts.target_triple.triple().starts_with("asmjs")
-    {
+    if is_apple || is_aix || cgcx.opts.target_triple.triple().starts_with("wasm") {
         // We don't need custom section flags, create LLVM globals.
         let llconst = common::bytes_in_context(llcx, bitcode);
         let llglobal = llvm::LLVMAddGlobal(
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index dd9d277fb77..33e8f352cd8 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -2243,9 +2243,9 @@ fn linker_with_args<'a>(
     // ------------ Late order-dependent options ------------
 
     // Doesn't really make sense.
-    // FIXME: In practice built-in target specs use this for arbitrary order-independent options,
-    // introduce a target spec option for order-independent linker options, migrate built-in specs
-    // to it and remove the option.
+    // FIXME: In practice built-in target specs use this for arbitrary order-independent options.
+    // Introduce a target spec option for order-independent linker options, migrate built-in specs
+    // to it and remove the option. Currently the last holdout is wasm32-unknown-emscripten.
     add_post_link_args(cmd, sess, flavor);
 
     Ok(cmd.take_cmd())
diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml
index da7c2440faa..545ff32e598 100644
--- a/compiler/rustc_driver_impl/Cargo.toml
+++ b/compiler/rustc_driver_impl/Cargo.toml
@@ -43,6 +43,7 @@ rustc_privacy = { path = "../rustc_privacy" }
 rustc_query_system = { path = "../rustc_query_system" }
 rustc_resolve = { path = "../rustc_resolve" }
 rustc_session = { path = "../rustc_session" }
+rustc_smir ={ path = "../rustc_smir" }
 rustc_span = { path = "../rustc_span" }
 rustc_symbol_mangling = { path = "../rustc_symbol_mangling" }
 rustc_target = { path = "../rustc_target" }
diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs
index cc533b9941a..7cd63bc6422 100644
--- a/compiler/rustc_driver_impl/src/pretty.rs
+++ b/compiler/rustc_driver_impl/src/pretty.rs
@@ -9,6 +9,7 @@ use rustc_middle::mir::{write_mir_graphviz, write_mir_pretty};
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_session::config::{OutFileName, PpHirMode, PpMode, PpSourceMode};
 use rustc_session::Session;
+use rustc_smir::rustc_internal::pretty::write_smir_pretty;
 use rustc_span::symbol::Ident;
 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();
             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 => {
             let tcx = ex.tcx();
             let mut out = String::new();
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 0546f4e1afc..56e3280088e 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -860,7 +860,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                         self.suggest_boxing_for_return_impl_trait(
                             err,
                             ret_sp,
-                            prior_arms.iter().chain(std::iter::once(&arm_span)).map(|s| *s),
+                            prior_arms.iter().chain(std::iter::once(&arm_span)).copied(),
                         );
                     }
                 }
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index cd4c0d07e55..d500c3b66d6 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -703,7 +703,7 @@ pub trait LintContext {
                     db.note("see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information");
                 },
                 BuiltinLintDiagnostics::UnexpectedCfgName((name, name_span), value) => {
-                    let possibilities: Vec<Symbol> = sess.parse_sess.check_config.expecteds.keys().map(|s| *s).collect();
+                    let possibilities: Vec<Symbol> = sess.parse_sess.check_config.expecteds.keys().copied().collect();
 
                     // Suggest the most probable if we found one
                     if let Some(best_match) = find_best_match_for_name(&possibilities, name, None) {
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index a1324858416..1974a35cb85 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -1337,7 +1337,7 @@ pub fn write_allocations<'tcx>(
     fn alloc_ids_from_alloc(
         alloc: ConstAllocation<'_>,
     ) -> impl DoubleEndedIterator<Item = AllocId> + '_ {
-        alloc.inner().provenance().ptrs().values().map(|id| *id)
+        alloc.inner().provenance().ptrs().values().copied()
     }
 
     fn alloc_ids_from_const_val(val: ConstValue<'_>) -> impl Iterator<Item = AllocId> + '_ {
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 93db6cfc463..28e6fe9b4b7 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -2028,7 +2028,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     },
                 )
             });
-            (format!("use of undeclared crate or module `{ident}`"), suggestion)
+            if let Ok(binding) = self.early_resolve_ident_in_lexical_scope(
+                ident,
+                ScopeSet::All(ValueNS),
+                parent_scope,
+                None,
+                false,
+                ignore_binding,
+            ) {
+                let descr = binding.res().descr();
+                (format!("{descr} `{ident}` is not a crate or module"), suggestion)
+            } else {
+                (format!("use of undeclared crate or module `{ident}`"), suggestion)
+            }
         }
     }
 
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index add40b83d21..d4f9122e7e3 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -2926,12 +2926,13 @@ fn parse_pretty(handler: &EarlyErrorHandler, unstable_opts: &UnstableOptions) ->
         "thir-tree" => ThirTree,
         "thir-flat" => ThirFlat,
         "mir" => Mir,
+        "stable-mir" => StableMir,
         "mir-cfg" => MirCFG,
         name => handler.early_error(format!(
             "argument to `unpretty` must be one of `normal`, `identified`, \
                             `expanded`, `expanded,identified`, `expanded,hygiene`, \
                             `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}"
         )),
     };
@@ -3106,6 +3107,8 @@ pub enum PpMode {
     Mir,
     /// `-Zunpretty=mir-cfg`
     MirCFG,
+    /// `-Zunpretty=stable-mir`
+    StableMir,
 }
 
 impl PpMode {
@@ -3122,7 +3125,8 @@ impl PpMode {
             | ThirTree
             | ThirFlat
             | Mir
-            | MirCFG => true,
+            | MirCFG
+            | StableMir => true,
         }
     }
     pub fn needs_hir(&self) -> bool {
@@ -3130,13 +3134,13 @@ impl PpMode {
         match *self {
             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 {
         use PpMode::*;
-        matches!(*self, Hir(PpHirMode::Typed) | Mir | MirCFG | ThirTree | ThirFlat)
+        matches!(*self, Hir(PpHirMode::Typed) | Mir | StableMir | MirCFG | ThirTree | ThirFlat)
     }
 }
 
diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
index c82f948f195..fa75fd3076c 100644
--- a/compiler/rustc_smir/src/rustc_internal/mod.rs
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -21,6 +21,7 @@ use std::hash::Hash;
 use std::ops::Index;
 
 mod internal;
+pub mod pretty;
 
 pub fn stable<'tcx, S: Stable<'tcx>>(item: S) -> S::T {
     with_tables(|tables| item.stable(tables))
diff --git a/compiler/rustc_smir/src/rustc_internal/pretty.rs b/compiler/rustc_smir/src/rustc_internal/pretty.rs
new file mode 100644
index 00000000000..3ef2d28ea47
--- /dev/null
+++ b/compiler/rustc_smir/src/rustc_internal/pretty.rs
@@ -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(())
+}
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 3df09cef1c7..89dbf40c7b4 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -7,7 +7,7 @@
 //!
 //! 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 rustc_hir as hir;
 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)
     }
 
+    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 {
         let mut tables = self.0.borrow_mut();
         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 {
                     ty: decl.ty.stable(tables),
                     span: decl.source_info.span.stable(tables),
+                    mutability: decl.mutability.stable(tables),
                 })
                 .collect(),
             self.arg_count,
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
index 5efd171b9dd..1aa24f6b84a 100644
--- a/compiler/rustc_target/src/abi/call/mod.rs
+++ b/compiler/rustc_target/src/abi/call/mod.rs
@@ -836,7 +836,6 @@ impl<'a, Ty> FnAbi<'a, Ty> {
                     wasm::compute_c_abi_info(cx, self)
                 }
             }
-            "asmjs" => wasm::compute_c_abi_info(cx, self),
             "bpf" => bpf::compute_abi_info(self),
             arch => {
                 return Err(AdjustForForeignAbiError::Unsupported {
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index d8dd4ae2286..9de8aa7c712 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1609,7 +1609,6 @@ supported_targets! {
     ("thumbv7a-pc-windows-msvc", thumbv7a_pc_windows_msvc),
     ("thumbv7a-uwp-windows-msvc", thumbv7a_uwp_windows_msvc),
 
-    ("asmjs-unknown-emscripten", asmjs_unknown_emscripten),
     ("wasm32-unknown-emscripten", wasm32_unknown_emscripten),
     ("wasm32-unknown-unknown", wasm32_unknown_unknown),
     ("wasm32-wasi", wasm32_wasi),
@@ -2244,10 +2243,6 @@ impl TargetOptions {
         add_link_args(&mut self.pre_link_args, flavor, args);
     }
 
-    fn add_post_link_args(&mut self, flavor: LinkerFlavor, args: &[&'static str]) {
-        add_link_args(&mut self.post_link_args, flavor, args);
-    }
-
     fn update_from_cli(&mut self) {
         self.linker_flavor = LinkerFlavor::from_cli_json(
             self.linker_flavor_json,
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index 3e140793b5a..ffeeae66858 100644
--- a/compiler/rustc_ty_utils/src/assoc.rs
+++ b/compiler/rustc_ty_utils/src/assoc.rs
@@ -43,7 +43,7 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] {
                                     trait_fn_def_id,
                                 )
                             })
-                            .map(|def_id| *def_id),
+                            .copied(),
                     ),
             )
         }
@@ -69,7 +69,7 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] {
                                     impl_fn_def_id,
                                 )
                             })
-                            .map(|def_id| *def_id)
+                            .copied()
                     })),
             )
         }
diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs
index 0262fb536e7..79102dcce35 100644
--- a/compiler/stable_mir/src/lib.rs
+++ b/compiler/stable_mir/src/lib.rs
@@ -19,9 +19,9 @@
 
 use crate::mir::mono::InstanceDef;
 use crate::mir::Body;
-use std::cell::Cell;
 use std::fmt;
 use std::fmt::Debug;
+use std::{cell::Cell, io};
 
 use self::ty::{
     GenericPredicates, Generics, ImplDef, ImplTrait, IndexedVal, LineInfo, Span, TraitDecl,
@@ -36,10 +36,12 @@ pub mod mir;
 pub mod ty;
 pub mod visitor;
 
+use crate::mir::pretty::function_name;
+use crate::mir::Mutability;
 use crate::ty::{AdtDef, AdtKind, ClosureDef, ClosureKind};
 pub use error::*;
 use mir::mono::Instance;
-use ty::{FnDef, GenericArgs};
+use ty::{Const, FnDef, GenericArgs};
 
 /// Use String for now but we should replace it.
 pub type Symbol = String;
@@ -137,6 +139,11 @@ impl CrateItem {
     pub fn ty(&self) -> Ty {
         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
@@ -223,6 +230,9 @@ pub trait Context {
     /// Returns the type of given crate item.
     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
     fn span_of_an_item(&self, def_id: DefId) -> Span;
 
diff --git a/compiler/stable_mir/src/mir.rs b/compiler/stable_mir/src/mir.rs
index 2e1714b49c1..2cbe6eb4ad1 100644
--- a/compiler/stable_mir/src/mir.rs
+++ b/compiler/stable_mir/src/mir.rs
@@ -1,5 +1,6 @@
 mod body;
 pub mod mono;
+pub mod pretty;
 pub mod visit;
 
 pub use body::*;
diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs
index 351e7bb69c3..fa58a7ffe15 100644
--- a/compiler/stable_mir/src/mir/body.rs
+++ b/compiler/stable_mir/src/mir/body.rs
@@ -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::Opaque;
 use crate::Span;
-
+use std::io;
 /// The SMIR representation of a single function.
 #[derive(Clone, Debug)]
 pub struct Body {
@@ -56,6 +57,28 @@ impl Body {
     pub fn locals(&self) -> &[LocalDecl] {
         &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>;
@@ -64,6 +87,7 @@ type LocalDecls = Vec<LocalDecl>;
 pub struct LocalDecl {
     pub ty: Ty,
     pub span: Span,
+    pub mutability: Mutability,
 }
 
 #[derive(Clone, Debug)]
diff --git a/compiler/stable_mir/src/mir/pretty.rs b/compiler/stable_mir/src/mir/pretty.rs
new file mode 100644
index 00000000000..e52c3360ce4
--- /dev/null
+++ b/compiler/stable_mir/src/mir/pretty.rs
@@ -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),
+    }
+}
diff --git a/compiler/stable_mir/src/mir/visit.rs b/compiler/stable_mir/src/mir/visit.rs
index d6304d3ea39..40bedd67352 100644
--- a/compiler/stable_mir/src/mir/visit.rs
+++ b/compiler/stable_mir/src/mir/visit.rs
@@ -157,7 +157,7 @@ pub trait MirVisitor {
 
     fn super_local_decl(&mut self, local: Local, decl: &LocalDecl) {
         let _ = local;
-        let LocalDecl { ty, span } = decl;
+        let LocalDecl { ty, span, .. } = decl;
         self.visit_ty(ty, Location(*span));
     }