From e8165e7f1bfdc7c82749e4bdaafec8ee1a161eb8 Mon Sep 17 00:00:00 2001
From: Smitty <me@smitop.com>
Date: Sat, 24 Jul 2021 17:18:15 -0400
Subject: [PATCH 1/2] Support -Z unpretty=thir-tree again

---
 Cargo.lock                                  |  1 +
 compiler/rustc_driver/Cargo.toml            |  1 +
 compiler/rustc_driver/src/pretty.rs         | 16 +++++++++++++---
 compiler/rustc_middle/src/query/mod.rs      |  6 ++++++
 compiler/rustc_mir_build/src/lib.rs         |  1 +
 compiler/rustc_mir_build/src/thir/cx/mod.rs |  7 +++++++
 6 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 553d9d05e57ba..f3ee3568dbcc6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3726,6 +3726,7 @@ dependencies = [
  "rustc_session",
  "rustc_span",
  "rustc_target",
+ "rustc_typeck",
  "tracing",
  "tracing-subscriber",
  "tracing-tree",
diff --git a/compiler/rustc_driver/Cargo.toml b/compiler/rustc_driver/Cargo.toml
index 93c6ec04e4fd6..2bc163e784316 100644
--- a/compiler/rustc_driver/Cargo.toml
+++ b/compiler/rustc_driver/Cargo.toml
@@ -34,6 +34,7 @@ rustc_interface = { path = "../rustc_interface" }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_span = { path = "../rustc_span" }
+rustc_typeck = { path = "../rustc_typeck" }
 
 [target.'cfg(windows)'.dependencies]
 winapi = { version = "0.3", features = ["consoleapi", "debugapi", "processenv"] }
diff --git a/compiler/rustc_driver/src/pretty.rs b/compiler/rustc_driver/src/pretty.rs
index bf131914b97cf..579ba43b6d8e7 100644
--- a/compiler/rustc_driver/src/pretty.rs
+++ b/compiler/rustc_driver/src/pretty.rs
@@ -14,6 +14,7 @@ use rustc_span::symbol::Ident;
 use rustc_span::FileName;
 
 use std::cell::Cell;
+use std::fmt::Write;
 use std::path::Path;
 
 pub use self::PpMode::*;
@@ -471,7 +472,6 @@ fn print_with_analysis(
     ofile: Option<&Path>,
 ) -> Result<(), ErrorReported> {
     tcx.analysis(())?;
-
     let out = match ppm {
         Mir => {
             let mut out = Vec::new();
@@ -486,8 +486,18 @@ fn print_with_analysis(
         }
 
         ThirTree => {
-            // FIXME(rust-lang/project-thir-unsafeck#8)
-            todo!()
+            let mut out = String::new();
+            abort_on_err(rustc_typeck::check_crate(tcx), tcx.sess);
+            debug!("pretty printing THIR tree");
+            for did in tcx.body_owners() {
+                let _ = writeln!(
+                    out,
+                    "{:?}:\n{}\n",
+                    did,
+                    tcx.thir_tree(ty::WithOptConstParam::unknown(did))
+                );
+            }
+            out
         }
 
         _ => unreachable!(),
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 0908b6a1763d5..2de836c058cf1 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -230,6 +230,12 @@ rustc_queries! {
         desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key.did.to_def_id()) }
     }
 
+    /// Create a THIR tree for debugging.
+    query thir_tree(key: ty::WithOptConstParam<LocalDefId>) -> String {
+        no_hash
+        desc { |tcx| "constructing THIR tree for `{}`", tcx.def_path_str(key.did.to_def_id()) }
+    }
+
     /// Set of all the `DefId`s in this crate that have MIR associated with
     /// them. This includes all the body owners, but also things like struct
     /// constructors.
diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs
index d2992f0bf186e..d0dd5116b75e1 100644
--- a/compiler/rustc_mir_build/src/lib.rs
+++ b/compiler/rustc_mir_build/src/lib.rs
@@ -30,4 +30,5 @@ pub fn provide(providers: &mut Providers) {
     providers.thir_check_unsafety = check_unsafety::thir_check_unsafety;
     providers.thir_check_unsafety_for_const_arg = check_unsafety::thir_check_unsafety_for_const_arg;
     providers.thir_body = thir::cx::thir_body;
+    providers.thir_tree = thir::cx::thir_tree;
 }
diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs
index 604e544286aef..5059dd939d92d 100644
--- a/compiler/rustc_mir_build/src/thir/cx/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs
@@ -30,6 +30,13 @@ crate fn thir_body<'tcx>(
     (tcx.alloc_steal_thir(cx.thir), expr)
 }
 
+crate fn thir_tree<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    owner_def: ty::WithOptConstParam<LocalDefId>,
+) -> String {
+    format!("{:#?}", thir_body(tcx, owner_def).0.steal())
+}
+
 struct Cx<'tcx> {
     tcx: TyCtxt<'tcx>,
     thir: Thir<'tcx>,

From 51df26eb5637ddd0012929fb21c3e51385434dd5 Mon Sep 17 00:00:00 2001
From: Smitty <me@smitop.com>
Date: Sat, 24 Jul 2021 17:33:43 -0400
Subject: [PATCH 2/2] Add test for -Z unpretty=thir-tree

---
 src/test/ui/thir-tree.rs     |  4 +++
 src/test/ui/thir-tree.stdout | 55 ++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)
 create mode 100644 src/test/ui/thir-tree.rs
 create mode 100644 src/test/ui/thir-tree.stdout

diff --git a/src/test/ui/thir-tree.rs b/src/test/ui/thir-tree.rs
new file mode 100644
index 0000000000000..32df7905adbad
--- /dev/null
+++ b/src/test/ui/thir-tree.rs
@@ -0,0 +1,4 @@
+// compile-flags: -Z unpretty=thir-tree
+// check-pass
+
+pub fn main() {}
diff --git a/src/test/ui/thir-tree.stdout b/src/test/ui/thir-tree.stdout
new file mode 100644
index 0000000000000..389eaf5e715b2
--- /dev/null
+++ b/src/test/ui/thir-tree.stdout
@@ -0,0 +1,55 @@
+DefId(0:3 ~ thir_tree[348d]::main):
+Thir {
+    arms: [],
+    exprs: [
+        Expr {
+            ty: (),
+            temp_lifetime: Some(
+                Node(2),
+            ),
+            span: $DIR/thir-tree.rs:4:15: 4:17 (#0),
+            kind: Block {
+                body: Block {
+                    targeted_by_break: false,
+                    region_scope: Node(1),
+                    opt_destruction_scope: None,
+                    span: $DIR/thir-tree.rs:4:15: 4:17 (#0),
+                    stmts: [],
+                    expr: None,
+                    safety_mode: Safe,
+                },
+            },
+        },
+        Expr {
+            ty: (),
+            temp_lifetime: Some(
+                Node(2),
+            ),
+            span: $DIR/thir-tree.rs:4:15: 4:17 (#0),
+            kind: Scope {
+                region_scope: Node(2),
+                lint_level: Explicit(
+                    HirId {
+                        owner: DefId(0:3 ~ thir_tree[348d]::main),
+                        local_id: 2,
+                    },
+                ),
+                value: e0,
+            },
+        },
+        Expr {
+            ty: (),
+            temp_lifetime: Some(
+                Node(2),
+            ),
+            span: $DIR/thir-tree.rs:4:15: 4:17 (#0),
+            kind: Scope {
+                region_scope: Destruction(2),
+                lint_level: Inherited,
+                value: e1,
+            },
+        },
+    ],
+    stmts: [],
+}
+