use self::cx::Cx;
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_middle::infer::canonical::Canonical;
use rustc_middle::middle::region;
use rustc_middle::mir::{BinOp, BorrowKind, Field, UnOp};
use rustc_middle::ty::adjustment::PointerCast;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{AdtDef, Const, Ty, UpvarSubsts, UserType};
use rustc_span::Span;
use rustc_target::abi::VariantIdx;
use rustc_target::asm::InlineAsmRegOrRegClass;
crate mod constant;
crate mod cx;
crate mod pattern;
crate use self::pattern::PatTyProj;
crate use self::pattern::{BindingMode, FieldPat, Pat, PatKind, PatRange};
mod util;
#[derive(Copy, Clone, Debug)]
crate enum LintLevel {
Inherited,
Explicit(hir::HirId),
}
#[derive(Clone, Debug)]
crate struct Block<'tcx> {
crate targeted_by_break: bool,
crate region_scope: region::Scope,
crate opt_destruction_scope: Option<region::Scope>,
crate span: Span,
crate stmts: Vec<StmtRef<'tcx>>,
crate expr: Option<ExprRef<'tcx>>,
crate safety_mode: BlockSafety,
}
#[derive(Copy, Clone, Debug)]
crate enum BlockSafety {
Safe,
ExplicitUnsafe(hir::HirId),
PushUnsafe,
PopUnsafe,
}
#[derive(Clone, Debug)]
crate enum StmtRef<'tcx> {
Mirror(Box<Stmt<'tcx>>),
}
#[derive(Clone, Debug)]
crate struct Stmt<'tcx> {
crate kind: StmtKind<'tcx>,
crate opt_destruction_scope: Option<region::Scope>,
}
#[derive(Clone, Debug)]
crate enum StmtKind<'tcx> {
Expr {
scope: region::Scope,
expr: ExprRef<'tcx>,
},
Let {
remainder_scope: region::Scope,
init_scope: region::Scope,
pattern: Pat<'tcx>,
initializer: Option<ExprRef<'tcx>>,
lint_level: LintLevel,
},
}
#[cfg(target_arch = "x86_64")]
rustc_data_structures::static_assert_size!(Expr<'_>, 168);
#[derive(Clone, Debug)]
crate struct Expr<'tcx> {
crate ty: Ty<'tcx>,
crate temp_lifetime: Option<region::Scope>,
crate span: Span,
crate kind: ExprKind<'tcx>,
}
#[derive(Clone, Debug)]
crate enum ExprKind<'tcx> {
Scope {
region_scope: region::Scope,
lint_level: LintLevel,
value: ExprRef<'tcx>,
},
Box {
value: ExprRef<'tcx>,
},
Call {
ty: Ty<'tcx>,
fun: ExprRef<'tcx>,
args: Vec<ExprRef<'tcx>>,
from_hir_call: bool,
fn_span: Span,
},
Deref {
arg: ExprRef<'tcx>,
},
Binary {
op: BinOp,
lhs: ExprRef<'tcx>,
rhs: ExprRef<'tcx>,
},
LogicalOp {
op: LogicalOp,
lhs: ExprRef<'tcx>,
rhs: ExprRef<'tcx>,
},
Unary {
op: UnOp,
arg: ExprRef<'tcx>,
},
Cast {
source: ExprRef<'tcx>,
},
Use {
source: ExprRef<'tcx>,
},
NeverToAny {
source: ExprRef<'tcx>,
},
Pointer {
cast: PointerCast,
source: ExprRef<'tcx>,
},
Loop {
body: ExprRef<'tcx>,
},
Match {
scrutinee: ExprRef<'tcx>,
arms: Vec<Arm<'tcx>>,
},
Block {
body: &'tcx hir::Block<'tcx>,
},
Assign {
lhs: ExprRef<'tcx>,
rhs: ExprRef<'tcx>,
},
AssignOp {
op: BinOp,
lhs: ExprRef<'tcx>,
rhs: ExprRef<'tcx>,
},
Field {
lhs: ExprRef<'tcx>,
name: Field,
},
Index {
lhs: ExprRef<'tcx>,
index: ExprRef<'tcx>,
},
VarRef {
id: hir::HirId,
},
UpvarRef {
closure_def_id: DefId,
var_hir_id: hir::HirId,
},
Borrow {
borrow_kind: BorrowKind,
arg: ExprRef<'tcx>,
},
AddressOf {
mutability: hir::Mutability,
arg: ExprRef<'tcx>,
},
Break {
label: region::Scope,
value: Option<ExprRef<'tcx>>,
},
Continue {
label: region::Scope,
},
Return {
value: Option<ExprRef<'tcx>>,
},
ConstBlock {
value: &'tcx Const<'tcx>,
},
Repeat {
value: ExprRef<'tcx>,
count: &'tcx Const<'tcx>,
},
Array {
fields: Vec<ExprRef<'tcx>>,
},
Tuple {
fields: Vec<ExprRef<'tcx>>,
},
Adt {
adt_def: &'tcx AdtDef,
variant_index: VariantIdx,
substs: SubstsRef<'tcx>,
user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
fields: Vec<FieldExprRef<'tcx>>,
base: Option<FruInfo<'tcx>>,
},
PlaceTypeAscription {
source: ExprRef<'tcx>,
user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
},
ValueTypeAscription {
source: ExprRef<'tcx>,
user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
},
Closure {
closure_id: DefId,
substs: UpvarSubsts<'tcx>,
upvars: Vec<ExprRef<'tcx>>,
movability: Option<hir::Movability>,
},
Literal {
literal: &'tcx Const<'tcx>,
user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
const_id: Option<DefId>,
},
StaticRef {
literal: &'tcx Const<'tcx>,
def_id: DefId,
},
InlineAsm {
template: &'tcx [InlineAsmTemplatePiece],
operands: Vec<InlineAsmOperand<'tcx>>,
options: InlineAsmOptions,
line_spans: &'tcx [Span],
},
ThreadLocalRef(DefId),
LlvmInlineAsm {
asm: &'tcx hir::LlvmInlineAsmInner,
outputs: Vec<ExprRef<'tcx>>,
inputs: Vec<ExprRef<'tcx>>,
},
Yield {
value: ExprRef<'tcx>,
},
}
#[derive(Clone, Debug)]
crate enum ExprRef<'tcx> {
Thir(&'tcx hir::Expr<'tcx>),
Mirror(Box<Expr<'tcx>>),
}
#[derive(Clone, Debug)]
crate struct FieldExprRef<'tcx> {
crate name: Field,
crate expr: ExprRef<'tcx>,
}
#[derive(Clone, Debug)]
crate struct FruInfo<'tcx> {
crate base: ExprRef<'tcx>,
crate field_types: Vec<Ty<'tcx>>,
}
#[derive(Clone, Debug)]
crate struct Arm<'tcx> {
crate pattern: Pat<'tcx>,
crate guard: Option<Guard<'tcx>>,
crate body: ExprRef<'tcx>,
crate lint_level: LintLevel,
crate scope: region::Scope,
crate span: Span,
}
#[derive(Clone, Debug)]
crate enum Guard<'tcx> {
If(ExprRef<'tcx>),
}
#[derive(Copy, Clone, Debug)]
crate enum LogicalOp {
And,
Or,
}
impl<'tcx> ExprRef<'tcx> {
crate fn span(&self) -> Span {
match self {
ExprRef::Thir(expr) => expr.span,
ExprRef::Mirror(expr) => expr.span,
}
}
}
#[derive(Clone, Debug)]
crate enum InlineAsmOperand<'tcx> {
In {
reg: InlineAsmRegOrRegClass,
expr: ExprRef<'tcx>,
},
Out {
reg: InlineAsmRegOrRegClass,
late: bool,
expr: Option<ExprRef<'tcx>>,
},
InOut {
reg: InlineAsmRegOrRegClass,
late: bool,
expr: ExprRef<'tcx>,
},
SplitInOut {
reg: InlineAsmRegOrRegClass,
late: bool,
in_expr: ExprRef<'tcx>,
out_expr: Option<ExprRef<'tcx>>,
},
Const {
expr: ExprRef<'tcx>,
},
SymFn {
expr: ExprRef<'tcx>,
},
SymStatic {
def_id: DefId,
},
}
crate trait Mirror<'tcx> {
type Output;
fn make_mirror(self, cx: &mut Cx<'_, 'tcx>) -> Self::Output;
}
impl<'tcx> Mirror<'tcx> for Expr<'tcx> {
type Output = Expr<'tcx>;
fn make_mirror(self, _: &mut Cx<'_, 'tcx>) -> Expr<'tcx> {
self
}
}
impl<'tcx> Mirror<'tcx> for ExprRef<'tcx> {
type Output = Expr<'tcx>;
fn make_mirror(self, hir: &mut Cx<'_, 'tcx>) -> Expr<'tcx> {
match self {
ExprRef::Thir(h) => h.make_mirror(hir),
ExprRef::Mirror(m) => *m,
}
}
}
impl<'tcx> Mirror<'tcx> for Stmt<'tcx> {
type Output = Stmt<'tcx>;
fn make_mirror(self, _: &mut Cx<'_, 'tcx>) -> Stmt<'tcx> {
self
}
}
impl<'tcx> Mirror<'tcx> for StmtRef<'tcx> {
type Output = Stmt<'tcx>;
fn make_mirror(self, _: &mut Cx<'_, 'tcx>) -> Stmt<'tcx> {
match self {
StmtRef::Mirror(m) => *m,
}
}
}
impl<'tcx> Mirror<'tcx> for Block<'tcx> {
type Output = Block<'tcx>;
fn make_mirror(self, _: &mut Cx<'_, 'tcx>) -> Block<'tcx> {
self
}
}