summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_mir_build/src/build/expr
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
commitc23a457e72abe608715ac76f076f47dc42af07a5 (patch)
tree2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /compiler/rustc_mir_build/src/build/expr
parentReleasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz
rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip
Merging upstream version 1.74.1+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.rs66
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_place.rs5
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs10
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs90
4 files changed, 85 insertions, 86 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 aaa37446e..4ed49e787 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
@@ -3,9 +3,7 @@
use crate::build::{parse_float_into_constval, Builder};
use rustc_ast as ast;
use rustc_middle::mir;
-use rustc_middle::mir::interpret::{
- Allocation, ConstValue, LitToConstError, LitToConstInput, Scalar,
-};
+use rustc_middle::mir::interpret::{Allocation, LitToConstError, LitToConstInput, Scalar};
use rustc_middle::mir::*;
use rustc_middle::thir::*;
use rustc_middle::ty::{
@@ -17,7 +15,7 @@ use rustc_target::abi::Size;
impl<'a, 'tcx> Builder<'a, 'tcx> {
/// Compile `expr`, yielding a compile-time constant. Assumes that
/// `expr` is a valid compile-time constant!
- pub(crate) fn as_constant(&mut self, expr: &Expr<'tcx>) -> Constant<'tcx> {
+ pub(crate) fn as_constant(&mut self, expr: &Expr<'tcx>) -> ConstOperand<'tcx> {
let this = self;
let tcx = this.tcx;
let Expr { ty, temp_lifetime: _, span, ref kind } = *expr;
@@ -44,62 +42,62 @@ pub fn as_constant_inner<'tcx>(
expr: &Expr<'tcx>,
push_cuta: impl FnMut(&Box<CanonicalUserType<'tcx>>) -> Option<UserTypeAnnotationIndex>,
tcx: TyCtxt<'tcx>,
-) -> Constant<'tcx> {
+) -> ConstOperand<'tcx> {
let Expr { ty, temp_lifetime: _, span, ref kind } = *expr;
match *kind {
ExprKind::Literal { lit, neg } => {
- let literal =
- match lit_to_mir_constant(tcx, LitToConstInput { lit: &lit.node, ty, neg }) {
- Ok(c) => c,
- Err(LitToConstError::Reported(guar)) => {
- ConstantKind::Ty(ty::Const::new_error(tcx, guar, ty))
- }
- Err(LitToConstError::TypeError) => {
- bug!("encountered type error in `lit_to_mir_constant`")
- }
- };
-
- Constant { span, user_ty: None, literal }
+ let const_ = match lit_to_mir_constant(tcx, LitToConstInput { lit: &lit.node, ty, neg })
+ {
+ Ok(c) => c,
+ Err(LitToConstError::Reported(guar)) => {
+ Const::Ty(ty::Const::new_error(tcx, guar, ty))
+ }
+ Err(LitToConstError::TypeError) => {
+ bug!("encountered type error in `lit_to_mir_constant`")
+ }
+ };
+
+ ConstOperand { span, user_ty: None, const_ }
}
ExprKind::NonHirLiteral { lit, ref user_ty } => {
let user_ty = user_ty.as_ref().and_then(push_cuta);
- let literal = ConstantKind::Val(ConstValue::Scalar(Scalar::Int(lit)), ty);
+ let const_ = Const::Val(ConstValue::Scalar(Scalar::Int(lit)), ty);
- Constant { span, user_ty, literal }
+ ConstOperand { span, user_ty, const_ }
}
ExprKind::ZstLiteral { ref user_ty } => {
let user_ty = user_ty.as_ref().and_then(push_cuta);
- let literal = ConstantKind::Val(ConstValue::ZeroSized, ty);
+ let const_ = Const::Val(ConstValue::ZeroSized, ty);
- Constant { span, user_ty, literal }
+ ConstOperand { span, user_ty, const_ }
}
ExprKind::NamedConst { def_id, args, ref user_ty } => {
let user_ty = user_ty.as_ref().and_then(push_cuta);
let uneval = mir::UnevaluatedConst::new(def_id, args);
- let literal = ConstantKind::Unevaluated(uneval, ty);
+ let const_ = Const::Unevaluated(uneval, ty);
- Constant { user_ty, span, literal }
+ ConstOperand { user_ty, span, const_ }
}
ExprKind::ConstParam { param, def_id: _ } => {
let const_param = ty::Const::new_param(tcx, param, expr.ty);
- let literal = ConstantKind::Ty(const_param);
+ let const_ = Const::Ty(const_param);
- Constant { user_ty: None, span, literal }
+ ConstOperand { user_ty: None, span, const_ }
}
ExprKind::ConstBlock { did: def_id, args } => {
let uneval = mir::UnevaluatedConst::new(def_id, args);
- let literal = ConstantKind::Unevaluated(uneval, ty);
+ let const_ = Const::Unevaluated(uneval, ty);
- Constant { user_ty: None, span, literal }
+ ConstOperand { user_ty: None, span, const_ }
}
ExprKind::StaticRef { alloc_id, ty, .. } => {
let const_val = ConstValue::Scalar(Scalar::from_pointer(alloc_id.into(), &tcx));
- let literal = ConstantKind::Val(const_val, ty);
+ let const_ = Const::Val(const_val, ty);
- Constant { span, user_ty: None, literal }
+ ConstOperand { span, user_ty: None, const_ }
}
_ => span_bug!(span, "expression is not a valid constant {:?}", kind),
}
@@ -109,7 +107,7 @@ pub fn as_constant_inner<'tcx>(
fn lit_to_mir_constant<'tcx>(
tcx: TyCtxt<'tcx>,
lit_input: LitToConstInput<'tcx>,
-) -> Result<ConstantKind<'tcx>, LitToConstError> {
+) -> Result<Const<'tcx>, LitToConstError> {
let LitToConstInput { lit, ty, neg } = lit_input;
let trunc = |n| {
let param_ty = ty::ParamEnv::reveal_all().and(ty);
@@ -133,14 +131,14 @@ fn lit_to_mir_constant<'tcx>(
let s = s.as_str();
let allocation = Allocation::from_bytes_byte_aligned_immutable(s.as_bytes());
let allocation = tcx.mk_const_alloc(allocation);
- ConstValue::Slice { data: allocation, start: 0, end: s.len() }
+ ConstValue::Slice { data: allocation, meta: allocation.inner().size().bytes() }
}
(ast::LitKind::ByteStr(data, _), ty::Ref(_, inner_ty, _))
if matches!(inner_ty.kind(), ty::Slice(_)) =>
{
let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]);
let allocation = tcx.mk_const_alloc(allocation);
- ConstValue::Slice { data: allocation, start: 0, end: data.len() }
+ ConstValue::Slice { data: allocation, meta: allocation.inner().size().bytes() }
}
(ast::LitKind::ByteStr(data, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_array() => {
let id = tcx.allocate_bytes(data);
@@ -150,7 +148,7 @@ fn lit_to_mir_constant<'tcx>(
{
let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]);
let allocation = tcx.mk_const_alloc(allocation);
- ConstValue::Slice { data: allocation, start: 0, end: data.len() }
+ ConstValue::Slice { data: allocation, meta: allocation.inner().size().bytes() }
}
(ast::LitKind::Byte(n), ty::Uint(ty::UintTy::U8)) => {
ConstValue::Scalar(Scalar::from_uint(*n, Size::from_bytes(1)))
@@ -175,5 +173,5 @@ fn lit_to_mir_constant<'tcx>(
_ => return Err(LitToConstError::TypeError),
};
- Ok(ConstantKind::Val(value, ty))
+ Ok(Const::Val(value, ty))
}
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 2e7ef265a..5bccba4fd 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs
@@ -102,7 +102,7 @@ fn convert_to_hir_projections_and_truncate_for_capture(
continue;
}
// These do not affect anything, they just make sure we know the right type.
- ProjectionElem::OpaqueCast(_) => continue,
+ ProjectionElem::OpaqueCast(_) | ProjectionElem::Subtype(..) => continue,
ProjectionElem::Index(..)
| ProjectionElem::ConstantIndex { .. }
| ProjectionElem::Subslice { .. } => {
@@ -690,7 +690,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
fake_borrow_temp.into(),
Rvalue::Ref(
tcx.lifetimes.re_erased,
- BorrowKind::Shallow,
+ BorrowKind::Fake,
Place { local: base_place.local, projection },
),
);
@@ -709,6 +709,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
ProjectionElem::Field(..)
| ProjectionElem::Downcast(..)
| ProjectionElem::OpaqueCast(..)
+ | ProjectionElem::Subtype(..)
| ProjectionElem::ConstantIndex { .. }
| ProjectionElem::Subslice { .. } => (),
}
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 3220a184d..d4089eef4 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -249,7 +249,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let mut comparer = |range: u128, bin_op: BinOp| -> Place<'tcx> {
let range_val =
- ConstantKind::from_bits(this.tcx, range, ty::ParamEnv::empty().and(unsigned_ty));
+ Const::from_bits(this.tcx, range, ty::ParamEnv::empty().and(unsigned_ty));
let lit_op = this.literal_operand(expr.span, range_val);
let is_bin_op = this.temp(bool_ty, expr_span);
this.cfg.push_assign(
@@ -485,10 +485,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => {
block = unpack!(this.stmt_expr(block, expr, None));
- block.and(Rvalue::Use(Operand::Constant(Box::new(Constant {
+ block.and(Rvalue::Use(Operand::Constant(Box::new(ConstOperand {
span: expr_span,
user_ty: None,
- literal: ConstantKind::zero_sized(this.tcx.types.unit),
+ const_: Const::zero_sized(this.tcx.types.unit),
}))))
}
@@ -817,7 +817,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
fn neg_1_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> {
let param_ty = ty::ParamEnv::empty().and(ty);
let size = self.tcx.layout_of(param_ty).unwrap().size;
- let literal = ConstantKind::from_bits(self.tcx, size.unsigned_int_max(), param_ty);
+ let literal = Const::from_bits(self.tcx, size.unsigned_int_max(), param_ty);
self.literal_operand(span, literal)
}
@@ -828,7 +828,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let param_ty = ty::ParamEnv::empty().and(ty);
let bits = self.tcx.layout_of(param_ty).unwrap().size.bits();
let n = 1 << (bits - 1);
- let literal = ConstantKind::from_bits(self.tcx, n, param_ty);
+ let literal = Const::from_bits(self.tcx, n, param_ty);
self.literal_operand(span, literal)
}
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index a5c86e31a..a4de42d45 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -114,10 +114,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
true_block,
source_info,
destination,
- Constant {
+ ConstOperand {
span: expr_span,
user_ty: None,
- literal: ConstantKind::from_bool(this.tcx, true),
+ const_: Const::from_bool(this.tcx, true),
},
);
@@ -125,10 +125,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
false_block,
source_info,
destination,
- Constant {
+ ConstOperand {
span: expr_span,
user_ty: None,
- literal: ConstantKind::from_bool(this.tcx, false),
+ const_: Const::from_bool(this.tcx, false),
},
);
@@ -159,52 +159,44 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}
ExprKind::LogicalOp { op, lhs, rhs } => {
- // And:
- //
- // [block: If(lhs)] -true-> [else_block: dest = (rhs)]
- // | (false)
- // [shortcircuit_block: dest = false]
- //
- // Or:
- //
- // [block: If(lhs)] -false-> [else_block: dest = (rhs)]
- // | (true)
- // [shortcircuit_block: dest = true]
-
- let (shortcircuit_block, mut else_block, join_block) = (
- this.cfg.start_new_block(),
- this.cfg.start_new_block(),
- this.cfg.start_new_block(),
- );
-
- let lhs = unpack!(block = this.as_local_operand(block, &this.thir[lhs]));
- let blocks = match op {
- LogicalOp::And => (else_block, shortcircuit_block),
- LogicalOp::Or => (shortcircuit_block, else_block),
+ let condition_scope = this.local_scope();
+ let source_info = this.source_info(expr.span);
+ // We first evaluate the left-hand side of the predicate ...
+ let (then_block, else_block) =
+ this.in_if_then_scope(condition_scope, expr.span, |this| {
+ this.then_else_break(
+ block,
+ &this.thir[lhs],
+ Some(condition_scope),
+ condition_scope,
+ source_info,
+ )
+ });
+ let (short_circuit, continuation, constant) = match op {
+ LogicalOp::And => (else_block, then_block, false),
+ LogicalOp::Or => (then_block, else_block, true),
};
- let term = TerminatorKind::if_(lhs, blocks.0, blocks.1);
- this.cfg.terminate(block, source_info, term);
-
+ // At this point, the control flow splits into a short-circuiting path
+ // and a continuation path.
+ // - If the operator is `&&`, passing `lhs` leads to continuation of evaluation on `rhs`;
+ // failing it leads to the short-circuting path which assigns `false` to the place.
+ // - If the operator is `||`, failing `lhs` leads to continuation of evaluation on `rhs`;
+ // passing it leads to the short-circuting path which assigns `true` to the place.
this.cfg.push_assign_constant(
- shortcircuit_block,
+ short_circuit,
source_info,
destination,
- Constant {
- span: expr_span,
+ ConstOperand {
+ span: expr.span,
user_ty: None,
- literal: match op {
- LogicalOp::And => ConstantKind::from_bool(this.tcx, false),
- LogicalOp::Or => ConstantKind::from_bool(this.tcx, true),
- },
+ const_: Const::from_bool(this.tcx, constant),
},
);
- this.cfg.goto(shortcircuit_block, source_info, join_block);
-
- let rhs = unpack!(else_block = this.as_local_operand(else_block, &this.thir[rhs]));
- this.cfg.push_assign(else_block, source_info, destination, Rvalue::Use(rhs));
- this.cfg.goto(else_block, source_info, join_block);
-
- join_block.unit()
+ let rhs = unpack!(this.expr_into_dest(destination, continuation, &this.thir[rhs]));
+ let target = this.cfg.start_new_block();
+ this.cfg.goto(rhs, source_info, target);
+ this.cfg.goto(short_circuit, source_info, target);
+ target.unit()
}
ExprKind::Loop { body } => {
// [block]
@@ -441,12 +433,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
thir::InlineAsmOperand::Const { value, span } => {
mir::InlineAsmOperand::Const {
- value: Box::new(Constant { span, user_ty: None, literal: value }),
+ value: Box::new(ConstOperand {
+ span,
+ user_ty: None,
+ const_: value,
+ }),
}
}
thir::InlineAsmOperand::SymFn { value, span } => {
mir::InlineAsmOperand::SymFn {
- value: Box::new(Constant { span, user_ty: None, literal: value }),
+ value: Box::new(ConstOperand {
+ span,
+ user_ty: None,
+ const_: value,
+ }),
}
}
thir::InlineAsmOperand::SymStatic { def_id } => {