about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-07-28 09:01:11 +0000
committerbors <bors@rust-lang.org>2021-07-28 09:01:11 +0000
commiteba3228b2a9875d268ff3990903d04e19f6cdb0c (patch)
treedff9e4c1c59e7d7dde4e79bd203eb34d83807f1c
parentaea2e446f09b923d513013743b37b43fca7282dc (diff)
parent51df26eb5637ddd0012929fb21c3e51385434dd5 (diff)
downloadrust-eba3228b2a9875d268ff3990903d04e19f6cdb0c.tar.gz
rust-eba3228b2a9875d268ff3990903d04e19f6cdb0c.zip
Auto merge of #86251 - Smittyvb:thir-tree-again, r=oli-obk
Support -Z unpretty=thir-tree again

Currently `-Z unpretty=thir-tree` is broken after some THIR refactorings. This re-implements it, making it easier to debug THIR-related issues.

We have to do analyzes before getting the THIR, since trying to create THIR from invalid HIR can ICE. But doing those analyzes requires the THIR to be built and stolen. We work around this by creating a separate query to construct the THIR tree string representation.

Closes https://github.com/rust-lang/project-thir-unsafeck/issues/8, fixes #85552.
-rw-r--r--Cargo.lock1
-rw-r--r--compiler/rustc_driver/Cargo.toml1
-rw-r--r--compiler/rustc_driver/src/pretty.rs16
-rw-r--r--compiler/rustc_middle/src/query/mod.rs6
-rw-r--r--compiler/rustc_mir_build/src/lib.rs1
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/mod.rs7
-rw-r--r--src/test/ui/thir-tree.rs4
-rw-r--r--src/test/ui/thir-tree.stdout55
8 files changed, 88 insertions, 3 deletions
diff --git a/Cargo.lock b/Cargo.lock
index bd950310b73..40e4837c663 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 93c6ec04e4f..2bc163e7843 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 bf131914b97..579ba43b6d8 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 0908b6a1763..2de836c058c 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 d2992f0bf18..d0dd5116b75 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 604e544286a..5059dd939d9 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>,
diff --git a/src/test/ui/thir-tree.rs b/src/test/ui/thir-tree.rs
new file mode 100644
index 00000000000..32df7905adb
--- /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 00000000000..389eaf5e715
--- /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: [],
+}
+