summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_mir_build/src/build/expr
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:39 +0000
commit1376c5a617be5c25655d0d7cb63e3beaa5a6e026 (patch)
tree3bb8d61aee02bc7a15eab3f36e3b921afc2075d0 /compiler/rustc_mir_build/src/build/expr
parentReleasing progress-linux version 1.69.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.tar.xz
rustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.zip
Merging upstream version 1.70.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_mir_build/src/build/expr')
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_constant.rs6
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_operand.rs14
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_place.rs10
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs174
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_temp.rs25
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs28
-rw-r--r--compiler/rustc_mir_build/src/build/expr/stmt.rs2
7 files changed, 171 insertions, 88 deletions
diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
index cfacb5ea3..99291740a 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
@@ -62,21 +62,21 @@ pub fn as_constant_inner<'tcx>(
Constant { span, user_ty: None, literal }
}
ExprKind::NonHirLiteral { lit, ref user_ty } => {
- let user_ty = user_ty.as_ref().map(push_cuta).flatten();
+ let user_ty = user_ty.as_ref().and_then(push_cuta);
let literal = ConstantKind::Val(ConstValue::Scalar(Scalar::Int(lit)), ty);
Constant { span, user_ty, literal }
}
ExprKind::ZstLiteral { ref user_ty } => {
- let user_ty = user_ty.as_ref().map(push_cuta).flatten();
+ let user_ty = user_ty.as_ref().and_then(push_cuta);
let literal = ConstantKind::Val(ConstValue::ZeroSized, ty);
Constant { span, user_ty, literal }
}
ExprKind::NamedConst { def_id, substs, ref user_ty } => {
- let user_ty = user_ty.as_ref().map(push_cuta).flatten();
+ let user_ty = user_ty.as_ref().and_then(push_cuta);
let uneval = mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs);
let literal = ConstantKind::Unevaluated(uneval, ty);
diff --git a/compiler/rustc_mir_build/src/build/expr/as_operand.rs b/compiler/rustc_mir_build/src/build/expr/as_operand.rs
index ff3198847..6941da331 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_operand.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_operand.rs
@@ -20,7 +20,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
expr: &Expr<'tcx>,
) -> BlockAnd<Operand<'tcx>> {
let local_scope = self.local_scope();
- self.as_operand(block, Some(local_scope), expr, None, NeedsTemporary::Maybe)
+ self.as_operand(block, Some(local_scope), expr, LocalInfo::Boring, NeedsTemporary::Maybe)
}
/// Returns an operand suitable for use until the end of the current scope expression and
@@ -102,7 +102,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
mut block: BasicBlock,
scope: Option<region::Scope>,
expr: &Expr<'tcx>,
- local_info: Option<Box<LocalInfo<'tcx>>>,
+ local_info: LocalInfo<'tcx>,
needs_temporary: NeedsTemporary,
) -> BlockAnd<Operand<'tcx>> {
let this = self;
@@ -124,8 +124,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
Category::Constant | Category::Place | Category::Rvalue(..) => {
let operand = unpack!(block = this.as_temp(block, scope, expr, Mutability::Mut));
- if this.local_decls[operand].local_info.is_none() {
- this.local_decls[operand].local_info = local_info;
+ // Overwrite temp local info if we have something more interesting to record.
+ if !matches!(local_info, LocalInfo::Boring) {
+ let decl_info = this.local_decls[operand].local_info.as_mut().assert_crate_local();
+ if let LocalInfo::Boring | LocalInfo::BlockTailTemp(_) = **decl_info {
+ **decl_info = local_info;
+ }
}
block.and(Operand::Move(Place::from(operand)))
}
@@ -178,6 +182,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}
- this.as_operand(block, scope, expr, None, NeedsTemporary::Maybe)
+ this.as_operand(block, scope, expr, LocalInfo::Boring, NeedsTemporary::Maybe)
}
}
diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs
index 33200b80a..fb775766c 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs
@@ -13,9 +13,7 @@ use rustc_middle::thir::*;
use rustc_middle::ty::AdtDef;
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, Variance};
use rustc_span::Span;
-use rustc_target::abi::VariantIdx;
-
-use rustc_index::vec::Idx;
+use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
use std::assert_matches::assert_matches;
use std::iter;
@@ -91,8 +89,8 @@ fn convert_to_hir_projections_and_truncate_for_capture(
let hir_projection = match mir_projection {
ProjectionElem::Deref => HirProjectionKind::Deref,
ProjectionElem::Field(field, _) => {
- let variant = variant.unwrap_or(VariantIdx::new(0));
- HirProjectionKind::Field(field.index() as u32, variant)
+ let variant = variant.unwrap_or(FIRST_VARIANT);
+ HirProjectionKind::Field(*field, variant)
}
ProjectionElem::Downcast(.., idx) => {
// We don't expect to see multi-variant enums here, as earlier
@@ -295,7 +293,7 @@ impl<'tcx> PlaceBuilder<'tcx> {
&self.projection
}
- pub(crate) fn field(self, f: Field, ty: Ty<'tcx>) -> Self {
+ pub(crate) fn field(self, f: FieldIdx, ty: Ty<'tcx>) -> Self {
self.project(PlaceElem::Field(f, ty))
}
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index a4e48c154..8631749a5 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -1,14 +1,15 @@
//! See docs in `build/expr/mod.rs`.
-use rustc_index::vec::Idx;
+use rustc_index::vec::{Idx, IndexVec};
use rustc_middle::ty::util::IntTypeExt;
-use rustc_target::abi::{Abi, Primitive};
+use rustc_target::abi::{Abi, FieldIdx, Primitive};
use crate::build::expr::as_place::PlaceBase;
use crate::build::expr::category::{Category, RvalueFunc};
use crate::build::{BlockAnd, BlockAndExtension, Builder, NeedsTemporary};
use rustc_hir::lang_items::LangItem;
use rustc_middle::middle::region;
+use rustc_middle::mir::interpret::Scalar;
use rustc_middle::mir::AssertKind;
use rustc_middle::mir::Place;
use rustc_middle::mir::*;
@@ -63,7 +64,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block,
scope,
&this.thir[value],
- None,
+ LocalInfo::Boring,
NeedsTemporary::No
)
);
@@ -72,19 +73,34 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
ExprKind::Binary { op, lhs, rhs } => {
let lhs = unpack!(
- block =
- this.as_operand(block, scope, &this.thir[lhs], None, NeedsTemporary::Maybe)
+ block = this.as_operand(
+ block,
+ scope,
+ &this.thir[lhs],
+ LocalInfo::Boring,
+ NeedsTemporary::Maybe
+ )
);
let rhs = unpack!(
- block =
- this.as_operand(block, scope, &this.thir[rhs], None, NeedsTemporary::No)
+ block = this.as_operand(
+ block,
+ scope,
+ &this.thir[rhs],
+ LocalInfo::Boring,
+ NeedsTemporary::No
+ )
);
this.build_binary_op(block, op, expr_span, expr.ty, lhs, rhs)
}
ExprKind::Unary { op, arg } => {
let arg = unpack!(
- block =
- this.as_operand(block, scope, &this.thir[arg], None, NeedsTemporary::No)
+ block = this.as_operand(
+ block,
+ scope,
+ &this.thir[arg],
+ LocalInfo::Boring,
+ NeedsTemporary::No
+ )
);
// Check for -MIN on signed integers
if this.check_overflow && op == UnOp::Neg && expr.ty.is_signed() {
@@ -155,7 +171,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
args: vec![Operand::Move(size), Operand::Move(align)],
destination: storage,
target: Some(success),
- cleanup: None,
+ unwind: UnwindAction::Continue,
from_hir_call: false,
fn_span: expr_span,
},
@@ -259,7 +275,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
} else {
let ty = source.ty;
let source = unpack!(
- block = this.as_operand(block, scope, source, None, NeedsTemporary::No)
+ block = this.as_operand(block, scope, source, LocalInfo::Boring, NeedsTemporary::No)
);
(source, ty)
};
@@ -271,8 +287,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
ExprKind::Pointer { cast, source } => {
let source = unpack!(
- block =
- this.as_operand(block, scope, &this.thir[source], None, NeedsTemporary::No)
+ block = this.as_operand(
+ block,
+ scope,
+ &this.thir[source],
+ LocalInfo::Boring,
+ NeedsTemporary::No
+ )
);
block.and(Rvalue::Cast(CastKind::Pointer(cast), source, expr.ty))
}
@@ -305,7 +326,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// first process the set of fields
let el_ty = expr.ty.sequence_element_type(this.tcx);
- let fields: Vec<_> = fields
+ let fields: IndexVec<FieldIdx, _> = fields
.into_iter()
.copied()
.map(|f| {
@@ -314,7 +335,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block,
scope,
&this.thir[f],
- None,
+ LocalInfo::Boring,
NeedsTemporary::Maybe
)
)
@@ -326,7 +347,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
ExprKind::Tuple { ref fields } => {
// see (*) above
// first process the set of fields
- let fields: Vec<_> = fields
+ let fields: IndexVec<FieldIdx, _> = fields
.into_iter()
.copied()
.map(|f| {
@@ -335,7 +356,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block,
scope,
&this.thir[f],
- None,
+ LocalInfo::Boring,
NeedsTemporary::Maybe
)
)
@@ -380,7 +401,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
// see (*) above
- let operands: Vec<_> = upvars
+ let operands: IndexVec<FieldIdx, _> = upvars
.into_iter()
.copied()
.map(|upvar| {
@@ -423,7 +444,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block,
scope,
upvar,
- None,
+ LocalInfo::Boring,
NeedsTemporary::Maybe
)
)
@@ -501,8 +522,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Category::of(&expr.kind),
Some(Category::Rvalue(RvalueFunc::AsRvalue) | Category::Constant)
));
- let operand =
- unpack!(block = this.as_operand(block, scope, expr, None, NeedsTemporary::No));
+ let operand = unpack!(
+ block =
+ this.as_operand(block, scope, expr, LocalInfo::Boring, NeedsTemporary::No)
+ );
block.and(Rvalue::Use(operand))
}
}
@@ -519,30 +542,78 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
) -> BlockAnd<Rvalue<'tcx>> {
let source_info = self.source_info(span);
let bool_ty = self.tcx.types.bool;
- if self.check_overflow && op.is_checkable() && ty.is_integral() {
- let result_tup = self.tcx.mk_tup(&[ty, bool_ty]);
- let result_value = self.temp(result_tup, span);
-
- self.cfg.push_assign(
- block,
- source_info,
- result_value,
- Rvalue::CheckedBinaryOp(op, Box::new((lhs.to_copy(), rhs.to_copy()))),
- );
- let val_fld = Field::new(0);
- let of_fld = Field::new(1);
+ let rvalue = match op {
+ BinOp::Add | BinOp::Sub | BinOp::Mul if self.check_overflow && ty.is_integral() => {
+ let result_tup = self.tcx.mk_tup(&[ty, bool_ty]);
+ let result_value = self.temp(result_tup, span);
- let tcx = self.tcx;
- let val = tcx.mk_place_field(result_value, val_fld, ty);
- let of = tcx.mk_place_field(result_value, of_fld, bool_ty);
+ self.cfg.push_assign(
+ block,
+ source_info,
+ result_value,
+ Rvalue::CheckedBinaryOp(op, Box::new((lhs.to_copy(), rhs.to_copy()))),
+ );
+ let val_fld = FieldIdx::new(0);
+ let of_fld = FieldIdx::new(1);
- let err = AssertKind::Overflow(op, lhs, rhs);
+ let tcx = self.tcx;
+ let val = tcx.mk_place_field(result_value, val_fld, ty);
+ let of = tcx.mk_place_field(result_value, of_fld, bool_ty);
- block = self.assert(block, Operand::Move(of), false, err, span);
+ let err = AssertKind::Overflow(op, lhs, rhs);
+ block = self.assert(block, Operand::Move(of), false, err, span);
- block.and(Rvalue::Use(Operand::Move(val)))
- } else {
- if ty.is_integral() && (op == BinOp::Div || op == BinOp::Rem) {
+ Rvalue::Use(Operand::Move(val))
+ }
+ BinOp::Shl | BinOp::Shr if self.check_overflow && ty.is_integral() => {
+ // For an unsigned RHS, the shift is in-range for `rhs < bits`.
+ // For a signed RHS, `IntToInt` cast to the equivalent unsigned
+ // type and do that same comparison. Because the type is the
+ // same size, there's no negative shift amount that ends up
+ // overlapping with valid ones, thus it catches negatives too.
+ let (lhs_size, _) = ty.int_size_and_signed(self.tcx);
+ let rhs_ty = rhs.ty(&self.local_decls, self.tcx);
+ let (rhs_size, _) = rhs_ty.int_size_and_signed(self.tcx);
+
+ let (unsigned_rhs, unsigned_ty) = match rhs_ty.kind() {
+ ty::Uint(_) => (rhs.to_copy(), rhs_ty),
+ ty::Int(int_width) => {
+ let uint_ty = self.tcx.mk_mach_uint(int_width.to_unsigned());
+ let rhs_temp = self.temp(uint_ty, span);
+ self.cfg.push_assign(
+ block,
+ source_info,
+ rhs_temp,
+ Rvalue::Cast(CastKind::IntToInt, rhs.to_copy(), uint_ty),
+ );
+ (Operand::Move(rhs_temp), uint_ty)
+ }
+ _ => unreachable!("only integers are shiftable"),
+ };
+
+ // This can't overflow because the largest shiftable types are 128-bit,
+ // which fits in `u8`, the smallest possible `unsigned_ty`.
+ // (And `from_uint` will `bug!` if that's ever no longer true.)
+ let lhs_bits = Operand::const_from_scalar(
+ self.tcx,
+ unsigned_ty,
+ Scalar::from_uint(lhs_size.bits(), rhs_size),
+ span,
+ );
+
+ let inbounds = self.temp(bool_ty, span);
+ self.cfg.push_assign(
+ block,
+ source_info,
+ inbounds,
+ Rvalue::BinaryOp(BinOp::Lt, Box::new((unsigned_rhs, lhs_bits))),
+ );
+
+ let overflow_err = AssertKind::Overflow(op, lhs.to_copy(), rhs.to_copy());
+ block = self.assert(block, Operand::Move(inbounds), true, overflow_err, span);
+ Rvalue::BinaryOp(op, Box::new((lhs, rhs)))
+ }
+ BinOp::Div | BinOp::Rem if ty.is_integral() => {
// Checking division and remainder is more complex, since we 1. always check
// and 2. there are two possible failure cases, divide-by-zero and overflow.
@@ -601,10 +672,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block = self.assert(block, Operand::Move(of), false, overflow_err, span);
}
- }
- block.and(Rvalue::BinaryOp(op, Box::new((lhs, rhs))))
- }
+ Rvalue::BinaryOp(op, Box::new((lhs, rhs)))
+ }
+ _ => Rvalue::BinaryOp(op, Box::new((lhs, rhs))),
+ };
+ block.and(rvalue)
}
fn build_zero_repeat(
@@ -621,21 +694,26 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// Repeating a const does nothing
} else {
// For a non-const, we may need to generate an appropriate `Drop`
- let value_operand =
- unpack!(block = this.as_operand(block, scope, value, None, NeedsTemporary::No));
+ let value_operand = unpack!(
+ block = this.as_operand(block, scope, value, LocalInfo::Boring, NeedsTemporary::No)
+ );
if let Operand::Move(to_drop) = value_operand {
let success = this.cfg.start_new_block();
this.cfg.terminate(
block,
outer_source_info,
- TerminatorKind::Drop { place: to_drop, target: success, unwind: None },
+ TerminatorKind::Drop {
+ place: to_drop,
+ target: success,
+ unwind: UnwindAction::Continue,
+ },
);
this.diverge_from(block);
block = success;
}
this.record_operands_moved(&[value_operand]);
}
- block.and(Rvalue::Aggregate(Box::new(AggregateKind::Array(elem_ty)), Vec::new()))
+ block.and(Rvalue::Aggregate(Box::new(AggregateKind::Array(elem_ty)), IndexVec::new()))
}
fn limit_capture_mutability(
diff --git a/compiler/rustc_mir_build/src/build/expr/as_temp.rs b/compiler/rustc_mir_build/src/build/expr/as_temp.rs
index 3d3cf7555..c8910c272 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_temp.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_temp.rs
@@ -49,29 +49,28 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
debug!("creating temp {:?} with block_context: {:?}", local_decl, this.block_context);
- // Find out whether this temp is being created within the
- // tail expression of a block whose result is ignored.
- if let Some(tail_info) = this.block_context.currently_in_block_tail() {
- local_decl = local_decl.block_tail(tail_info);
- }
- match expr.kind {
+ let local_info = match expr.kind {
ExprKind::StaticRef { def_id, .. } => {
assert!(!this.tcx.is_thread_local_static(def_id));
local_decl.internal = true;
- local_decl.local_info =
- Some(Box::new(LocalInfo::StaticRef { def_id, is_thread_local: false }));
+ LocalInfo::StaticRef { def_id, is_thread_local: false }
}
ExprKind::ThreadLocalRef(def_id) => {
assert!(this.tcx.is_thread_local_static(def_id));
local_decl.internal = true;
- local_decl.local_info =
- Some(Box::new(LocalInfo::StaticRef { def_id, is_thread_local: true }));
+ LocalInfo::StaticRef { def_id, is_thread_local: true }
}
ExprKind::NamedConst { def_id, .. } | ExprKind::ConstParam { def_id, .. } => {
- local_decl.local_info = Some(Box::new(LocalInfo::ConstRef { def_id }));
+ LocalInfo::ConstRef { def_id }
}
- _ => {}
- }
+ // Find out whether this temp is being created within the
+ // tail expression of a block whose result is ignored.
+ _ if let Some(tail_info) = this.block_context.currently_in_block_tail() => {
+ LocalInfo::BlockTailTemp(tail_info)
+ }
+ _ => LocalInfo::Boring,
+ };
+ **local_decl.local_info.as_mut().assert_crate_local() = local_info;
this.local_decls.push(local_decl)
};
let temp_place = Place::from(temp);
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index dac9bf0a8..05a723a6b 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -6,7 +6,6 @@ use rustc_ast::InlineAsmOptions;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir as hir;
-use rustc_index::vec::Idx;
use rustc_middle::mir::*;
use rustc_middle::thir::*;
use rustc_middle::ty::CanonicalUserTypeAnnotation;
@@ -229,7 +228,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
this.cfg.terminate(
loop_block,
source_info,
- TerminatorKind::FalseUnwind { real_target: body_block, unwind: None },
+ TerminatorKind::FalseUnwind {
+ real_target: body_block,
+ unwind: UnwindAction::Continue,
+ },
);
this.diverge_from(loop_block);
@@ -265,7 +267,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
TerminatorKind::Call {
func: fun,
args,
- cleanup: None,
+ unwind: UnwindAction::Continue,
destination,
// The presence or absence of a return edge affects control-flow sensitive
// MIR checks and ultimately whether code is accepted or not. We can only
@@ -319,7 +321,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// See the notes for `ExprKind::Array` in `as_rvalue` and for
// `ExprKind::Borrow` above.
let is_union = adt_def.is_union();
- let active_field_index = is_union.then(|| fields[0].name.index());
+ let active_field_index = is_union.then(|| fields[0].name);
let scope = this.local_scope();
@@ -328,7 +330,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let fields_map: FxHashMap<_, _> = fields
.into_iter()
.map(|f| {
- let local_info = Box::new(LocalInfo::AggregateTemp);
(
f.name,
unpack!(
@@ -336,7 +337,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block,
Some(scope),
&this.thir[f.expr],
- Some(local_info),
+ LocalInfo::AggregateTemp,
NeedsTemporary::Maybe,
)
),
@@ -344,10 +345,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
})
.collect();
- let field_names: Vec<_> =
- (0..adt_def.variant(variant_index).fields.len()).map(Field::new).collect();
+ let field_names = adt_def.variant(variant_index).fields.indices();
- let fields: Vec<_> = if let Some(FruInfo { base, field_types }) = base {
+ let fields = if let Some(FruInfo { base, field_types }) = base {
let place_builder =
unpack!(block = this.as_place_builder(block, &this.thir[*base]));
@@ -364,7 +364,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
})
.collect()
} else {
- field_names.iter().filter_map(|n| fields_map.get(n).cloned()).collect()
+ field_names.filter_map(|n| fields_map.get(&n).cloned()).collect()
};
let inferred_ty = expr.ty;
@@ -469,7 +469,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
} else {
Some(destination_block)
},
- cleanup: None,
+ unwind: if options.contains(InlineAsmOptions::MAY_UNWIND) {
+ UnwindAction::Continue
+ } else {
+ UnwindAction::Unreachable
+ },
},
);
if options.contains(InlineAsmOptions::MAY_UNWIND) {
@@ -526,7 +530,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block,
Some(scope),
&this.thir[value],
- None,
+ LocalInfo::Boring,
NeedsTemporary::No
)
);
diff --git a/compiler/rustc_mir_build/src/build/expr/stmt.rs b/compiler/rustc_mir_build/src/build/expr/stmt.rs
index 780836851..ea5aeb67d 100644
--- a/compiler/rustc_mir_build/src/build/expr/stmt.rs
+++ b/compiler/rustc_mir_build/src/build/expr/stmt.rs
@@ -40,7 +40,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// Generate better code for things that don't need to be
// dropped.
if lhs.ty.needs_drop(this.tcx, this.param_env) {
- let rhs = unpack!(block = this.as_local_operand(block, rhs));
+ let rhs = unpack!(block = this.as_local_rvalue(block, rhs));
let lhs = unpack!(block = this.as_place(block, lhs));
unpack!(block = this.build_drop_and_replace(block, lhs_span, lhs, rhs));
} else {