Store THIR in IndexVecs instead of an Arena

This commit is contained in:
LeSeulArtichaut
2021-04-03 19:58:46 +02:00
parent e78bccfbc0
commit dc3eabd487
18 changed files with 686 additions and 633 deletions

View File

@@ -7,6 +7,8 @@
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_index::newtype_index;
use rustc_index::vec::IndexVec;
use rustc_middle::infer::canonical::Canonical;
use rustc_middle::middle::region;
use rustc_middle::mir::{BinOp, BorrowKind, FakeReadCause, Field, UnOp};
@@ -17,6 +19,8 @@ use rustc_span::Span;
use rustc_target::abi::VariantIdx;
use rustc_target::asm::InlineAsmRegOrRegClass;
use std::ops::Index;
crate mod constant;
crate mod cx;
@@ -25,12 +29,62 @@ pub use cx::build_thir;
crate mod pattern;
pub use self::pattern::{Ascription, BindingMode, FieldPat, Pat, PatKind, PatRange, PatTyProj};
mod arena;
pub use arena::Arena;
mod util;
pub mod visit;
newtype_index! {
pub struct ArmId {
DEBUG_FORMAT = "a{}"
}
}
newtype_index! {
pub struct ExprId {
DEBUG_FORMAT = "e{}"
}
}
newtype_index! {
pub struct StmtId {
DEBUG_FORMAT = "s{}"
}
}
macro_rules! thir_with_elements {
($($name:ident: $id:ty => $value:ty,)*) => {
pub struct Thir<'tcx> {
$(
$name: IndexVec<$id, $value>,
)*
}
impl<'tcx> Thir<'tcx> {
fn new() -> Thir<'tcx> {
Thir {
$(
$name: IndexVec::new(),
)*
}
}
}
$(
impl<'tcx> Index<$id> for Thir<'tcx> {
type Output = $value;
fn index(&self, index: $id) -> &Self::Output {
&self.$name[index]
}
}
)*
}
}
thir_with_elements! {
arms: ArmId => Arm<'tcx>,
exprs: ExprId => Expr<'tcx>,
stmts: StmtId => Stmt<'tcx>,
}
#[derive(Copy, Clone, Debug)]
pub enum LintLevel {
Inherited,
@@ -38,13 +92,13 @@ pub enum LintLevel {
}
#[derive(Debug)]
pub struct Block<'thir, 'tcx> {
pub struct Block {
pub targeted_by_break: bool,
pub region_scope: region::Scope,
pub opt_destruction_scope: Option<region::Scope>,
pub span: Span,
pub stmts: &'thir [Stmt<'thir, 'tcx>],
pub expr: Option<&'thir Expr<'thir, 'tcx>>,
pub stmts: Box<[StmtId]>,
pub expr: Option<ExprId>,
pub safety_mode: BlockSafety,
}
@@ -57,19 +111,19 @@ pub enum BlockSafety {
}
#[derive(Debug)]
pub struct Stmt<'thir, 'tcx> {
pub kind: StmtKind<'thir, 'tcx>,
pub struct Stmt<'tcx> {
pub kind: StmtKind<'tcx>,
pub opt_destruction_scope: Option<region::Scope>,
}
#[derive(Debug)]
pub enum StmtKind<'thir, 'tcx> {
pub enum StmtKind<'tcx> {
Expr {
/// scope for this statement; may be used as lifetime of temporaries
scope: region::Scope,
/// expression being evaluated in this statement
expr: &'thir Expr<'thir, 'tcx>,
expr: ExprId,
},
Let {
@@ -87,7 +141,7 @@ pub enum StmtKind<'thir, 'tcx> {
pattern: Pat<'tcx>,
/// let pat: ty = <INIT> ...
initializer: Option<&'thir Expr<'thir, 'tcx>>,
initializer: Option<ExprId>,
/// the lint level for this let-statement
lint_level: LintLevel,
@@ -96,12 +150,12 @@ pub enum StmtKind<'thir, 'tcx> {
// `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(Expr<'_, '_>, 144);
rustc_data_structures::static_assert_size!(Expr<'_>, 144);
/// The Thir trait implementor lowers their expressions (`&'tcx H::Expr`)
/// into instances of this `Expr` enum. This lowering can be done
/// basically as lazily or as eagerly as desired: every recursive
/// reference to an expression in this enum is an `&'thir Expr<'thir, 'tcx>`, which
/// reference to an expression in this enum is an `ExprId`, which
/// may in turn be another instance of this enum (boxed), or else an
/// unlowered `&'tcx H::Expr`. Note that instances of `Expr` are very
/// short-lived. They are created by `Thir::to_expr`, analyzed and
@@ -113,7 +167,7 @@ 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)]
pub struct Expr<'thir, 'tcx> {
pub struct Expr<'tcx> {
/// type of this expression
pub ty: Ty<'tcx>,
@@ -125,28 +179,28 @@ pub struct Expr<'thir, 'tcx> {
pub span: Span,
/// kind of expression
pub kind: ExprKind<'thir, 'tcx>,
pub kind: ExprKind<'tcx>,
}
#[derive(Debug)]
pub enum ExprKind<'thir, 'tcx> {
pub enum ExprKind<'tcx> {
Scope {
region_scope: region::Scope,
lint_level: LintLevel,
value: &'thir Expr<'thir, 'tcx>,
value: ExprId,
},
Box {
value: &'thir Expr<'thir, 'tcx>,
value: ExprId,
},
If {
cond: &'thir Expr<'thir, 'tcx>,
then: &'thir Expr<'thir, 'tcx>,
else_opt: Option<&'thir Expr<'thir, 'tcx>>,
cond: ExprId,
then: ExprId,
else_opt: Option<ExprId>,
},
Call {
ty: Ty<'tcx>,
fun: &'thir Expr<'thir, 'tcx>,
args: &'thir [Expr<'thir, 'tcx>],
fun: ExprId,
args: Box<[ExprId]>,
/// Whether this is from a call in HIR, rather than from an overloaded
/// operator. `true` for overloaded function call.
from_hir_call: bool,
@@ -155,62 +209,62 @@ pub enum ExprKind<'thir, 'tcx> {
fn_span: Span,
},
Deref {
arg: &'thir Expr<'thir, 'tcx>,
arg: ExprId,
}, // NOT overloaded!
Binary {
op: BinOp,
lhs: &'thir Expr<'thir, 'tcx>,
rhs: &'thir Expr<'thir, 'tcx>,
lhs: ExprId,
rhs: ExprId,
}, // NOT overloaded!
LogicalOp {
op: LogicalOp,
lhs: &'thir Expr<'thir, 'tcx>,
rhs: &'thir Expr<'thir, 'tcx>,
lhs: ExprId,
rhs: ExprId,
}, // NOT overloaded!
// LogicalOp is distinct from BinaryOp because of lazy evaluation of the operands.
Unary {
op: UnOp,
arg: &'thir Expr<'thir, 'tcx>,
arg: ExprId,
}, // NOT overloaded!
Cast {
source: &'thir Expr<'thir, 'tcx>,
source: ExprId,
},
Use {
source: &'thir Expr<'thir, 'tcx>,
source: ExprId,
}, // Use a lexpr to get a vexpr.
NeverToAny {
source: &'thir Expr<'thir, 'tcx>,
source: ExprId,
},
Pointer {
cast: PointerCast,
source: &'thir Expr<'thir, 'tcx>,
source: ExprId,
},
Loop {
body: &'thir Expr<'thir, 'tcx>,
body: ExprId,
},
Match {
scrutinee: &'thir Expr<'thir, 'tcx>,
arms: &'thir [Arm<'thir, 'tcx>],
scrutinee: ExprId,
arms: Box<[ArmId]>,
},
Block {
body: Block<'thir, 'tcx>,
body: Block,
},
Assign {
lhs: &'thir Expr<'thir, 'tcx>,
rhs: &'thir Expr<'thir, 'tcx>,
lhs: ExprId,
rhs: ExprId,
},
AssignOp {
op: BinOp,
lhs: &'thir Expr<'thir, 'tcx>,
rhs: &'thir Expr<'thir, 'tcx>,
lhs: ExprId,
rhs: ExprId,
},
Field {
lhs: &'thir Expr<'thir, 'tcx>,
lhs: ExprId,
name: Field,
},
Index {
lhs: &'thir Expr<'thir, 'tcx>,
index: &'thir Expr<'thir, 'tcx>,
lhs: ExprId,
index: ExprId,
},
VarRef {
id: hir::HirId,
@@ -225,35 +279,35 @@ pub enum ExprKind<'thir, 'tcx> {
},
Borrow {
borrow_kind: BorrowKind,
arg: &'thir Expr<'thir, 'tcx>,
arg: ExprId,
},
/// A `&raw [const|mut] $place_expr` raw borrow resulting in type `*[const|mut] T`.
AddressOf {
mutability: hir::Mutability,
arg: &'thir Expr<'thir, 'tcx>,
arg: ExprId,
},
Break {
label: region::Scope,
value: Option<&'thir Expr<'thir, 'tcx>>,
value: Option<ExprId>,
},
Continue {
label: region::Scope,
},
Return {
value: Option<&'thir Expr<'thir, 'tcx>>,
value: Option<ExprId>,
},
ConstBlock {
value: &'tcx Const<'tcx>,
},
Repeat {
value: &'thir Expr<'thir, 'tcx>,
value: ExprId,
count: &'tcx Const<'tcx>,
},
Array {
fields: &'thir [Expr<'thir, 'tcx>],
fields: Box<[ExprId]>,
},
Tuple {
fields: &'thir [Expr<'thir, 'tcx>],
fields: Box<[ExprId]>,
},
Adt {
adt_def: &'tcx AdtDef,
@@ -264,25 +318,25 @@ pub enum ExprKind<'thir, 'tcx> {
/// Bar::<T> { ... }`.
user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
fields: &'thir [FieldExpr<'thir, 'tcx>],
base: Option<FruInfo<'thir, 'tcx>>,
fields: Box<[FieldExpr]>,
base: Option<FruInfo<'tcx>>,
},
PlaceTypeAscription {
source: &'thir Expr<'thir, 'tcx>,
source: ExprId,
/// Type that the user gave to this expression
user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
},
ValueTypeAscription {
source: &'thir Expr<'thir, 'tcx>,
source: ExprId,
/// Type that the user gave to this expression
user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
},
Closure {
closure_id: DefId,
substs: UpvarSubsts<'tcx>,
upvars: &'thir [Expr<'thir, 'tcx>],
upvars: Box<[ExprId]>,
movability: Option<hir::Movability>,
fake_reads: Vec<(&'thir Expr<'thir, 'tcx>, FakeReadCause, hir::HirId)>,
fake_reads: Vec<(ExprId, FakeReadCause, hir::HirId)>,
},
Literal {
literal: &'tcx Const<'tcx>,
@@ -302,7 +356,7 @@ pub enum ExprKind<'thir, 'tcx> {
},
InlineAsm {
template: &'tcx [InlineAsmTemplatePiece],
operands: &'thir [InlineAsmOperand<'thir, 'tcx>],
operands: Box<[InlineAsmOperand<'tcx>]>,
options: InlineAsmOptions,
line_spans: &'tcx [Span],
},
@@ -310,40 +364,40 @@ pub enum ExprKind<'thir, 'tcx> {
ThreadLocalRef(DefId),
LlvmInlineAsm {
asm: &'tcx hir::LlvmInlineAsmInner,
outputs: &'thir [Expr<'thir, 'tcx>],
inputs: &'thir [Expr<'thir, 'tcx>],
outputs: Box<[ExprId]>,
inputs: Box<[ExprId]>,
},
Yield {
value: &'thir Expr<'thir, 'tcx>,
value: ExprId,
},
}
#[derive(Debug)]
pub struct FieldExpr<'thir, 'tcx> {
pub struct FieldExpr {
pub name: Field,
pub expr: &'thir Expr<'thir, 'tcx>,
pub expr: ExprId,
}
#[derive(Debug)]
pub struct FruInfo<'thir, 'tcx> {
pub base: &'thir Expr<'thir, 'tcx>,
pub field_types: &'thir [Ty<'tcx>],
pub struct FruInfo<'tcx> {
pub base: ExprId,
pub field_types: Box<[Ty<'tcx>]>,
}
#[derive(Debug)]
pub struct Arm<'thir, 'tcx> {
pub struct Arm<'tcx> {
pub pattern: Pat<'tcx>,
pub guard: Option<Guard<'thir, 'tcx>>,
pub body: &'thir Expr<'thir, 'tcx>,
pub guard: Option<Guard<'tcx>>,
pub body: ExprId,
pub lint_level: LintLevel,
pub scope: region::Scope,
pub span: Span,
}
#[derive(Debug)]
pub enum Guard<'thir, 'tcx> {
If(&'thir Expr<'thir, 'tcx>),
IfLet(Pat<'tcx>, &'thir Expr<'thir, 'tcx>),
pub enum Guard<'tcx> {
If(ExprId),
IfLet(Pat<'tcx>, ExprId),
}
#[derive(Copy, Clone, Debug)]
@@ -353,33 +407,33 @@ pub enum LogicalOp {
}
#[derive(Debug)]
pub enum InlineAsmOperand<'thir, 'tcx> {
pub enum InlineAsmOperand<'tcx> {
In {
reg: InlineAsmRegOrRegClass,
expr: &'thir Expr<'thir, 'tcx>,
expr: ExprId,
},
Out {
reg: InlineAsmRegOrRegClass,
late: bool,
expr: Option<&'thir Expr<'thir, 'tcx>>,
expr: Option<ExprId>,
},
InOut {
reg: InlineAsmRegOrRegClass,
late: bool,
expr: &'thir Expr<'thir, 'tcx>,
expr: ExprId,
},
SplitInOut {
reg: InlineAsmRegOrRegClass,
late: bool,
in_expr: &'thir Expr<'thir, 'tcx>,
out_expr: Option<&'thir Expr<'thir, 'tcx>>,
in_expr: ExprId,
out_expr: Option<ExprId>,
},
Const {
value: &'tcx Const<'tcx>,
span: Span,
},
SymFn {
expr: &'thir Expr<'thir, 'tcx>,
expr: ExprId,
},
SymStatic {
def_id: DefId,