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:
commit
f183a3ec13
|
@ -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",
|
||||||
|
|
|
@ -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"] }
|
||||||
|
|
|
@ -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!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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>,
|
||||||
|
|
|
@ -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>,
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue