Store THIR in IndexVecs instead of an Arena
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user