diff --git a/src/abi/pass_mode.rs b/src/abi/pass_mode.rs index 024a9a9137c7..7c9f8c1051cb 100644 --- a/src/abi/pass_mode.rs +++ b/src/abi/pass_mode.rs @@ -100,11 +100,11 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { } _ => unreachable!("{:?}", self.layout.abi), }, - PassMode::Cast(ref cast, pad_i32) => { + PassMode::Cast { ref cast, pad_i32 } => { assert!(!pad_i32, "padding support not yet implemented"); cast_target_to_abi_params(cast) } - PassMode::Indirect { attrs, extra_attrs: None, on_stack } => { + PassMode::Indirect { attrs, meta_attrs: None, on_stack } => { if on_stack { // Abi requires aligning struct size to pointer size let size = self.layout.size.align_to(tcx.data_layout.pointer_align.abi); @@ -117,11 +117,11 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { smallvec![apply_arg_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), attrs)] } } - PassMode::Indirect { attrs, extra_attrs: Some(extra_attrs), on_stack } => { + PassMode::Indirect { attrs, meta_attrs: Some(meta_attrs), on_stack } => { assert!(!on_stack); smallvec![ apply_arg_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), attrs), - apply_arg_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), extra_attrs), + apply_arg_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), meta_attrs), ] } } @@ -148,14 +148,14 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { } _ => unreachable!("{:?}", self.layout.abi), }, - PassMode::Cast(ref cast, _) => { + PassMode::Cast { ref cast, .. } => { (None, cast_target_to_abi_params(cast).into_iter().collect()) } - PassMode::Indirect { attrs: _, extra_attrs: None, on_stack } => { + PassMode::Indirect { attrs: _, meta_attrs: None, on_stack } => { assert!(!on_stack); (Some(AbiParam::special(pointer_ty(tcx), ArgumentPurpose::StructReturn)), vec![]) } - PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => { + PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => { unreachable!("unsized return value") } } @@ -229,7 +229,7 @@ pub(super) fn adjust_arg_for_abi<'tcx>( let (a, b) = arg.load_scalar_pair(fx); smallvec![a, b] } - PassMode::Cast(ref cast, _) => to_casted_value(fx, arg, cast), + PassMode::Cast { ref cast, .. } => to_casted_value(fx, arg, cast), PassMode::Indirect { .. } => { if is_owned { match arg.force_stack(fx) { @@ -287,14 +287,14 @@ pub(super) fn cvalue_for_param<'tcx>( assert_eq!(block_params.len(), 2, "{:?}", block_params); Some(CValue::by_val_pair(block_params[0], block_params[1], arg_abi.layout)) } - PassMode::Cast(ref cast, _) => { + PassMode::Cast { ref cast, .. } => { Some(from_casted_value(fx, &block_params, arg_abi.layout, cast)) } - PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => { + PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => { assert_eq!(block_params.len(), 1, "{:?}", block_params); Some(CValue::by_ref(Pointer::new(block_params[0]), arg_abi.layout)) } - PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => { + PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => { assert_eq!(block_params.len(), 2, "{:?}", block_params); Some(CValue::by_ref_unsized( Pointer::new(block_params[0]), diff --git a/src/abi/returning.rs b/src/abi/returning.rs index ff86f74d9b98..0799a22c6e16 100644 --- a/src/abi/returning.rs +++ b/src/abi/returning.rs @@ -13,7 +13,7 @@ pub(super) fn codegen_return_param<'tcx>( block_params_iter: &mut impl Iterator, ) -> CPlace<'tcx> { let (ret_place, ret_param): (_, SmallVec<[_; 2]>) = match fx.fn_abi.as_ref().unwrap().ret.mode { - PassMode::Ignore | PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast(..) => { + PassMode::Ignore | PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast { .. } => { let is_ssa = ssa_analyzed[RETURN_PLACE].is_ssa(fx, fx.fn_abi.as_ref().unwrap().ret.layout.ty); ( @@ -26,7 +26,7 @@ pub(super) fn codegen_return_param<'tcx>( smallvec![], ) } - PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => { + PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => { let ret_param = block_params_iter.next().unwrap(); assert_eq!(fx.bcx.func.dfg.value_type(ret_param), fx.pointer_type); ( @@ -34,7 +34,7 @@ pub(super) fn codegen_return_param<'tcx>( smallvec![ret_param], ) } - PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => { + PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => { unreachable!("unsized return value") } }; @@ -62,7 +62,7 @@ pub(super) fn codegen_with_call_return_arg<'tcx>( ) { let (ret_temp_place, return_ptr) = match ret_arg_abi.mode { PassMode::Ignore => (None, None), - PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => { + PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => { if let Some(ret_ptr) = ret_place.try_to_ptr() { // This is an optimization to prevent unnecessary copies of the return value when // the return place is already a memory place as opposed to a register. @@ -73,10 +73,10 @@ pub(super) fn codegen_with_call_return_arg<'tcx>( (Some(place), Some(place.to_ptr().get_addr(fx))) } } - PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => { + PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => { unreachable!("unsized return value") } - PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast(..) => (None, None), + PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast { .. } => (None, None), }; let call_inst = f(fx, return_ptr); @@ -93,21 +93,21 @@ pub(super) fn codegen_with_call_return_arg<'tcx>( ret_place .write_cvalue(fx, CValue::by_val_pair(ret_val_a, ret_val_b, ret_arg_abi.layout)); } - PassMode::Cast(ref cast, _) => { + PassMode::Cast { ref cast, .. } => { let results = fx.bcx.inst_results(call_inst).iter().copied().collect::>(); let result = super::pass_mode::from_casted_value(fx, &results, ret_place.layout(), cast); ret_place.write_cvalue(fx, result); } - PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => { + PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => { if let Some(ret_temp_place) = ret_temp_place { // If ret_temp_place is None, it is not necessary to copy the return value. let ret_temp_value = ret_temp_place.to_cvalue(fx); ret_place.write_cvalue(fx, ret_temp_value); } } - PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => { + PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => { unreachable!("unsized return value") } } @@ -116,10 +116,10 @@ pub(super) fn codegen_with_call_return_arg<'tcx>( /// Codegen a return instruction with the right return value(s) if any. pub(crate) fn codegen_return(fx: &mut FunctionCx<'_, '_, '_>) { match fx.fn_abi.as_ref().unwrap().ret.mode { - PassMode::Ignore | PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => { + PassMode::Ignore | PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => { fx.bcx.ins().return_(&[]); } - PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => { + PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => { unreachable!("unsized return value") } PassMode::Direct(_) => { @@ -132,7 +132,7 @@ pub(crate) fn codegen_return(fx: &mut FunctionCx<'_, '_, '_>) { let (ret_val_a, ret_val_b) = place.to_cvalue(fx).load_scalar_pair(fx); fx.bcx.ins().return_(&[ret_val_a, ret_val_b]); } - PassMode::Cast(ref cast, _) => { + PassMode::Cast { ref cast, .. } => { let place = fx.get_local_place(RETURN_PLACE); let ret_val = place.to_cvalue(fx); let ret_vals = super::pass_mode::to_casted_value(fx, ret_val, cast); diff --git a/src/base.rs b/src/base.rs index b4d5fd0b0921..798de7ccc79c 100644 --- a/src/base.rs +++ b/src/base.rs @@ -249,7 +249,10 @@ pub(crate) fn verify_func( } fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { - if !crate::constant::check_constants(fx) { + if let Err(err) = + fx.mir.post_mono_checks(fx.tcx, ty::ParamEnv::reveal_all(), |c| Ok(fx.monomorphize(c))) + { + err.emit_err(fx.tcx); fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]); fx.bcx.switch_to_block(fx.block_map[START_BLOCK]); // compilation should have been aborted diff --git a/src/constant.rs b/src/constant.rs index 3cfe957e397e..259c50ee6588 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -3,9 +3,7 @@ use cranelift_module::*; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; -use rustc_middle::mir::interpret::{ - read_target_uint, AllocId, ConstAllocation, ConstValue, ErrorHandled, GlobalAlloc, Scalar, -}; +use rustc_middle::mir::interpret::{read_target_uint, AllocId, ConstValue, GlobalAlloc, Scalar}; use crate::prelude::*; @@ -32,16 +30,6 @@ impl ConstantCx { } } -pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool { - let mut all_constants_ok = true; - for constant in &fx.mir.required_consts { - if eval_mir_constant(fx, constant).is_none() { - all_constants_ok = false; - } - } - all_constants_ok -} - pub(crate) fn codegen_static(tcx: TyCtxt<'_>, module: &mut dyn Module, def_id: DefId) { let mut constants_cx = ConstantCx::new(); constants_cx.todo.push(TodoItem::Static(def_id)); @@ -75,30 +63,20 @@ pub(crate) fn codegen_tls_ref<'tcx>( pub(crate) fn eval_mir_constant<'tcx>( fx: &FunctionCx<'_, '_, 'tcx>, constant: &Constant<'tcx>, -) -> Option<(ConstValue<'tcx>, Ty<'tcx>)> { +) -> (ConstValue<'tcx>, Ty<'tcx>) { let cv = fx.monomorphize(constant.literal); + // This cannot fail because we checked all required_consts in advance. let val = cv .eval(fx.tcx, ty::ParamEnv::reveal_all(), Some(constant.span)) - .map_err(|err| match err { - ErrorHandled::Reported(_) => { - fx.tcx.sess.span_err(constant.span, "erroneous constant encountered"); - } - ErrorHandled::TooGeneric => { - span_bug!(constant.span, "codegen encountered polymorphic constant: {:?}", err); - } - }) - .ok(); - val.map(|val| (val, cv.ty())) + .expect("erroneous constant not captured by required_consts"); + (val, cv.ty()) } pub(crate) fn codegen_constant_operand<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, constant: &Constant<'tcx>, ) -> CValue<'tcx> { - let (const_val, ty) = eval_mir_constant(fx, constant).unwrap_or_else(|| { - span_bug!(constant.span, "erroneous constant not captured by required_consts") - }); - + let (const_val, ty) = eval_mir_constant(fx, constant); codegen_const_value(fx, const_val, ty) } @@ -115,7 +93,7 @@ pub(crate) fn codegen_const_value<'tcx>( } match const_val { - ConstValue::ZeroSized => unreachable!(), // we already handles ZST above + ConstValue::ZeroSized => unreachable!(), // we already handled ZST above ConstValue::Scalar(x) => match x { Scalar::Int(int) => { if fx.clif_type(layout.ty).is_some() { @@ -199,13 +177,14 @@ pub(crate) fn codegen_const_value<'tcx>( CValue::by_val(val, layout) } }, - ConstValue::ByRef { alloc, offset } => CValue::by_ref( - pointer_for_allocation(fx, alloc) + ConstValue::Indirect { alloc_id, offset } => CValue::by_ref( + pointer_for_allocation(fx, alloc_id) .offset_i64(fx, i64::try_from(offset.bytes()).unwrap()), layout, ), ConstValue::Slice { data, start, end } => { - let ptr = pointer_for_allocation(fx, data) + let alloc_id = fx.tcx.reserve_and_set_memory_alloc(data); + let ptr = pointer_for_allocation(fx, alloc_id) .offset_i64(fx, i64::try_from(start).unwrap()) .get_addr(fx); let len = fx @@ -219,9 +198,9 @@ pub(crate) fn codegen_const_value<'tcx>( fn pointer_for_allocation<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, - alloc: ConstAllocation<'tcx>, + alloc_id: AllocId, ) -> crate::pointer::Pointer { - let alloc_id = fx.tcx.create_memory_alloc(alloc); + let alloc = fx.tcx.global_alloc(alloc_id).unwrap_memory(); let data_id = data_id_for_alloc_id( &mut fx.constants_cx, &mut *fx.module, @@ -352,6 +331,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant unreachable!() } }; + // FIXME: should we have a cache so we don't do this multiple times for the same `ConstAllocation`? let data_id = *cx.anon_allocs.entry(alloc_id).or_insert_with(|| { module.declare_anonymous_data(alloc.inner().mutability.is_mut(), false).unwrap() }); @@ -456,7 +436,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( operand: &Operand<'tcx>, ) -> Option> { match operand { - Operand::Constant(const_) => Some(eval_mir_constant(fx, const_).unwrap().0), + Operand::Constant(const_) => Some(eval_mir_constant(fx, const_).0), // FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored // inside a temporary before being passed to the intrinsic requiring the const argument. // This code tries to find a single constant defining definition of the referenced local. diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 73d7c14ec003..5467190970e4 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -242,8 +242,7 @@ pub(crate) fn codegen_inline_asm<'tcx>( } } InlineAsmOperand::Const { ref value } => { - let (const_value, ty) = crate::constant::eval_mir_constant(fx, value) - .unwrap_or_else(|| span_bug!(span, "asm const cannot be resolved")); + let (const_value, ty) = crate::constant::eval_mir_constant(fx, value); let value = rustc_codegen_ssa::common::asm_const_to_str( fx.tcx, span, diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index b90d4f4bce49..9278f99e0da1 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -176,7 +176,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( }; let idx_bytes = match idx_const { - ConstValue::ByRef { alloc, offset } => { + ConstValue::Indirect { alloc_id, offset } => { + let alloc = fx.tcx.global_alloc(alloc_id).unwrap_memory(); let size = Size::from_bytes( 4 * ret_lane_count, /* size_of([u32; ret_lane_count]) */ );