Rollup merge of #82860 - LeSeulArtichaut:unpretty-thir, r=spastorino

Add `-Z unpretty` flag for the THIR

This adds a new perma-unstable flag, `-Zunpretty=thir-tree`, that dumps the raw THIR tree for each body in the crate.

Implements the THIR part of MCP rust-lang/compiler-team#408, helps with rust-lang/rustc-dev-guide#1062.
Depends on #82495, blocked on that. Only the two last commits are added by this PR.
r? ```@spastorino``` cc ```@estebank```
This commit is contained in:
Yuki Okushi 2021-03-12 08:55:14 +09:00 committed by GitHub
commit f183a3ec13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 87 additions and 62 deletions

View File

@ -3870,6 +3870,7 @@ dependencies = [
"rustc_metadata", "rustc_metadata",
"rustc_middle", "rustc_middle",
"rustc_mir", "rustc_mir",
"rustc_mir_build",
"rustc_parse", "rustc_parse",
"rustc_plugin_impl", "rustc_plugin_impl",
"rustc_save_analysis", "rustc_save_analysis",
@ -3877,6 +3878,7 @@ dependencies = [
"rustc_session", "rustc_session",
"rustc_span", "rustc_span",
"rustc_target", "rustc_target",
"rustc_typeck",
"tracing", "tracing",
"tracing-subscriber", "tracing-subscriber",
"tracing-tree", "tracing-tree",

View File

@ -34,6 +34,8 @@ rustc_interface = { path = "../rustc_interface" }
rustc_serialize = { path = "../rustc_serialize" } rustc_serialize = { path = "../rustc_serialize" }
rustc_ast = { path = "../rustc_ast" } rustc_ast = { path = "../rustc_ast" }
rustc_span = { path = "../rustc_span" } rustc_span = { path = "../rustc_span" }
rustc_mir_build = { path = "../rustc_mir_build" }
rustc_typeck = { path = "../rustc_typeck" }
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["consoleapi", "debugapi", "processenv"] } winapi = { version = "0.3", features = ["consoleapi", "debugapi", "processenv"] }

View File

@ -9,12 +9,14 @@ use rustc_hir_pretty as pprust_hir;
use rustc_middle::hir::map as hir_map; use rustc_middle::hir::map as hir_map;
use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::ty::{self, TyCtxt};
use rustc_mir::util::{write_mir_graphviz, write_mir_pretty}; 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::config::{Input, PpAstTreeMode, PpHirMode, PpMode, PpSourceMode};
use rustc_session::Session; use rustc_session::Session;
use rustc_span::symbol::Ident; use rustc_span::symbol::Ident;
use rustc_span::FileName; use rustc_span::FileName;
use std::cell::Cell; use std::cell::Cell;
use std::fmt::Write;
use std::path::Path; use std::path::Path;
pub use self::PpMode::*; pub use self::PpMode::*;
@ -469,6 +471,21 @@ pub fn print_after_hir_lowering<'tcx>(
format!("{:#?}", krate) 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!(), _ => unreachable!(),
}; };

View File

@ -1,7 +1,6 @@
use crate::build; use crate::build;
use crate::build::scope::DropKind; use crate::build::scope::DropKind;
use crate::thir::cx::build_thir; use crate::thir::{build_thir, Arena, BindingMode, Expr, LintLevel, Pat, PatKind};
use crate::thir::{Arena, BindingMode, Expr, LintLevel, Pat, PatKind};
use rustc_attr::{self as attr, UnwindAttr}; use rustc_attr::{self as attr, UnwindAttr};
use rustc_errors::ErrorReported; use rustc_errors::ErrorReported;
use rustc_hir as hir; use rustc_hir as hir;

View File

@ -20,7 +20,7 @@ extern crate rustc_middle;
mod build; mod build;
mod lints; mod lints;
mod thir; pub mod thir;
use rustc_middle::ty::query::Providers; use rustc_middle::ty::query::Providers;

View File

@ -14,7 +14,7 @@ use rustc_middle::middle::region;
use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{self, Ty, TyCtxt};
crate fn build_thir<'thir, 'tcx>( pub fn build_thir<'thir, 'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
owner_def: ty::WithOptConstParam<LocalDefId>, owner_def: ty::WithOptConstParam<LocalDefId>,
arena: &'thir Arena<'thir, 'tcx>, arena: &'thir Arena<'thir, 'tcx>,

View File

@ -18,36 +18,37 @@ use rustc_target::abi::VariantIdx;
use rustc_target::asm::InlineAsmRegOrRegClass; use rustc_target::asm::InlineAsmRegOrRegClass;
crate mod constant; crate mod constant;
crate mod cx; crate mod cx;
pub use cx::build_thir;
crate mod pattern; crate mod pattern;
crate use self::pattern::PatTyProj; pub use self::pattern::{Ascription, BindingMode, FieldPat, Pat, PatKind, PatRange, PatTyProj};
crate use self::pattern::{BindingMode, FieldPat, Pat, PatKind, PatRange};
mod arena; mod arena;
crate use arena::Arena; pub use arena::Arena;
mod util; mod util;
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
crate enum LintLevel { pub enum LintLevel {
Inherited, Inherited,
Explicit(hir::HirId), Explicit(hir::HirId),
} }
#[derive(Debug)] #[derive(Debug)]
crate struct Block<'thir, 'tcx> { pub struct Block<'thir, 'tcx> {
crate targeted_by_break: bool, pub targeted_by_break: bool,
crate region_scope: region::Scope, pub region_scope: region::Scope,
crate opt_destruction_scope: Option<region::Scope>, pub opt_destruction_scope: Option<region::Scope>,
crate span: Span, pub span: Span,
crate stmts: &'thir [Stmt<'thir, 'tcx>], pub stmts: &'thir [Stmt<'thir, 'tcx>],
crate expr: Option<&'thir Expr<'thir, 'tcx>>, pub expr: Option<&'thir Expr<'thir, 'tcx>>,
crate safety_mode: BlockSafety, pub safety_mode: BlockSafety,
} }
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
crate enum BlockSafety { pub enum BlockSafety {
Safe, Safe,
ExplicitUnsafe(hir::HirId), ExplicitUnsafe(hir::HirId),
PushUnsafe, PushUnsafe,
@ -55,13 +56,13 @@ crate enum BlockSafety {
} }
#[derive(Debug)] #[derive(Debug)]
crate struct Stmt<'thir, 'tcx> { pub struct Stmt<'thir, 'tcx> {
crate kind: StmtKind<'thir, 'tcx>, pub kind: StmtKind<'thir, 'tcx>,
crate opt_destruction_scope: Option<region::Scope>, pub opt_destruction_scope: Option<region::Scope>,
} }
#[derive(Debug)] #[derive(Debug)]
crate enum StmtKind<'thir, 'tcx> { pub enum StmtKind<'thir, 'tcx> {
Expr { Expr {
/// scope for this statement; may be used as lifetime of temporaries /// scope for this statement; may be used as lifetime of temporaries
scope: region::Scope, 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 /// example, method calls and overloaded operators are absent: they are
/// expected to be converted into `Expr::Call` instances. /// expected to be converted into `Expr::Call` instances.
#[derive(Debug)] #[derive(Debug)]
crate struct Expr<'thir, 'tcx> { pub struct Expr<'thir, 'tcx> {
/// type of this expression /// type of this expression
crate ty: Ty<'tcx>, pub ty: Ty<'tcx>,
/// lifetime of this expression if it should be spilled into a /// lifetime of this expression if it should be spilled into a
/// temporary; should be None only if in a constant context /// temporary; should be None only if in a constant context
crate temp_lifetime: Option<region::Scope>, pub temp_lifetime: Option<region::Scope>,
/// span of the expression in the source /// span of the expression in the source
crate span: Span, pub span: Span,
/// kind of expression /// kind of expression
crate kind: ExprKind<'thir, 'tcx>, pub kind: ExprKind<'thir, 'tcx>,
} }
#[derive(Debug)] #[derive(Debug)]
crate enum ExprKind<'thir, 'tcx> { pub enum ExprKind<'thir, 'tcx> {
Scope { Scope {
region_scope: region::Scope, region_scope: region::Scope,
lint_level: LintLevel, lint_level: LintLevel,
@ -316,41 +317,41 @@ crate enum ExprKind<'thir, 'tcx> {
} }
#[derive(Debug)] #[derive(Debug)]
crate struct FieldExpr<'thir, 'tcx> { pub struct FieldExpr<'thir, 'tcx> {
crate name: Field, pub name: Field,
crate expr: &'thir Expr<'thir, 'tcx>, pub expr: &'thir Expr<'thir, 'tcx>,
} }
#[derive(Debug)] #[derive(Debug)]
crate struct FruInfo<'thir, 'tcx> { pub struct FruInfo<'thir, 'tcx> {
crate base: &'thir Expr<'thir, 'tcx>, pub base: &'thir Expr<'thir, 'tcx>,
crate field_types: &'thir [Ty<'tcx>], pub field_types: &'thir [Ty<'tcx>],
} }
#[derive(Debug)] #[derive(Debug)]
crate struct Arm<'thir, 'tcx> { pub struct Arm<'thir, 'tcx> {
crate pattern: Pat<'tcx>, pub pattern: Pat<'tcx>,
crate guard: Option<Guard<'thir, 'tcx>>, pub guard: Option<Guard<'thir, 'tcx>>,
crate body: &'thir Expr<'thir, 'tcx>, pub body: &'thir Expr<'thir, 'tcx>,
crate lint_level: LintLevel, pub lint_level: LintLevel,
crate scope: region::Scope, pub scope: region::Scope,
crate span: Span, pub span: Span,
} }
#[derive(Debug)] #[derive(Debug)]
crate enum Guard<'thir, 'tcx> { pub enum Guard<'thir, 'tcx> {
If(&'thir Expr<'thir, 'tcx>), If(&'thir Expr<'thir, 'tcx>),
IfLet(Pat<'tcx>, &'thir Expr<'thir, 'tcx>), IfLet(Pat<'tcx>, &'thir Expr<'thir, 'tcx>),
} }
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
crate enum LogicalOp { pub enum LogicalOp {
And, And,
Or, Or,
} }
#[derive(Debug)] #[derive(Debug)]
crate enum InlineAsmOperand<'thir, 'tcx> { pub enum InlineAsmOperand<'thir, 'tcx> {
In { In {
reg: InlineAsmRegOrRegClass, reg: InlineAsmRegOrRegClass,
expr: &'thir Expr<'thir, 'tcx>, expr: &'thir Expr<'thir, 'tcx>,

View File

@ -40,22 +40,22 @@ crate enum PatternError {
} }
#[derive(Copy, Clone, Debug, PartialEq)] #[derive(Copy, Clone, Debug, PartialEq)]
crate enum BindingMode { pub enum BindingMode {
ByValue, ByValue,
ByRef(BorrowKind), ByRef(BorrowKind),
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
crate struct FieldPat<'tcx> { pub struct FieldPat<'tcx> {
crate field: Field, pub field: Field,
crate pattern: Pat<'tcx>, pub pattern: Pat<'tcx>,
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
crate struct Pat<'tcx> { pub struct Pat<'tcx> {
crate ty: Ty<'tcx>, pub ty: Ty<'tcx>,
crate span: Span, pub span: Span,
crate kind: Box<PatKind<'tcx>>, pub kind: Box<PatKind<'tcx>>,
} }
impl<'tcx> Pat<'tcx> { impl<'tcx> Pat<'tcx> {
@ -65,8 +65,8 @@ impl<'tcx> Pat<'tcx> {
} }
#[derive(Copy, Clone, Debug, PartialEq)] #[derive(Copy, Clone, Debug, PartialEq)]
crate struct PatTyProj<'tcx> { pub struct PatTyProj<'tcx> {
crate user_ty: CanonicalUserType<'tcx>, pub user_ty: CanonicalUserType<'tcx>,
} }
impl<'tcx> PatTyProj<'tcx> { impl<'tcx> PatTyProj<'tcx> {
@ -92,8 +92,8 @@ impl<'tcx> PatTyProj<'tcx> {
} }
#[derive(Copy, Clone, Debug, PartialEq)] #[derive(Copy, Clone, Debug, PartialEq)]
crate struct Ascription<'tcx> { pub struct Ascription<'tcx> {
crate user_ty: PatTyProj<'tcx>, pub user_ty: PatTyProj<'tcx>,
/// Variance to use when relating the type `user_ty` to the **type of the value being /// 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 /// matched**. Typically, this is `Variance::Covariant`, since the value being matched must
/// have a type that is some subtype of the ascribed type. /// 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 /// 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 /// probably be checking for a `PartialEq` impl instead, but this preserves the behavior
/// of the old type-check for now. See #57280 for details. /// of the old type-check for now. See #57280 for details.
crate variance: ty::Variance, pub variance: ty::Variance,
crate user_ty_span: Span, pub user_ty_span: Span,
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
crate enum PatKind<'tcx> { pub enum PatKind<'tcx> {
Wild, Wild,
AscribeUserType { AscribeUserType {
@ -195,10 +195,10 @@ crate enum PatKind<'tcx> {
} }
#[derive(Copy, Clone, Debug, PartialEq)] #[derive(Copy, Clone, Debug, PartialEq)]
crate struct PatRange<'tcx> { pub struct PatRange<'tcx> {
crate lo: &'tcx ty::Const<'tcx>, pub lo: &'tcx ty::Const<'tcx>,
crate hi: &'tcx ty::Const<'tcx>, pub hi: &'tcx ty::Const<'tcx>,
crate end: RangeEnd, pub end: RangeEnd,
} }
impl<'tcx> fmt::Display for Pat<'tcx> { impl<'tcx> fmt::Display for Pat<'tcx> {

View File

@ -2074,6 +2074,7 @@ fn parse_pretty(
("hir,identified", true) => Hir(PpHirMode::Identified), ("hir,identified", true) => Hir(PpHirMode::Identified),
("hir,typed", true) => Hir(PpHirMode::Typed), ("hir,typed", true) => Hir(PpHirMode::Typed),
("hir-tree", true) => HirTree, ("hir-tree", true) => HirTree,
("thir-tree", true) => ThirTree,
("mir", true) => Mir, ("mir", true) => Mir,
("mir-cfg", true) => MirCFG, ("mir-cfg", true) => MirCFG,
_ => { _ => {
@ -2265,6 +2266,8 @@ pub enum PpMode {
Hir(PpHirMode), Hir(PpHirMode),
/// `-Zunpretty=hir-tree` /// `-Zunpretty=hir-tree`
HirTree, HirTree,
/// `-Zunpretty=thir-tree`
ThirTree,
/// `-Zunpretty=mir` /// `-Zunpretty=mir`
Mir, Mir,
/// `-Zunpretty=mir-cfg` /// `-Zunpretty=mir-cfg`
@ -2282,6 +2285,7 @@ impl PpMode {
| AstTree(PpAstTreeMode::Expanded) | AstTree(PpAstTreeMode::Expanded)
| Hir(_) | Hir(_)
| HirTree | HirTree
| ThirTree
| Mir | Mir
| MirCFG => true, | MirCFG => true,
} }