diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
commit | c23a457e72abe608715ac76f076f47dc42af07a5 (patch) | |
tree | 2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /compiler/rustc_mir_build/src/build/expr | |
parent | Releasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-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')
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 } => { |