Auto merge of #100944 - nnethercote:shrink-thir-Expr, r=cjgillot
Shrink `thir::Expr` r? `@cjgillot`
This commit is contained in:
commit
8a13871b69
15 changed files with 191 additions and 150 deletions
|
@ -15,50 +15,33 @@ use rustc_hir::def_id::DefId;
|
|||
use rustc_hir::RangeEnd;
|
||||
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::interpret::AllocId;
|
||||
use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, Field, Mutability, UnOp};
|
||||
use rustc_middle::ty::adjustment::PointerCast;
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::CanonicalUserTypeAnnotation;
|
||||
use rustc_middle::ty::{self, AdtDef, Ty, UpvarSubsts, UserType};
|
||||
use rustc_middle::ty::{self, AdtDef, Ty, UpvarSubsts};
|
||||
use rustc_middle::ty::{CanonicalUserType, CanonicalUserTypeAnnotation};
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::{Span, Symbol, DUMMY_SP};
|
||||
use rustc_target::abi::VariantIdx;
|
||||
use rustc_target::asm::InlineAsmRegOrRegClass;
|
||||
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use std::fmt;
|
||||
use std::ops::Index;
|
||||
|
||||
pub mod visit;
|
||||
|
||||
newtype_index! {
|
||||
/// An index to an [`Arm`] stored in [`Thir::arms`]
|
||||
#[derive(HashStable)]
|
||||
pub struct ArmId {
|
||||
DEBUG_FORMAT = "a{}"
|
||||
}
|
||||
}
|
||||
|
||||
newtype_index! {
|
||||
/// An index to an [`Expr`] stored in [`Thir::exprs`]
|
||||
#[derive(HashStable)]
|
||||
pub struct ExprId {
|
||||
DEBUG_FORMAT = "e{}"
|
||||
}
|
||||
}
|
||||
|
||||
newtype_index! {
|
||||
#[derive(HashStable)]
|
||||
/// An index to a [`Stmt`] stored in [`Thir::stmts`]
|
||||
pub struct StmtId {
|
||||
DEBUG_FORMAT = "s{}"
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! thir_with_elements {
|
||||
($($name:ident: $id:ty => $value:ty,)*) => {
|
||||
($($name:ident: $id:ty => $value:ty => $format:literal,)*) => {
|
||||
$(
|
||||
newtype_index! {
|
||||
#[derive(HashStable)]
|
||||
pub struct $id {
|
||||
DEBUG_FORMAT = $format
|
||||
}
|
||||
}
|
||||
)*
|
||||
|
||||
/// A container for a THIR body.
|
||||
///
|
||||
/// This can be indexed directly by any THIR index (e.g. [`ExprId`]).
|
||||
|
@ -91,9 +74,10 @@ macro_rules! thir_with_elements {
|
|||
}
|
||||
|
||||
thir_with_elements! {
|
||||
arms: ArmId => Arm<'tcx>,
|
||||
exprs: ExprId => Expr<'tcx>,
|
||||
stmts: StmtId => Stmt<'tcx>,
|
||||
arms: ArmId => Arm<'tcx> => "a{}",
|
||||
blocks: BlockId => Block => "b{}",
|
||||
exprs: ExprId => Expr<'tcx> => "e{}",
|
||||
stmts: StmtId => Stmt<'tcx> => "s{}",
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, HashStable)]
|
||||
|
@ -121,8 +105,10 @@ pub struct Block {
|
|||
pub safety_mode: BlockSafety,
|
||||
}
|
||||
|
||||
type UserTy<'tcx> = Option<Box<CanonicalUserType<'tcx>>>;
|
||||
|
||||
#[derive(Clone, Debug, HashStable)]
|
||||
pub struct Adt<'tcx> {
|
||||
pub struct AdtExpr<'tcx> {
|
||||
/// The ADT we're constructing.
|
||||
pub adt_def: AdtDef<'tcx>,
|
||||
/// The variant of the ADT.
|
||||
|
@ -131,13 +117,30 @@ pub struct Adt<'tcx> {
|
|||
|
||||
/// Optional user-given substs: for something like `let x =
|
||||
/// Bar::<T> { ... }`.
|
||||
pub user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
|
||||
pub user_ty: UserTy<'tcx>,
|
||||
|
||||
pub fields: Box<[FieldExpr]>,
|
||||
/// The base, e.g. `Foo {x: 1, .. base}`.
|
||||
pub base: Option<FruInfo<'tcx>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, HashStable)]
|
||||
pub struct ClosureExpr<'tcx> {
|
||||
pub closure_id: LocalDefId,
|
||||
pub substs: UpvarSubsts<'tcx>,
|
||||
pub upvars: Box<[ExprId]>,
|
||||
pub movability: Option<hir::Movability>,
|
||||
pub fake_reads: Vec<(ExprId, FakeReadCause, hir::HirId)>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, HashStable)]
|
||||
pub struct InlineAsmExpr<'tcx> {
|
||||
pub template: &'tcx [InlineAsmTemplatePiece],
|
||||
pub operands: Box<[InlineAsmOperand<'tcx>]>,
|
||||
pub options: InlineAsmOptions,
|
||||
pub line_spans: &'tcx [Span],
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, HashStable)]
|
||||
pub enum BlockSafety {
|
||||
Safe,
|
||||
|
@ -183,7 +186,7 @@ pub enum StmtKind<'tcx> {
|
|||
initializer: Option<ExprId>,
|
||||
|
||||
/// `let pat: ty = <INIT> else { <ELSE> }
|
||||
else_block: Option<Block>,
|
||||
else_block: Option<BlockId>,
|
||||
|
||||
/// The lint level for this `let` statement.
|
||||
lint_level: LintLevel,
|
||||
|
@ -307,7 +310,7 @@ pub enum ExprKind<'tcx> {
|
|||
},
|
||||
/// A block.
|
||||
Block {
|
||||
body: Block,
|
||||
block: BlockId,
|
||||
},
|
||||
/// An assignment: `lhs = rhs`.
|
||||
Assign {
|
||||
|
@ -387,27 +390,21 @@ pub enum ExprKind<'tcx> {
|
|||
fields: Box<[ExprId]>,
|
||||
},
|
||||
/// An ADT constructor, e.g. `Foo {x: 1, y: 2}`.
|
||||
Adt(Box<Adt<'tcx>>),
|
||||
Adt(Box<AdtExpr<'tcx>>),
|
||||
/// A type ascription on a place.
|
||||
PlaceTypeAscription {
|
||||
source: ExprId,
|
||||
/// Type that the user gave to this expression
|
||||
user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
|
||||
user_ty: UserTy<'tcx>,
|
||||
},
|
||||
/// A type ascription on a value, e.g. `42: i32`.
|
||||
ValueTypeAscription {
|
||||
source: ExprId,
|
||||
/// Type that the user gave to this expression
|
||||
user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
|
||||
user_ty: UserTy<'tcx>,
|
||||
},
|
||||
/// A closure definition.
|
||||
Closure {
|
||||
closure_id: LocalDefId,
|
||||
substs: UpvarSubsts<'tcx>,
|
||||
upvars: Box<[ExprId]>,
|
||||
movability: Option<hir::Movability>,
|
||||
fake_reads: Vec<(ExprId, FakeReadCause, hir::HirId)>,
|
||||
},
|
||||
Closure(Box<ClosureExpr<'tcx>>),
|
||||
/// A literal.
|
||||
Literal {
|
||||
lit: &'tcx hir::Lit,
|
||||
|
@ -416,17 +413,17 @@ pub enum ExprKind<'tcx> {
|
|||
/// For literals that don't correspond to anything in the HIR
|
||||
NonHirLiteral {
|
||||
lit: ty::ScalarInt,
|
||||
user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
|
||||
user_ty: UserTy<'tcx>,
|
||||
},
|
||||
/// A literal of a ZST type.
|
||||
ZstLiteral {
|
||||
user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
|
||||
user_ty: UserTy<'tcx>,
|
||||
},
|
||||
/// Associated constants and named constants
|
||||
NamedConst {
|
||||
def_id: DefId,
|
||||
substs: SubstsRef<'tcx>,
|
||||
user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
|
||||
user_ty: UserTy<'tcx>,
|
||||
},
|
||||
ConstParam {
|
||||
param: ty::ParamConst,
|
||||
|
@ -443,12 +440,7 @@ pub enum ExprKind<'tcx> {
|
|||
def_id: DefId,
|
||||
},
|
||||
/// Inline assembly, i.e. `asm!()`.
|
||||
InlineAsm {
|
||||
template: &'tcx [InlineAsmTemplatePiece],
|
||||
operands: Box<[InlineAsmOperand<'tcx>]>,
|
||||
options: InlineAsmOptions,
|
||||
line_spans: &'tcx [Span],
|
||||
},
|
||||
InlineAsm(Box<InlineAsmExpr<'tcx>>),
|
||||
/// An expression taking a reference to a thread local.
|
||||
ThreadLocalRef(DefId),
|
||||
/// A `yield` expression.
|
||||
|
@ -815,7 +807,10 @@ mod size_asserts {
|
|||
use super::*;
|
||||
// These are in alphabetical order, which is easy to maintain.
|
||||
static_assert_size!(Block, 56);
|
||||
static_assert_size!(Expr<'_>, 104);
|
||||
static_assert_size!(Expr<'_>, 64);
|
||||
static_assert_size!(ExprKind<'_>, 40);
|
||||
static_assert_size!(Pat<'_>, 24);
|
||||
static_assert_size!(Stmt<'_>, 120);
|
||||
static_assert_size!(PatKind<'_>, 112);
|
||||
static_assert_size!(Stmt<'_>, 72);
|
||||
static_assert_size!(StmtKind<'_>, 64);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use super::{
|
||||
Arm, Block, Expr, ExprKind, Guard, InlineAsmOperand, Pat, PatKind, Stmt, StmtKind, Thir,
|
||||
AdtExpr, Arm, Block, ClosureExpr, Expr, ExprKind, Guard, InlineAsmExpr, InlineAsmOperand, Pat,
|
||||
PatKind, Stmt, StmtKind, Thir,
|
||||
};
|
||||
|
||||
pub trait Visitor<'a, 'tcx: 'a>: Sized {
|
||||
|
@ -75,7 +76,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
|
|||
visitor.visit_arm(&visitor.thir()[arm]);
|
||||
}
|
||||
}
|
||||
Block { ref body } => visitor.visit_block(body),
|
||||
Block { block } => visitor.visit_block(&visitor.thir()[block]),
|
||||
Assign { lhs, rhs } | AssignOp { lhs, rhs, op: _ } => {
|
||||
visitor.visit_expr(&visitor.thir()[lhs]);
|
||||
visitor.visit_expr(&visitor.thir()[rhs]);
|
||||
|
@ -108,7 +109,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
|
|||
visitor.visit_expr(&visitor.thir()[field]);
|
||||
}
|
||||
}
|
||||
Adt(box crate::thir::Adt {
|
||||
Adt(box AdtExpr {
|
||||
ref fields,
|
||||
ref base,
|
||||
adt_def: _,
|
||||
|
@ -126,14 +127,20 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
|
|||
PlaceTypeAscription { source, user_ty: _ } | ValueTypeAscription { source, user_ty: _ } => {
|
||||
visitor.visit_expr(&visitor.thir()[source])
|
||||
}
|
||||
Closure { closure_id: _, substs: _, upvars: _, movability: _, fake_reads: _ } => {}
|
||||
Closure(box ClosureExpr {
|
||||
closure_id: _,
|
||||
substs: _,
|
||||
upvars: _,
|
||||
movability: _,
|
||||
fake_reads: _,
|
||||
}) => {}
|
||||
Literal { lit: _, neg: _ } => {}
|
||||
NonHirLiteral { lit: _, user_ty: _ } => {}
|
||||
ZstLiteral { user_ty: _ } => {}
|
||||
NamedConst { def_id: _, substs: _, user_ty: _ } => {}
|
||||
ConstParam { param: _, def_id: _ } => {}
|
||||
StaticRef { alloc_id: _, ty: _, def_id: _ } => {}
|
||||
InlineAsm { ref operands, template: _, options: _, line_spans: _ } => {
|
||||
InlineAsm(box InlineAsmExpr { ref operands, template: _, options: _, line_spans: _ }) => {
|
||||
for op in &**operands {
|
||||
use InlineAsmOperand::*;
|
||||
match op {
|
||||
|
@ -174,7 +181,7 @@ pub fn walk_stmt<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, stmt: &Stm
|
|||
}
|
||||
visitor.visit_pat(pattern);
|
||||
if let Some(block) = else_block {
|
||||
visitor.visit_block(block)
|
||||
visitor.visit_block(&visitor.thir()[*block])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
&mut self,
|
||||
destination: Place<'tcx>,
|
||||
block: BasicBlock,
|
||||
ast_block: &Block,
|
||||
ast_block: BlockId,
|
||||
source_info: SourceInfo,
|
||||
) -> BlockAnd<()> {
|
||||
let Block {
|
||||
|
@ -22,7 +22,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
expr,
|
||||
targeted_by_break,
|
||||
safety_mode,
|
||||
} = *ast_block;
|
||||
} = self.thir[ast_block];
|
||||
let expr = expr.map(|expr| &self.thir[expr]);
|
||||
self.in_opt_scope(opt_destruction_scope.map(|de| (de, source_info)), move |this| {
|
||||
this.in_scope((region_scope, source_info), LintLevel::Inherited, move |this| {
|
||||
|
@ -146,7 +146,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
block,
|
||||
init,
|
||||
initializer_span,
|
||||
else_block,
|
||||
*else_block,
|
||||
visibility_scope,
|
||||
last_remainder_scope,
|
||||
remainder_span,
|
||||
|
|
|
@ -41,11 +41,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
|
||||
Constant { span, user_ty: None, literal }
|
||||
}
|
||||
ExprKind::NonHirLiteral { lit, user_ty } => {
|
||||
let user_ty = user_ty.map(|user_ty| {
|
||||
ExprKind::NonHirLiteral { lit, ref user_ty } => {
|
||||
let user_ty = user_ty.as_ref().map(|box user_ty| {
|
||||
this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
|
||||
span,
|
||||
user_ty,
|
||||
user_ty: *user_ty,
|
||||
inferred_ty: ty,
|
||||
})
|
||||
});
|
||||
|
@ -53,11 +53,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
|
||||
Constant { span, user_ty: user_ty, literal }
|
||||
}
|
||||
ExprKind::ZstLiteral { user_ty } => {
|
||||
let user_ty = user_ty.map(|user_ty| {
|
||||
ExprKind::ZstLiteral { ref user_ty } => {
|
||||
let user_ty = user_ty.as_ref().map(|box user_ty| {
|
||||
this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
|
||||
span,
|
||||
user_ty,
|
||||
user_ty: *user_ty,
|
||||
inferred_ty: ty,
|
||||
})
|
||||
});
|
||||
|
@ -65,11 +65,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
|
||||
Constant { span, user_ty: user_ty, literal }
|
||||
}
|
||||
ExprKind::NamedConst { def_id, substs, user_ty } => {
|
||||
let user_ty = user_ty.map(|user_ty| {
|
||||
ExprKind::NamedConst { def_id, substs, ref user_ty } => {
|
||||
let user_ty = user_ty.as_ref().map(|box user_ty| {
|
||||
this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
|
||||
span,
|
||||
user_ty,
|
||||
user_ty: *user_ty,
|
||||
inferred_ty: ty,
|
||||
})
|
||||
});
|
||||
|
|
|
@ -513,7 +513,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
block.and(place_builder)
|
||||
}
|
||||
|
||||
ExprKind::PlaceTypeAscription { source, user_ty } => {
|
||||
ExprKind::PlaceTypeAscription { source, ref user_ty } => {
|
||||
let place_builder = unpack!(
|
||||
block = this.expr_as_place(
|
||||
block,
|
||||
|
@ -522,11 +522,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
fake_borrow_temps,
|
||||
)
|
||||
);
|
||||
if let Some(user_ty) = user_ty {
|
||||
if let Some(box user_ty) = user_ty {
|
||||
let annotation_index =
|
||||
this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
|
||||
span: source_info.span,
|
||||
user_ty,
|
||||
user_ty: *user_ty,
|
||||
inferred_ty: expr.ty,
|
||||
});
|
||||
|
||||
|
@ -547,15 +547,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
}
|
||||
block.and(place_builder)
|
||||
}
|
||||
ExprKind::ValueTypeAscription { source, user_ty } => {
|
||||
ExprKind::ValueTypeAscription { source, ref user_ty } => {
|
||||
let source = &this.thir[source];
|
||||
let temp =
|
||||
unpack!(block = this.as_temp(block, source.temp_lifetime, source, mutability));
|
||||
if let Some(user_ty) = user_ty {
|
||||
if let Some(box user_ty) = user_ty {
|
||||
let annotation_index =
|
||||
this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
|
||||
span: source_info.span,
|
||||
user_ty,
|
||||
user_ty: *user_ty,
|
||||
inferred_ty: expr.ty,
|
||||
});
|
||||
this.cfg.push(
|
||||
|
|
|
@ -302,7 +302,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
|
||||
block.and(Rvalue::Aggregate(Box::new(AggregateKind::Tuple), fields))
|
||||
}
|
||||
ExprKind::Closure { closure_id, substs, ref upvars, movability, ref fake_reads } => {
|
||||
ExprKind::Closure(box ClosureExpr {
|
||||
closure_id,
|
||||
substs,
|
||||
ref upvars,
|
||||
movability,
|
||||
ref fake_reads,
|
||||
}) => {
|
||||
// Convert the closure fake reads, if any, from `ExprRef` to mir `Place`
|
||||
// and push the fake reads.
|
||||
// This must come before creating the operands. This is required in case
|
||||
|
|
|
@ -83,8 +83,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
// Don't bother with StorageLive and Dead for these temporaries,
|
||||
// they are never assigned.
|
||||
ExprKind::Break { .. } | ExprKind::Continue { .. } | ExprKind::Return { .. } => (),
|
||||
ExprKind::Block { body: Block { expr: None, targeted_by_break: false, .. } }
|
||||
if expr_ty.is_never() => {}
|
||||
ExprKind::Block { block }
|
||||
if let Block { expr: None, targeted_by_break: false, .. } = this.thir[block]
|
||||
&& expr_ty.is_never() => {}
|
||||
_ => {
|
||||
this.cfg
|
||||
.push(block, Statement { source_info, kind: StatementKind::StorageLive(temp) });
|
||||
|
|
|
@ -46,7 +46,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
})
|
||||
})
|
||||
}
|
||||
ExprKind::Block { body: ref ast_block } => {
|
||||
ExprKind::Block { block: ast_block } => {
|
||||
this.ast_block(destination, block, ast_block, source_info)
|
||||
}
|
||||
ExprKind::Match { scrutinee, ref arms } => {
|
||||
|
@ -314,11 +314,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
this.cfg.push_assign(block, source_info, destination, address_of);
|
||||
block.unit()
|
||||
}
|
||||
ExprKind::Adt(box Adt {
|
||||
ExprKind::Adt(box AdtExpr {
|
||||
adt_def,
|
||||
variant_index,
|
||||
substs,
|
||||
user_ty,
|
||||
ref user_ty,
|
||||
ref fields,
|
||||
ref base,
|
||||
}) => {
|
||||
|
@ -378,10 +378,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
};
|
||||
|
||||
let inferred_ty = expr.ty;
|
||||
let user_ty = user_ty.map(|ty| {
|
||||
let user_ty = user_ty.as_ref().map(|box user_ty| {
|
||||
this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
|
||||
span: source_info.span,
|
||||
user_ty: ty,
|
||||
user_ty: *user_ty,
|
||||
inferred_ty,
|
||||
})
|
||||
});
|
||||
|
@ -400,7 +400,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
);
|
||||
block.unit()
|
||||
}
|
||||
ExprKind::InlineAsm { template, ref operands, options, line_spans } => {
|
||||
ExprKind::InlineAsm(box InlineAsmExpr {
|
||||
template,
|
||||
ref operands,
|
||||
options,
|
||||
line_spans,
|
||||
}) => {
|
||||
use rustc_middle::{mir, thir};
|
||||
let operands = operands
|
||||
.into_iter()
|
||||
|
|
|
@ -116,15 +116,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
// it is usually better to focus on `the_value` rather
|
||||
// than the entirety of block(s) surrounding it.
|
||||
let adjusted_span = (|| {
|
||||
if let ExprKind::Block { body } = &expr.kind && let Some(tail_ex) = body.expr {
|
||||
if let ExprKind::Block { block } = expr.kind
|
||||
&& let Some(tail_ex) = this.thir[block].expr
|
||||
{
|
||||
let mut expr = &this.thir[tail_ex];
|
||||
while let ExprKind::Block {
|
||||
body: Block { expr: Some(nested_expr), .. },
|
||||
}
|
||||
| ExprKind::Scope { value: nested_expr, .. } = expr.kind
|
||||
loop {
|
||||
match expr.kind {
|
||||
ExprKind::Block { block }
|
||||
if let Some(nested_expr) = this.thir[block].expr =>
|
||||
{
|
||||
expr = &this.thir[nested_expr];
|
||||
}
|
||||
ExprKind::Scope { value: nested_expr, .. } => {
|
||||
expr = &this.thir[nested_expr];
|
||||
}
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
this.block_context.push(BlockFrame::TailExpr {
|
||||
tail_result_is_ignored: true,
|
||||
span: expr.span,
|
||||
|
|
|
@ -2280,15 +2280,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
mut block: BasicBlock,
|
||||
init: &Expr<'tcx>,
|
||||
initializer_span: Span,
|
||||
else_block: &Block,
|
||||
else_block: BlockId,
|
||||
visibility_scope: Option<SourceScope>,
|
||||
remainder_scope: region::Scope,
|
||||
remainder_span: Span,
|
||||
pattern: &Pat<'tcx>,
|
||||
) -> BlockAnd<()> {
|
||||
let else_block_span = self.thir[else_block].span;
|
||||
let (matching, failure) = self.in_if_then_scope(remainder_scope, |this| {
|
||||
let scrutinee = unpack!(block = this.lower_scrutinee(block, init, initializer_span));
|
||||
let pat = Pat { ty: init.ty, span: else_block.span, kind: Box::new(PatKind::Wild) };
|
||||
let pat = Pat { ty: init.ty, span: else_block_span, kind: Box::new(PatKind::Wild) };
|
||||
let mut wildcard = Candidate::new(scrutinee.clone(), &pat, false);
|
||||
this.declare_bindings(
|
||||
visibility_scope,
|
||||
|
@ -2318,7 +2319,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
);
|
||||
// This block is for the failure case
|
||||
let failure = this.bind_pattern(
|
||||
this.source_info(else_block.span),
|
||||
this.source_info(else_block_span),
|
||||
wildcard,
|
||||
None,
|
||||
&fake_borrow_temps,
|
||||
|
@ -2334,19 +2335,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
// This place is not really used because this destination place
|
||||
// should never be used to take values at the end of the failure
|
||||
// block.
|
||||
let dummy_place = self.temp(self.tcx.types.never, else_block.span);
|
||||
let dummy_place = self.temp(self.tcx.types.never, else_block_span);
|
||||
let failure_block;
|
||||
unpack!(
|
||||
failure_block = self.ast_block(
|
||||
dummy_place,
|
||||
failure,
|
||||
else_block,
|
||||
self.source_info(else_block.span),
|
||||
self.source_info(else_block_span),
|
||||
)
|
||||
);
|
||||
self.cfg.terminate(
|
||||
failure_block,
|
||||
self.source_info(else_block.span),
|
||||
self.source_info(else_block_span),
|
||||
TerminatorKind::Unreachable,
|
||||
);
|
||||
matching.unit()
|
||||
|
|
|
@ -391,7 +391,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
|||
ExprKind::InlineAsm { .. } => {
|
||||
self.requires_unsafe(expr.span, UseOfInlineAssembly);
|
||||
}
|
||||
ExprKind::Adt(box Adt {
|
||||
ExprKind::Adt(box AdtExpr {
|
||||
adt_def,
|
||||
variant_index: _,
|
||||
substs: _,
|
||||
|
@ -402,13 +402,13 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
|||
(Bound::Unbounded, Bound::Unbounded) => {}
|
||||
_ => self.requires_unsafe(expr.span, InitializingTypeWith),
|
||||
},
|
||||
ExprKind::Closure {
|
||||
ExprKind::Closure(box ClosureExpr {
|
||||
closure_id,
|
||||
substs: _,
|
||||
upvars: _,
|
||||
movability: _,
|
||||
fake_reads: _,
|
||||
} => {
|
||||
}) => {
|
||||
let closure_def = if let Some((did, const_param_id)) =
|
||||
ty::WithOptConstParam::try_lookup(closure_id, self.tcx)
|
||||
{
|
||||
|
|
|
@ -9,13 +9,13 @@ use rustc_index::vec::Idx;
|
|||
use rustc_middle::ty::CanonicalUserTypeAnnotation;
|
||||
|
||||
impl<'tcx> Cx<'tcx> {
|
||||
pub(crate) fn mirror_block(&mut self, block: &'tcx hir::Block<'tcx>) -> Block {
|
||||
pub(crate) fn mirror_block(&mut self, block: &'tcx hir::Block<'tcx>) -> BlockId {
|
||||
// We have to eagerly lower the "spine" of the statements
|
||||
// in order to get the lexical scoping correctly.
|
||||
let stmts = self.mirror_stmts(block.hir_id.local_id, block.stmts);
|
||||
let opt_destruction_scope =
|
||||
self.region_scope_tree.opt_destruction_scope(block.hir_id.local_id);
|
||||
Block {
|
||||
let block = Block {
|
||||
targeted_by_break: block.targeted_by_break,
|
||||
region_scope: region::Scope {
|
||||
id: block.hir_id.local_id,
|
||||
|
@ -34,7 +34,9 @@ impl<'tcx> Cx<'tcx> {
|
|||
BlockSafety::ExplicitUnsafe(block.hir_id)
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
self.thir.blocks.push(block)
|
||||
}
|
||||
|
||||
fn mirror_stmts(
|
||||
|
|
|
@ -108,8 +108,8 @@ impl<'tcx> Cx<'tcx> {
|
|||
// // ^ error message points at this expression.
|
||||
// }
|
||||
let mut adjust_span = |expr: &mut Expr<'tcx>| {
|
||||
if let ExprKind::Block { body } = &expr.kind {
|
||||
if let Some(last_expr) = body.expr {
|
||||
if let ExprKind::Block { block } = expr.kind {
|
||||
if let Some(last_expr) = self.thir[block].expr {
|
||||
span = self.thir[last_expr].span;
|
||||
expr.span = span;
|
||||
}
|
||||
|
@ -329,7 +329,7 @@ impl<'tcx> Cx<'tcx> {
|
|||
if let UserType::TypeOf(ref mut did, _) = &mut u_ty.value {
|
||||
*did = adt_def.did();
|
||||
}
|
||||
u_ty
|
||||
Box::new(u_ty)
|
||||
});
|
||||
debug!("make_mirror_unadjusted: (call) user_ty={:?}", user_ty);
|
||||
|
||||
|
@ -341,7 +341,7 @@ impl<'tcx> Cx<'tcx> {
|
|||
expr: self.mirror_expr(e),
|
||||
})
|
||||
.collect();
|
||||
ExprKind::Adt(Box::new(Adt {
|
||||
ExprKind::Adt(Box::new(AdtExpr {
|
||||
adt_def,
|
||||
substs,
|
||||
variant_index: index,
|
||||
|
@ -369,7 +369,7 @@ impl<'tcx> Cx<'tcx> {
|
|||
ExprKind::AddressOf { mutability, arg: self.mirror_expr(arg) }
|
||||
}
|
||||
|
||||
hir::ExprKind::Block(ref blk, _) => ExprKind::Block { body: self.mirror_block(blk) },
|
||||
hir::ExprKind::Block(ref blk, _) => ExprKind::Block { block: self.mirror_block(blk) },
|
||||
|
||||
hir::ExprKind::Assign(ref lhs, ref rhs, _) => {
|
||||
ExprKind::Assign { lhs: self.mirror_expr(lhs), rhs: self.mirror_expr(rhs) }
|
||||
|
@ -464,9 +464,9 @@ impl<'tcx> Cx<'tcx> {
|
|||
ty::Adt(adt, substs) => match adt.adt_kind() {
|
||||
AdtKind::Struct | AdtKind::Union => {
|
||||
let user_provided_types = self.typeck_results().user_provided_types();
|
||||
let user_ty = user_provided_types.get(expr.hir_id).copied();
|
||||
let user_ty = user_provided_types.get(expr.hir_id).copied().map(Box::new);
|
||||
debug!("make_mirror_unadjusted: (struct/union) user_ty={:?}", user_ty);
|
||||
ExprKind::Adt(Box::new(Adt {
|
||||
ExprKind::Adt(Box::new(AdtExpr {
|
||||
adt_def: *adt,
|
||||
variant_index: VariantIdx::new(0),
|
||||
substs,
|
||||
|
@ -490,9 +490,10 @@ impl<'tcx> Cx<'tcx> {
|
|||
let index = adt.variant_index_with_id(variant_id);
|
||||
let user_provided_types =
|
||||
self.typeck_results().user_provided_types();
|
||||
let user_ty = user_provided_types.get(expr.hir_id).copied();
|
||||
let user_ty =
|
||||
user_provided_types.get(expr.hir_id).copied().map(Box::new);
|
||||
debug!("make_mirror_unadjusted: (variant) user_ty={:?}", user_ty);
|
||||
ExprKind::Adt(Box::new(Adt {
|
||||
ExprKind::Adt(Box::new(AdtExpr {
|
||||
adt_def: *adt,
|
||||
variant_index: index,
|
||||
substs,
|
||||
|
@ -547,7 +548,13 @@ impl<'tcx> Cx<'tcx> {
|
|||
None => Vec::new(),
|
||||
};
|
||||
|
||||
ExprKind::Closure { closure_id: def_id, substs, upvars, movability, fake_reads }
|
||||
ExprKind::Closure(Box::new(ClosureExpr {
|
||||
closure_id: def_id,
|
||||
substs,
|
||||
upvars,
|
||||
movability,
|
||||
fake_reads,
|
||||
}))
|
||||
}
|
||||
|
||||
hir::ExprKind::Path(ref qpath) => {
|
||||
|
@ -555,7 +562,7 @@ impl<'tcx> Cx<'tcx> {
|
|||
self.convert_path_expr(expr, res)
|
||||
}
|
||||
|
||||
hir::ExprKind::InlineAsm(ref asm) => ExprKind::InlineAsm {
|
||||
hir::ExprKind::InlineAsm(ref asm) => ExprKind::InlineAsm(Box::new(InlineAsmExpr {
|
||||
template: asm.template,
|
||||
operands: asm
|
||||
.operands
|
||||
|
@ -614,7 +621,7 @@ impl<'tcx> Cx<'tcx> {
|
|||
.collect(),
|
||||
options: asm.options,
|
||||
line_spans: asm.line_spans,
|
||||
},
|
||||
})),
|
||||
|
||||
hir::ExprKind::ConstBlock(ref anon_const) => {
|
||||
let ty = self.typeck_results().node_type(anon_const.hir_id);
|
||||
|
@ -679,8 +686,8 @@ impl<'tcx> Cx<'tcx> {
|
|||
let body = self.thir.exprs.push(Expr {
|
||||
ty: block_ty,
|
||||
temp_lifetime,
|
||||
span: block.span,
|
||||
kind: ExprKind::Block { body: block },
|
||||
span: self.thir[block].span,
|
||||
kind: ExprKind::Block { block },
|
||||
});
|
||||
ExprKind::Loop { body }
|
||||
}
|
||||
|
@ -712,14 +719,17 @@ impl<'tcx> Cx<'tcx> {
|
|||
});
|
||||
debug!("make_mirror_unadjusted: (cast) user_ty={:?}", user_ty);
|
||||
|
||||
ExprKind::ValueTypeAscription { source: cast_expr, user_ty: Some(*user_ty) }
|
||||
ExprKind::ValueTypeAscription {
|
||||
source: cast_expr,
|
||||
user_ty: Some(Box::new(*user_ty)),
|
||||
}
|
||||
} else {
|
||||
cast
|
||||
}
|
||||
}
|
||||
hir::ExprKind::Type(ref source, ref ty) => {
|
||||
let user_provided_types = self.typeck_results.user_provided_types();
|
||||
let user_ty = user_provided_types.get(ty.hir_id).copied();
|
||||
let user_ty = user_provided_types.get(ty.hir_id).copied().map(Box::new);
|
||||
debug!("make_mirror_unadjusted: (type) user_ty={:?}", user_ty);
|
||||
let mirrored = self.mirror_expr(source);
|
||||
if source.is_syntactic_place_expr() {
|
||||
|
@ -748,7 +758,7 @@ impl<'tcx> Cx<'tcx> {
|
|||
&mut self,
|
||||
hir_id: hir::HirId,
|
||||
res: Res,
|
||||
) -> Option<ty::CanonicalUserType<'tcx>> {
|
||||
) -> Option<Box<ty::CanonicalUserType<'tcx>>> {
|
||||
debug!("user_substs_applied_to_res: res={:?}", res);
|
||||
let user_provided_type = match res {
|
||||
// A reference to something callable -- e.g., a fn, method, or
|
||||
|
@ -759,7 +769,7 @@ impl<'tcx> Cx<'tcx> {
|
|||
| Res::Def(DefKind::Ctor(_, CtorKind::Fn), _)
|
||||
| Res::Def(DefKind::Const, _)
|
||||
| Res::Def(DefKind::AssocConst, _) => {
|
||||
self.typeck_results().user_provided_types().get(hir_id).copied()
|
||||
self.typeck_results().user_provided_types().get(hir_id).copied().map(Box::new)
|
||||
}
|
||||
|
||||
// A unit struct/variant which is used as a value (e.g.,
|
||||
|
@ -767,11 +777,11 @@ impl<'tcx> Cx<'tcx> {
|
|||
// this variant -- but with the substitutions given by the
|
||||
// user.
|
||||
Res::Def(DefKind::Ctor(_, CtorKind::Const), _) => {
|
||||
self.user_substs_applied_to_ty_of_hir_id(hir_id)
|
||||
self.user_substs_applied_to_ty_of_hir_id(hir_id).map(Box::new)
|
||||
}
|
||||
|
||||
// `Self` is used in expression as a tuple struct constructor or a unit struct constructor
|
||||
Res::SelfCtor(_) => self.user_substs_applied_to_ty_of_hir_id(hir_id),
|
||||
Res::SelfCtor(_) => self.user_substs_applied_to_ty_of_hir_id(hir_id).map(Box::new),
|
||||
|
||||
_ => bug!("user_substs_applied_to_res: unexpected res {:?} at {:?}", res, hir_id),
|
||||
};
|
||||
|
@ -846,22 +856,22 @@ impl<'tcx> Cx<'tcx> {
|
|||
|
||||
Res::Def(DefKind::Const, def_id) | Res::Def(DefKind::AssocConst, def_id) => {
|
||||
let user_ty = self.user_substs_applied_to_res(expr.hir_id, res);
|
||||
ExprKind::NamedConst { def_id, substs, user_ty: user_ty }
|
||||
ExprKind::NamedConst { def_id, substs, user_ty }
|
||||
}
|
||||
|
||||
Res::Def(DefKind::Ctor(_, CtorKind::Const), def_id) => {
|
||||
let user_provided_types = self.typeck_results.user_provided_types();
|
||||
let user_provided_type = user_provided_types.get(expr.hir_id).copied();
|
||||
debug!("convert_path_expr: user_provided_type={:?}", user_provided_type);
|
||||
let user_ty = user_provided_types.get(expr.hir_id).copied().map(Box::new);
|
||||
debug!("convert_path_expr: user_ty={:?}", user_ty);
|
||||
let ty = self.typeck_results().node_type(expr.hir_id);
|
||||
match ty.kind() {
|
||||
// A unit struct/variant which is used as a value.
|
||||
// We return a completely different ExprKind here to account for this special case.
|
||||
ty::Adt(adt_def, substs) => ExprKind::Adt(Box::new(Adt {
|
||||
ty::Adt(adt_def, substs) => ExprKind::Adt(Box::new(AdtExpr {
|
||||
adt_def: *adt_def,
|
||||
variant_index: adt_def.variant_index_with_ctor_id(def_id),
|
||||
substs,
|
||||
user_ty: user_provided_type,
|
||||
user_ty,
|
||||
fields: Box::new([]),
|
||||
base: None,
|
||||
})),
|
||||
|
|
|
@ -311,8 +311,15 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
|||
// bar::<{ N + 1 }>();
|
||||
// }
|
||||
// ```
|
||||
ExprKind::Block { body: thir::Block { stmts: box [], expr: Some(e), .. } } => {
|
||||
ExprKind::Block { block } => {
|
||||
if let thir::Block { stmts: box [], expr: Some(e), .. } = &self.body.blocks[*block] {
|
||||
self.recurse_build(*e)?
|
||||
} else {
|
||||
self.maybe_supported_error(
|
||||
node.span,
|
||||
"blocks are not supported in generic constant",
|
||||
)?
|
||||
}
|
||||
}
|
||||
// `ExprKind::Use` happens when a `hir::ExprKind::Cast` is a
|
||||
// "coercion cast" i.e. using a coercion or is a no-op.
|
||||
|
@ -349,10 +356,6 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
|||
node.span,
|
||||
"array construction is not supported in generic constants",
|
||||
)?,
|
||||
ExprKind::Block { .. } => self.maybe_supported_error(
|
||||
node.span,
|
||||
"blocks are not supported in generic constant",
|
||||
)?,
|
||||
ExprKind::NeverToAny { .. } => self.maybe_supported_error(
|
||||
node.span,
|
||||
"converting nevers to any is not supported in generic constant",
|
||||
|
|
|
@ -1,15 +1,8 @@
|
|||
DefId(0:3 ~ thir_tree[8f1d]::main):
|
||||
Thir {
|
||||
arms: [],
|
||||
exprs: [
|
||||
Expr {
|
||||
ty: (),
|
||||
temp_lifetime: Some(
|
||||
Node(2),
|
||||
),
|
||||
span: $DIR/thir-tree.rs:4:15: 4:17 (#0),
|
||||
kind: Block {
|
||||
body: Block {
|
||||
blocks: [
|
||||
Block {
|
||||
targeted_by_break: false,
|
||||
region_scope: Node(1),
|
||||
opt_destruction_scope: None,
|
||||
|
@ -18,6 +11,16 @@ Thir {
|
|||
expr: None,
|
||||
safety_mode: Safe,
|
||||
},
|
||||
],
|
||||
exprs: [
|
||||
Expr {
|
||||
ty: (),
|
||||
temp_lifetime: Some(
|
||||
Node(2),
|
||||
),
|
||||
span: $DIR/thir-tree.rs:4:15: 4:17 (#0),
|
||||
kind: Block {
|
||||
block: b0,
|
||||
},
|
||||
},
|
||||
Expr {
|
||||
|
|
Loading…
Add table
Reference in a new issue