From 2a3442825335fe55ba30ef000f472bffb0ee9fe9 Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Sun, 7 Mar 2021 15:09:00 +0100 Subject: [PATCH 1/2] Make THIR data structures public --- compiler/rustc_mir_build/src/build/mod.rs | 3 +- compiler/rustc_mir_build/src/lib.rs | 2 +- compiler/rustc_mir_build/src/thir/cx/mod.rs | 2 +- compiler/rustc_mir_build/src/thir/mod.rs | 79 ++++++++++--------- .../rustc_mir_build/src/thir/pattern/mod.rs | 38 ++++----- 5 files changed, 62 insertions(+), 62 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index b633fe32674be..9c83c0d09aa8e 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -1,7 +1,6 @@ use crate::build; use crate::build::scope::DropKind; -use crate::thir::cx::build_thir; -use crate::thir::{Arena, BindingMode, Expr, LintLevel, Pat, PatKind}; +use crate::thir::{build_thir, Arena, BindingMode, Expr, LintLevel, Pat, PatKind}; use rustc_attr::{self as attr, UnwindAttr}; use rustc_errors::ErrorReported; use rustc_hir as hir; diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 0866892265bd9..b1591d8ba35f4 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -20,7 +20,7 @@ extern crate rustc_middle; mod build; mod lints; -mod thir; +pub mod thir; use rustc_middle::ty::query::Providers; diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 66c11ea95286d..fe8a58c008872 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -14,7 +14,7 @@ use rustc_middle::middle::region; use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; use rustc_middle::ty::{self, Ty, TyCtxt}; -crate fn build_thir<'thir, 'tcx>( +pub fn build_thir<'thir, 'tcx>( tcx: TyCtxt<'tcx>, owner_def: ty::WithOptConstParam, arena: &'thir Arena<'thir, 'tcx>, diff --git a/compiler/rustc_mir_build/src/thir/mod.rs b/compiler/rustc_mir_build/src/thir/mod.rs index 27a7e99951c3b..0c9df32c18803 100644 --- a/compiler/rustc_mir_build/src/thir/mod.rs +++ b/compiler/rustc_mir_build/src/thir/mod.rs @@ -18,36 +18,37 @@ use rustc_target::abi::VariantIdx; use rustc_target::asm::InlineAsmRegOrRegClass; crate mod constant; + crate mod cx; +pub use cx::build_thir; crate mod pattern; -crate use self::pattern::PatTyProj; -crate use self::pattern::{BindingMode, FieldPat, Pat, PatKind, PatRange}; +pub use self::pattern::{Ascription, BindingMode, FieldPat, Pat, PatKind, PatRange, PatTyProj}; mod arena; -crate use arena::Arena; +pub use arena::Arena; mod util; #[derive(Copy, Clone, Debug)] -crate enum LintLevel { +pub enum LintLevel { Inherited, Explicit(hir::HirId), } #[derive(Debug)] -crate struct Block<'thir, 'tcx> { - crate targeted_by_break: bool, - crate region_scope: region::Scope, - crate opt_destruction_scope: Option, - crate span: Span, - crate stmts: &'thir [Stmt<'thir, 'tcx>], - crate expr: Option<&'thir Expr<'thir, 'tcx>>, - crate safety_mode: BlockSafety, +pub struct Block<'thir, 'tcx> { + pub targeted_by_break: bool, + pub region_scope: region::Scope, + pub opt_destruction_scope: Option, + pub span: Span, + pub stmts: &'thir [Stmt<'thir, 'tcx>], + pub expr: Option<&'thir Expr<'thir, 'tcx>>, + pub safety_mode: BlockSafety, } #[derive(Copy, Clone, Debug)] -crate enum BlockSafety { +pub enum BlockSafety { Safe, ExplicitUnsafe(hir::HirId), PushUnsafe, @@ -55,13 +56,13 @@ crate enum BlockSafety { } #[derive(Debug)] -crate struct Stmt<'thir, 'tcx> { - crate kind: StmtKind<'thir, 'tcx>, - crate opt_destruction_scope: Option, +pub struct Stmt<'thir, 'tcx> { + pub kind: StmtKind<'thir, 'tcx>, + pub opt_destruction_scope: Option, } #[derive(Debug)] -crate enum StmtKind<'thir, 'tcx> { +pub enum StmtKind<'thir, 'tcx> { Expr { /// scope for this statement; may be used as lifetime of temporaries scope: region::Scope, @@ -111,23 +112,23 @@ rustc_data_structures::static_assert_size!(Expr<'_, '_>, 144); /// example, method calls and overloaded operators are absent: they are /// expected to be converted into `Expr::Call` instances. #[derive(Debug)] -crate struct Expr<'thir, 'tcx> { +pub struct Expr<'thir, 'tcx> { /// type of this expression - crate ty: Ty<'tcx>, + pub ty: Ty<'tcx>, /// lifetime of this expression if it should be spilled into a /// temporary; should be None only if in a constant context - crate temp_lifetime: Option, + pub temp_lifetime: Option, /// span of the expression in the source - crate span: Span, + pub span: Span, /// kind of expression - crate kind: ExprKind<'thir, 'tcx>, + pub kind: ExprKind<'thir, 'tcx>, } #[derive(Debug)] -crate enum ExprKind<'thir, 'tcx> { +pub enum ExprKind<'thir, 'tcx> { Scope { region_scope: region::Scope, lint_level: LintLevel, @@ -316,41 +317,41 @@ crate enum ExprKind<'thir, 'tcx> { } #[derive(Debug)] -crate struct FieldExpr<'thir, 'tcx> { - crate name: Field, - crate expr: &'thir Expr<'thir, 'tcx>, +pub struct FieldExpr<'thir, 'tcx> { + pub name: Field, + pub expr: &'thir Expr<'thir, 'tcx>, } #[derive(Debug)] -crate struct FruInfo<'thir, 'tcx> { - crate base: &'thir Expr<'thir, 'tcx>, - crate field_types: &'thir [Ty<'tcx>], +pub struct FruInfo<'thir, 'tcx> { + pub base: &'thir Expr<'thir, 'tcx>, + pub field_types: &'thir [Ty<'tcx>], } #[derive(Debug)] -crate struct Arm<'thir, 'tcx> { - crate pattern: Pat<'tcx>, - crate guard: Option>, - crate body: &'thir Expr<'thir, 'tcx>, - crate lint_level: LintLevel, - crate scope: region::Scope, - crate span: Span, +pub struct Arm<'thir, 'tcx> { + pub pattern: Pat<'tcx>, + pub guard: Option>, + pub body: &'thir Expr<'thir, 'tcx>, + pub lint_level: LintLevel, + pub scope: region::Scope, + pub span: Span, } #[derive(Debug)] -crate enum Guard<'thir, 'tcx> { +pub enum Guard<'thir, 'tcx> { If(&'thir Expr<'thir, 'tcx>), IfLet(Pat<'tcx>, &'thir Expr<'thir, 'tcx>), } #[derive(Copy, Clone, Debug)] -crate enum LogicalOp { +pub enum LogicalOp { And, Or, } #[derive(Debug)] -crate enum InlineAsmOperand<'thir, 'tcx> { +pub enum InlineAsmOperand<'thir, 'tcx> { In { reg: InlineAsmRegOrRegClass, expr: &'thir Expr<'thir, 'tcx>, diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 6e29e60b3034d..9ac79a37ac690 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -40,22 +40,22 @@ crate enum PatternError { } #[derive(Copy, Clone, Debug, PartialEq)] -crate enum BindingMode { +pub enum BindingMode { ByValue, ByRef(BorrowKind), } #[derive(Clone, Debug, PartialEq)] -crate struct FieldPat<'tcx> { - crate field: Field, - crate pattern: Pat<'tcx>, +pub struct FieldPat<'tcx> { + pub field: Field, + pub pattern: Pat<'tcx>, } #[derive(Clone, Debug, PartialEq)] -crate struct Pat<'tcx> { - crate ty: Ty<'tcx>, - crate span: Span, - crate kind: Box>, +pub struct Pat<'tcx> { + pub ty: Ty<'tcx>, + pub span: Span, + pub kind: Box>, } impl<'tcx> Pat<'tcx> { @@ -65,8 +65,8 @@ impl<'tcx> Pat<'tcx> { } #[derive(Copy, Clone, Debug, PartialEq)] -crate struct PatTyProj<'tcx> { - crate user_ty: CanonicalUserType<'tcx>, +pub struct PatTyProj<'tcx> { + pub user_ty: CanonicalUserType<'tcx>, } impl<'tcx> PatTyProj<'tcx> { @@ -92,8 +92,8 @@ impl<'tcx> PatTyProj<'tcx> { } #[derive(Copy, Clone, Debug, PartialEq)] -crate struct Ascription<'tcx> { - crate user_ty: PatTyProj<'tcx>, +pub struct Ascription<'tcx> { + pub user_ty: PatTyProj<'tcx>, /// Variance to use when relating the type `user_ty` to the **type of the value being /// matched**. Typically, this is `Variance::Covariant`, since the value being matched must /// have a type that is some subtype of the ascribed type. @@ -112,12 +112,12 @@ crate struct Ascription<'tcx> { /// requires that `&'static str <: T_x`, where `T_x` is the type of `x`. Really, we should /// probably be checking for a `PartialEq` impl instead, but this preserves the behavior /// of the old type-check for now. See #57280 for details. - crate variance: ty::Variance, - crate user_ty_span: Span, + pub variance: ty::Variance, + pub user_ty_span: Span, } #[derive(Clone, Debug, PartialEq)] -crate enum PatKind<'tcx> { +pub enum PatKind<'tcx> { Wild, AscribeUserType { @@ -195,10 +195,10 @@ crate enum PatKind<'tcx> { } #[derive(Copy, Clone, Debug, PartialEq)] -crate struct PatRange<'tcx> { - crate lo: &'tcx ty::Const<'tcx>, - crate hi: &'tcx ty::Const<'tcx>, - crate end: RangeEnd, +pub struct PatRange<'tcx> { + pub lo: &'tcx ty::Const<'tcx>, + pub hi: &'tcx ty::Const<'tcx>, + pub end: RangeEnd, } impl<'tcx> fmt::Display for Pat<'tcx> { From 6bf41476465278b82ad875ee15d88f371e51b1dc Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Sun, 7 Mar 2021 15:09:39 +0100 Subject: [PATCH 2/2] Add `-Z unpretty` flag for the THIR --- Cargo.lock | 2 ++ compiler/rustc_driver/Cargo.toml | 2 ++ compiler/rustc_driver/src/pretty.rs | 17 +++++++++++++++++ compiler/rustc_session/src/config.rs | 4 ++++ 4 files changed, 25 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 25039b5cbd92a..2c9eaebb5fdc2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3870,6 +3870,7 @@ dependencies = [ "rustc_metadata", "rustc_middle", "rustc_mir", + "rustc_mir_build", "rustc_parse", "rustc_plugin_impl", "rustc_save_analysis", @@ -3877,6 +3878,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..c521f2041d891 100644 --- a/compiler/rustc_driver/Cargo.toml +++ b/compiler/rustc_driver/Cargo.toml @@ -34,6 +34,8 @@ rustc_interface = { path = "../rustc_interface" } rustc_serialize = { path = "../rustc_serialize" } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } +rustc_mir_build = { path = "../rustc_mir_build" } +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 38c493a920d26..5512bd74453e5 100644 --- a/compiler/rustc_driver/src/pretty.rs +++ b/compiler/rustc_driver/src/pretty.rs @@ -9,12 +9,14 @@ use rustc_hir_pretty as pprust_hir; use rustc_middle::hir::map as hir_map; use rustc_middle::ty::{self, TyCtxt}; use rustc_mir::util::{write_mir_graphviz, write_mir_pretty}; +use rustc_mir_build::thir; use rustc_session::config::{Input, PpAstTreeMode, PpHirMode, PpMode, PpSourceMode}; use rustc_session::Session; 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::*; @@ -469,6 +471,21 @@ pub fn print_after_hir_lowering<'tcx>( format!("{:#?}", krate) }), + ThirTree => { + 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 hir = tcx.hir(); + let body = hir.body(hir.body_owned_by(hir.local_def_id_to_hir_id(did))); + let arena = thir::Arena::default(); + let thir = + thir::build_thir(tcx, ty::WithOptConstParam::unknown(did), &arena, &body.value); + let _ = writeln!(out, "{:?}:\n{:#?}\n", did, thir); + } + out + } + _ => unreachable!(), }; diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index f25828e21618f..c1be90efc7299 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2074,6 +2074,7 @@ fn parse_pretty( ("hir,identified", true) => Hir(PpHirMode::Identified), ("hir,typed", true) => Hir(PpHirMode::Typed), ("hir-tree", true) => HirTree, + ("thir-tree", true) => ThirTree, ("mir", true) => Mir, ("mir-cfg", true) => MirCFG, _ => { @@ -2265,6 +2266,8 @@ pub enum PpMode { Hir(PpHirMode), /// `-Zunpretty=hir-tree` HirTree, + /// `-Zunpretty=thir-tree` + ThirTree, /// `-Zunpretty=mir` Mir, /// `-Zunpretty=mir-cfg` @@ -2282,6 +2285,7 @@ impl PpMode { | AstTree(PpAstTreeMode::Expanded) | Hir(_) | HirTree + | ThirTree | Mir | MirCFG => true, }