diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs
index 3a8289f38bdc4..b2ca5b5ce29ad 100644
--- a/compiler/rustc_smir/src/rustc_smir/context.rs
+++ b/compiler/rustc_smir/src/rustc_smir/context.rs
@@ -18,7 +18,9 @@ use stable_mir::ty::{
     AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, GenericArgs,
     LineInfo, PolyFnSig, RigidTy, Span, Ty, TyKind, VariantDef,
 };
-use stable_mir::{Crate, CrateItem, DefId, Error, Filename, ItemKind, Symbol};
+use stable_mir::{
+    self, opaque, Crate, CrateItem, DefId, Error, Filename, ItemKind, Opaque, Symbol,
+};
 use std::cell::RefCell;
 
 use crate::rustc_internal::{internal, RustcInternal};
@@ -297,6 +299,12 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
         internal(cnst).to_string()
     }
 
+    fn adt_literal(&self, adt: &AdtDef) -> Opaque {
+        let mut tables = self.0.borrow_mut();
+        let internal = adt.internal(&mut *tables);
+        opaque(&internal)
+    }
+
     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)
diff --git a/compiler/stable_mir/src/compiler_interface.rs b/compiler/stable_mir/src/compiler_interface.rs
index 2fac59e71fd5b..c5c376009ab31 100644
--- a/compiler/stable_mir/src/compiler_interface.rs
+++ b/compiler/stable_mir/src/compiler_interface.rs
@@ -15,8 +15,8 @@ use crate::ty::{
     TraitDef, Ty, TyKind, VariantDef,
 };
 use crate::{
-    mir, Crate, CrateItem, CrateItems, DefId, Error, Filename, ImplTraitDecls, ItemKind, Symbol,
-    TraitDecls,
+    mir, Crate, CrateItem, CrateItems, DefId, Error, Filename, ImplTraitDecls, ItemKind, Opaque,
+    Symbol, TraitDecls,
 };
 
 /// This trait defines the interface between stable_mir and the Rust compiler.
@@ -106,6 +106,9 @@ pub trait Context {
     /// Returns literal value of a const as a string.
     fn const_literal(&self, cnst: &Const) -> String;
 
+    /// Returns literal version of a Adt as a Opaque
+    fn adt_literal(&self, adt: &AdtDef) -> Opaque;
+
     /// `Span` of an item
     fn span_of_an_item(&self, def_id: DefId) -> Span;
 
diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs
index 5023af9ab79ec..b93f1878ee124 100644
--- a/compiler/stable_mir/src/mir/body.rs
+++ b/compiler/stable_mir/src/mir/body.rs
@@ -107,6 +107,7 @@ impl Body {
                 Ok(())
             })
             .collect::<Result<Vec<_>, _>>()?;
+        writeln!(w, "}}")?;
         Ok(())
     }
 
diff --git a/compiler/stable_mir/src/mir/pretty.rs b/compiler/stable_mir/src/mir/pretty.rs
index 8b7b488d312cf..fcf20022bb945 100644
--- a/compiler/stable_mir/src/mir/pretty.rs
+++ b/compiler/stable_mir/src/mir/pretty.rs
@@ -7,27 +7,25 @@ use std::{io, iter};
 
 use super::{AssertMessage, BinOp, TerminatorKind};
 
+use super::BorrowKind;
+
 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());
+    pretty_name.push_str(format!("fn {}", 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()));
+        pretty_name.push_str(format!("_{}: {}", index, pretty_ty(local.ty.kind())).as_str());
     });
     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.push_str(format!(" -> {} {{", pretty_ty(return_local.ty.kind())).as_str());
     pretty_name
 }
 
@@ -35,12 +33,16 @@ 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(
+            format!(
+                "let {}_{}: {};\n",
+                ret_mutability(&local.mutability),
+                index,
+                pretty_ty(local.ty.kind())
+            )
+            .as_str(),
+        );
     });
-    pretty_body.push_str("}");
     pretty_body
 }
 
@@ -55,8 +57,7 @@ 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());
+            pretty.push_str(format!("        _{} = {}", place.local, pretty_rvalue(rval)).as_str());
         }
         // FIXME: Add rest of the statements
         StatementKind::FakeRead(_, _) => {
@@ -116,7 +117,7 @@ pub fn pretty_terminator<W: io::Write>(terminator: &TerminatorKind, w: &mut W) -
             Ok(())
         }
         (1, false) => {
-            write!(w, " -> {:?}", successors[0])?;
+            write!(w, " -> bb{:?}", successors[0])?;
             Ok(())
         }
         _ => {
@@ -153,9 +154,7 @@ pub fn pretty_terminator_head(terminator: &TerminatorKind) -> String {
         Drop { place, .. } => format!("        drop(_{:?})", place.local),
         Call { func, args, destination, .. } => {
             pretty.push_str("        ");
-            pretty.push_str(format!("_{} = ", destination.local).as_str());
-            pretty.push_str(&pretty_operand(func));
-            pretty.push_str("(");
+            pretty.push_str(format!("_{} = {}(", destination.local, pretty_operand(func)).as_str());
             args.iter().enumerate().for_each(|(i, arg)| {
                 if i > 0 {
                     pretty.push_str(", ");
@@ -170,9 +169,9 @@ pub fn pretty_terminator_head(terminator: &TerminatorKind) -> String {
             if !expected {
                 pretty.push_str("!");
             }
-            pretty.push_str(format!("{} bool),", &pretty_operand(cond)).as_str());
-            pretty.push_str(&pretty_assert_message(msg));
-            pretty.push_str(")");
+            pretty.push_str(
+                format!("{} bool),{})", &pretty_operand(cond), pretty_assert_message(msg)).as_str(),
+            );
             pretty
         }
         InlineAsm { .. } => todo!(),
@@ -296,16 +295,14 @@ 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());
+            pretty.push_str(format!("_{}", copy.local).as_str());
         }
         Operand::Move(mv) => {
-            pretty.push_str("move ");
-            pretty.push_str(format!("_{}", mv.local).as_str());
+            pretty.push_str(format!("move _{}", mv.local).as_str());
         }
         Operand::Constant(cnst) => {
-            pretty.push_str("const ");
-            pretty.push_str(with(|cx| cx.const_literal(&cnst.literal)).as_str());
+            pretty
+                .push_str(format!("const {}", with(|cx| cx.const_literal(&cnst.literal))).as_str());
         }
     }
     pretty
@@ -315,13 +312,11 @@ 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());
+            pretty.push_str(format!("&raw {}(*_{})", &ret_mutability(muta), addr.local).as_str());
         }
         Rvalue::Aggregate(aggregatekind, operands) => {
-            pretty.push_str(format!("{:#?}", aggregatekind).as_str());
-            pretty.push_str("(");
+            // FIXME: Add pretty_aggregate function that returns a pretty string
+            pretty.push_str(format!("{:#?} (", aggregatekind).as_str());
             operands.iter().enumerate().for_each(|(i, op)| {
                 pretty.push_str(&pretty_operand(op));
                 if i != operands.len() - 1 {
@@ -330,61 +325,51 @@ pub fn pretty_rvalue(rval: &Rvalue) -> String {
             });
             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::BinaryOp(bin, op1, op2) => {
+            pretty.push_str(
+                format!("{:#?}({}, {})", bin, &pretty_operand(op1), pretty_operand(op2)).as_str(),
+            );
         }
         Rvalue::Cast(_, op, ty) => {
-            pretty.push_str(&pretty_operand(op));
-            pretty.push_str(" as ");
-            pretty.push_str(&pretty_ty(ty.kind()));
+            pretty.push_str(format!("{} as {}", pretty_operand(op), pretty_ty(ty.kind())).as_str());
         }
         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));
+            pretty.push_str(
+                format!("Checked{:#?}({}, {})", bin, &pretty_operand(op1), pretty_operand(op2))
+                    .as_str(),
+            );
         }
         Rvalue::CopyForDeref(deref) => {
-            pretty.push_str("CopyForDeref");
-            pretty.push_str(format!("{}", deref.local).as_str());
+            pretty.push_str(format!("CopyForDeref{}", deref.local).as_str());
         }
         Rvalue::Discriminant(place) => {
-            pretty.push_str("discriminant");
-            pretty.push_str(format!("{}", place.local).as_str());
+            pretty.push_str(format!("discriminant{}", place.local).as_str());
         }
         Rvalue::Len(len) => {
-            pretty.push_str("len");
-            pretty.push_str(format!("{}", len.local).as_str());
+            pretty.push_str(format!("len{}", len.local).as_str());
         }
         Rvalue::Ref(_, borrowkind, place) => {
-            pretty.push_str("ref");
-            pretty.push_str(format!("{:#?}", borrowkind).as_str());
+            match borrowkind {
+                BorrowKind::Shared => pretty.push_str("&"),
+                BorrowKind::Fake => pretty.push_str("&fake "),
+                BorrowKind::Mut { .. } => pretty.push_str("&mut "),
+            }
             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()));
+            pretty.push_str(
+                &format!("{} \" \" {}", &pretty_operand(op), pretty_ty(cnst.ty().kind())).as_str(),
+            );
         }
         Rvalue::ShallowInitBox(_, _) => (),
         Rvalue::ThreadLocalRef(item) => {
-            pretty.push_str("thread_local_ref");
-            pretty.push_str(format!("{:#?}", item).as_str());
+            pretty.push_str(format!("thread_local_ref{:#?}", item).as_str());
         }
         Rvalue::NullaryOp(nul, ty) => {
-            pretty.push_str(format!("{:#?}", nul).as_str());
-            pretty.push_str(&pretty_ty(ty.kind()));
-            pretty.push_str(" ");
+            pretty.push_str(format!("{:#?} {} \" \"", nul, pretty_ty(ty.kind())).as_str());
         }
         Rvalue::UnaryOp(un, op) => {
-            pretty.push_str(&pretty_operand(op));
-            pretty.push_str(" ");
-            pretty.push_str(format!("{:#?}", un).as_str());
+            pretty.push_str(format!("{} \" \" {:#?}", pretty_operand(op), un).as_str());
         }
         Rvalue::Use(op) => pretty.push_str(&pretty_operand(op)),
     }
@@ -418,7 +403,7 @@ pub fn pretty_ty(ty: TyKind) -> String {
                 FloatTy::F64 => "f64".to_string(),
             },
             RigidTy::Adt(def, _) => {
-                format!("{:#?}", with(|cx| cx.def_ty(def.0)))
+                format!("{}", with(|cx| cx.adt_literal(&def)))
             }
             RigidTy::Str => "str".to_string(),
             RigidTy::Array(ty, len) => {
@@ -451,8 +436,7 @@ pub fn pretty_ty(ty: TyKind) -> String {
                     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.push_str(format!("{:#?} + {:#?}", data, region).as_str());
                 pretty
             }
             RigidTy::Never => "!".to_string(),
diff --git a/tests/ui/stable-mir-print/basic_function.rs b/tests/ui/stable-mir-print/basic_function.rs
index 6394edcbb7847..5af3b21302e13 100644
--- a/tests/ui/stable-mir-print/basic_function.rs
+++ b/tests/ui/stable-mir-print/basic_function.rs
@@ -12,4 +12,13 @@ fn bar(vec: &mut Vec<i32>) -> Vec<i32> {
     new_vec
 }
 
+pub fn demux(input: u8) -> u8 {
+    match input {
+        0 => 10,
+        1 => 6,
+        2 => 8,
+        _ => 0,
+    }
+}
+
 fn main(){}
diff --git a/tests/ui/stable-mir-print/basic_function.stdout b/tests/ui/stable-mir-print/basic_function.stdout
index d9b33a4257c2c..5a858a86d7b87 100644
--- a/tests/ui/stable-mir-print/basic_function.stdout
+++ b/tests/ui/stable-mir-print/basic_function.stdout
@@ -2,219 +2,28 @@
 // If you find a bug or want to improve the output open a issue at https://github.com/rust-lang/project-stable-mir.
 fn foo(_0: i32) -> i32 {
     let mut _0: (i32, bool);
-}
+
     bb0: {
-        _2 = 1 Add const 1_i32
-        assert(!move _2 bool),"attempt to compute `{} + {}`, which would overflow", 1, const 1_i32) -> [success: bb1, unwind continue]
+        _2 = CheckedAdd(_1, const 1_i32)
+        assert(!move _2 bool),"attempt to compute `{} + {}`, which would overflow", _1, const 1_i32) -> [success: bb1, unwind continue]
     }
     bb1: {
         _0 = move _2
         return
     }
-fn bar(_0: &mut Ty {
-    id: 10,
-    kind: RigidTy(
-        Adt(
-            AdtDef(
-                DefId {
-                    id: 3,
-                    name: "std::vec::Vec",
-                },
-            ),
-            GenericArgs(
-                [
-                    Type(
-                        Ty {
-                            id: 11,
-                            kind: Param(
-                                ParamTy {
-                                    index: 0,
-                                    name: "T",
-                                },
-                            ),
-                        },
-                    ),
-                    Type(
-                        Ty {
-                            id: 12,
-                            kind: Param(
-                                ParamTy {
-                                    index: 1,
-                                    name: "A",
-                                },
-                            ),
-                        },
-                    ),
-                ],
-            ),
-        ),
-    ),
-}) -> Ty {
-    id: 10,
-    kind: RigidTy(
-        Adt(
-            AdtDef(
-                DefId {
-                    id: 3,
-                    name: "std::vec::Vec",
-                },
-            ),
-            GenericArgs(
-                [
-                    Type(
-                        Ty {
-                            id: 11,
-                            kind: Param(
-                                ParamTy {
-                                    index: 0,
-                                    name: "T",
-                                },
-                            ),
-                        },
-                    ),
-                    Type(
-                        Ty {
-                            id: 12,
-                            kind: Param(
-                                ParamTy {
-                                    index: 1,
-                                    name: "A",
-                                },
-                            ),
-                        },
-                    ),
-                ],
-            ),
-        ),
-    ),
-} {
-    let mut _0: Ty {
-    id: 10,
-    kind: RigidTy(
-        Adt(
-            AdtDef(
-                DefId {
-                    id: 3,
-                    name: "std::vec::Vec",
-                },
-            ),
-            GenericArgs(
-                [
-                    Type(
-                        Ty {
-                            id: 11,
-                            kind: Param(
-                                ParamTy {
-                                    index: 0,
-                                    name: "T",
-                                },
-                            ),
-                        },
-                    ),
-                    Type(
-                        Ty {
-                            id: 12,
-                            kind: Param(
-                                ParamTy {
-                                    index: 1,
-                                    name: "A",
-                                },
-                            ),
-                        },
-                    ),
-                ],
-            ),
-        ),
-    ),
-};
-    let mut _1: &Ty {
-    id: 10,
-    kind: RigidTy(
-        Adt(
-            AdtDef(
-                DefId {
-                    id: 3,
-                    name: "std::vec::Vec",
-                },
-            ),
-            GenericArgs(
-                [
-                    Type(
-                        Ty {
-                            id: 11,
-                            kind: Param(
-                                ParamTy {
-                                    index: 0,
-                                    name: "T",
-                                },
-                            ),
-                        },
-                    ),
-                    Type(
-                        Ty {
-                            id: 12,
-                            kind: Param(
-                                ParamTy {
-                                    index: 1,
-                                    name: "A",
-                                },
-                            ),
-                        },
-                    ),
-                ],
-            ),
-        ),
-    ),
-};
-    let _2: ();
-    let mut _3: &mut Ty {
-    id: 10,
-    kind: RigidTy(
-        Adt(
-            AdtDef(
-                DefId {
-                    id: 3,
-                    name: "std::vec::Vec",
-                },
-            ),
-            GenericArgs(
-                [
-                    Type(
-                        Ty {
-                            id: 11,
-                            kind: Param(
-                                ParamTy {
-                                    index: 0,
-                                    name: "T",
-                                },
-                            ),
-                        },
-                    ),
-                    Type(
-                        Ty {
-                            id: 12,
-                            kind: Param(
-                                ParamTy {
-                                    index: 1,
-                                    name: "A",
-                                },
-                            ),
-                        },
-                    ),
-                ],
-            ),
-        ),
-    ),
-};
 }
+fn bar(_0: &mut std::vec::Vec) -> std::vec::Vec {
+    let mut _0: std::vec::Vec;
+    let mut _1: &std::vec::Vec;
+    let _2: ();
+    let mut _3: &mut std::vec::Vec;
+
     bb0: {
-        _3 = refShared1
+        _3 = &1
         _2 = const <Vec<i32> as Clone>::clone(move _3) -> [return: bb1, unwind continue]
     }
     bb1: {
-        _5 = refMut {
-    kind: TwoPhaseBorrow,
-}2
+        _5 = &mut 2
         _4 = const Vec::<i32>::push(move _5, const 1_i32) -> [return: bb2, unwind: bb3]
     }
     bb2: {
@@ -227,8 +36,35 @@ fn bar(_0: &mut Ty {
     bb4: {
         resume
     }
-fn main() -> () {
 }
+fn demux(_0: u8) -> u8 {
+
     bb0: {
+        switchInt(__1) -> [0: bb2, 1: bb3, 2: bb4, otherwise: bb1]
+    }
+    bb1: {
+        _0 = const 0_u8
+        goto -> bb5
+    }
+    bb2: {
+        _0 = const 10_u8
+        goto -> bb5
+    }
+    bb3: {
+        _0 = const 6_u8
+        goto -> bb5
+    }
+    bb4: {
+        _0 = const 8_u8
+        goto -> bb5
+    }
+    bb5: {
         return
     }
+}
+fn main() -> () {
+
+    bb0: {
+        return
+    }
+}