From 083f1d7a37a5b439c1b9325e7860ef4fd880d418 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 30 Jul 2020 17:58:39 +0200 Subject: [PATCH 01/18] Validate constants during `const_eval_raw` --- .../rustc_mir/src/const_eval/eval_queries.rs | 51 +++++++++++++------ compiler/rustc_mir/src/interpret/validity.rs | 18 ++++--- .../ui/consts/const-eval/double_check2.rs | 23 ++++++--- .../ui/consts/const-eval/double_check2.stderr | 22 -------- 4 files changed, 62 insertions(+), 52 deletions(-) delete mode 100644 src/test/ui/consts/const-eval/double_check2.stderr diff --git a/compiler/rustc_mir/src/const_eval/eval_queries.rs b/compiler/rustc_mir/src/const_eval/eval_queries.rs index 72151df7230..dd2731fb0a0 100644 --- a/compiler/rustc_mir/src/const_eval/eval_queries.rs +++ b/compiler/rustc_mir/src/const_eval/eval_queries.rs @@ -193,21 +193,7 @@ fn validate_and_turn_into_const<'tcx>( let ecx = mk_eval_cx(tcx, tcx.def_span(key.value.instance.def_id()), key.param_env, is_static); let val = (|| { let mplace = ecx.raw_const_to_mplace(constant)?; - - // FIXME do not validate promoteds until a decision on - // https://github.com/rust-lang/rust/issues/67465 is made - if cid.promoted.is_none() { - let mut ref_tracking = RefTracking::new(mplace); - while let Some((mplace, path)) = ref_tracking.todo.pop() { - ecx.const_validate_operand( - mplace.into(), - path, - &mut ref_tracking, - /*may_ref_to_static*/ ecx.memory.extra.can_access_statics, - )?; - } - } - // Now that we validated, turn this into a proper constant. + // Turn this into a proper constant. // Statics/promoteds are always `ByRef`, for the rest `op_to_const` decides // whether they become immediates. if is_static || cid.promoted.is_some() { @@ -221,6 +207,7 @@ fn validate_and_turn_into_const<'tcx>( } })(); + // FIXME: Can this ever be an error and not be a compiler bug or can we just ICE here? val.map_err(|error| { let err = ConstEvalErr::new(&ecx, error, None); err.struct_error(ecx.tcx, "it is undefined behavior to use this value", |mut diag| { @@ -319,7 +306,6 @@ pub fn const_eval_raw_provider<'tcx>( let res = ecx.load_mir(cid.instance.def, cid.promoted); res.and_then(|body| eval_body_using_ecx(&mut ecx, cid, &body)) - .map(|place| RawConst { alloc_id: place.ptr.assert_ptr().alloc_id, ty: place.layout.ty }) .map_err(|error| { let err = ConstEvalErr::new(&ecx, error, None); // errors in statics are always emitted as fatal errors @@ -397,4 +383,37 @@ pub fn const_eval_raw_provider<'tcx>( err.report_as_error(ecx.tcx.at(ecx.cur_span()), "could not evaluate constant") } }) + .and_then(|mplace| { + // Since evaluation had no errors, valiate the resulting constant: + let validation = try { + // FIXME do not validate promoteds until a decision on + // https://github.com/rust-lang/rust/issues/67465 is made + if cid.promoted.is_none() { + let mut ref_tracking = RefTracking::new(mplace); + while let Some((mplace, path)) = ref_tracking.todo.pop() { + ecx.const_validate_operand( + mplace.into(), + path, + &mut ref_tracking, + /*may_ref_to_static*/ ecx.memory.extra.can_access_statics, + )?; + } + } + }; + if let Err(error) = validation { + // Validation failed, report an error + let err = ConstEvalErr::new(&ecx, error, None); + Err(err.struct_error( + ecx.tcx, + "it is undefined behavior to use this value", + |mut diag| { + diag.note(note_on_undefined_behavior_error()); + diag.emit(); + }, + )) + } else { + // Convert to raw constant + Ok(RawConst { alloc_id: mplace.ptr.assert_ptr().alloc_id, ty: mplace.layout.ty }) + } + }) } diff --git a/compiler/rustc_mir/src/interpret/validity.rs b/compiler/rustc_mir/src/interpret/validity.rs index ca62f0347ff..7d9507c08fa 100644 --- a/compiler/rustc_mir/src/interpret/validity.rs +++ b/compiler/rustc_mir/src/interpret/validity.rs @@ -425,26 +425,28 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' let alloc_kind = self.ecx.tcx.get_global_alloc(ptr.alloc_id); if let Some(GlobalAlloc::Static(did)) = alloc_kind { assert!(!self.ecx.tcx.is_thread_local_static(did)); + assert!(self.ecx.tcx.is_static(did)); // See const_eval::machine::MemoryExtra::can_access_statics for why // this check is so important. // This check is reachable when the const just referenced the static, // but never read it (so we never entered `before_access_global`). // We also need to do it here instead of going on to avoid running // into the `before_access_global` check during validation. - if !self.may_ref_to_static && self.ecx.tcx.is_static(did) { + if !self.may_ref_to_static { throw_validation_failure!(self.path, { "a {} pointing to a static variable", kind } ); } - // `extern static` cannot be validated as they have no body. - // FIXME: Statics from other crates are also skipped. - // They might be checked at a different type, but for now we - // want to avoid recursing too deeply. We might miss const-invalid data, + // We skip checking other statics. These statics must be sound by themselves, + // and the only way to get broken statics here is by using unsafe code. + // The reasons we don't check other statics is twofold. For one, in all sound + // cases, the static was already validated on its own, and second, we trigger + // cycle errors if we try to compute the value of the other static and that + // static refers back to us. + // We might miss const-invalid data, // but things are still sound otherwise (in particular re: consts // referring to statics). - if !did.is_local() || self.ecx.tcx.is_foreign_item(did) { - return Ok(()); - } + return Ok(()); } } // Proceed recursively even for ZST, no reason to skip them! diff --git a/src/test/ui/consts/const-eval/double_check2.rs b/src/test/ui/consts/const-eval/double_check2.rs index 8402d628856..e1f3e5bb27a 100644 --- a/src/test/ui/consts/const-eval/double_check2.rs +++ b/src/test/ui/consts/const-eval/double_check2.rs @@ -1,3 +1,11 @@ +// check-pass + +// This test exhibits undefined behavior, but it is impossible to prevent generally during +// const eval, even if possible to prevent in the cases here. The reason it's impossible in general +// is that we run into query cycles even *without* UB, just because we're checking for UB. +// We do not detect it if you create references to statics +// in ways that are UB. + enum Foo { A = 5, B = 42, @@ -13,11 +21,14 @@ union Union { u8: &'static u8, } static BAR: u8 = 5; -static FOO: (&Foo, &Bar) = unsafe {( //~ undefined behavior - Union { u8: &BAR }.foo, - Union { u8: &BAR }.bar, -)}; -static FOO2: (&Foo, &Bar) = unsafe {(std::mem::transmute(&BAR), std::mem::transmute(&BAR))}; -//~^ undefined behavior +static FOO: (&Foo, &Bar) = unsafe { + ( + // undefined behavior + Union { u8: &BAR }.foo, + Union { u8: &BAR }.bar, + ) +}; +static FOO2: (&Foo, &Bar) = unsafe { (std::mem::transmute(&BAR), std::mem::transmute(&BAR)) }; +//^ undefined behavior fn main() {} diff --git a/src/test/ui/consts/const-eval/double_check2.stderr b/src/test/ui/consts/const-eval/double_check2.stderr deleted file mode 100644 index 84f60809156..00000000000 --- a/src/test/ui/consts/const-eval/double_check2.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error[E0080]: it is undefined behavior to use this value - --> $DIR/double_check2.rs:16:1 - | -LL | / static FOO: (&Foo, &Bar) = unsafe {( -LL | | Union { u8: &BAR }.foo, -LL | | Union { u8: &BAR }.bar, -LL | | )}; - | |___^ type validation failed: encountered 0x05 at .1.., but expected a valid enum tag - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - -error[E0080]: it is undefined behavior to use this value - --> $DIR/double_check2.rs:20:1 - | -LL | static FOO2: (&Foo, &Bar) = unsafe {(std::mem::transmute(&BAR), std::mem::transmute(&BAR))}; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x05 at .1.., but expected a valid enum tag - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0080`. From 2d7ac728e4ce2aa1a77068e1f668be71d10116a0 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 31 Jul 2020 13:27:54 +0200 Subject: [PATCH 02/18] Stop using the `const_eval` query for initializers of statics As a side effect, we now represent most promoteds as `ConstValue::Scalar` again. This is useful because all implict promoteds are just references anyway and most explicit promoteds are numeric arguments to `asm!` or SIMD instructions. --- compiler/rustc_codegen_llvm/src/consts.rs | 7 ++--- compiler/rustc_codegen_ssa/src/mir/block.rs | 26 +++++----------- compiler/rustc_lint/src/builtin.rs | 15 ++++----- .../rustc_mir/src/const_eval/eval_queries.rs | 31 +++++++------------ .../rustc_mir/src/interpret/eval_context.rs | 7 ----- compiler/rustc_mir/src/interpret/operand.rs | 8 ++--- .../rustc_mir/src/monomorphize/collector.rs | 6 ++-- compiler/rustc_mir/src/util/pretty.rs | 7 ++--- compiler/rustc_typeck/src/check/mod.rs | 6 ++-- ...nst-pointer-values-in-various-types.stderr | 12 +++---- src/test/ui/consts/const-eval/ub-enum.stderr | 8 ++--- .../ui/consts/const-eval/ub-nonnull.stderr | 2 +- src/test/ui/consts/const-eval/ub-ref.stderr | 2 +- .../recursive-zst-static.default.stderr | 6 +--- .../recursive-zst-static.unleash.stderr | 6 +--- .../recursive-static-definition.stderr | 6 +--- .../ui/write-to-static-mut-in-static.stderr | 6 +--- 17 files changed, 53 insertions(+), 108 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 2b2bcd97999..dc09790df02 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -12,7 +12,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::Node; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::interpret::{ - read_target_uint, Allocation, ConstValue, ErrorHandled, GlobalAlloc, Pointer, + read_target_uint, Allocation, ErrorHandled, GlobalAlloc, Pointer, }; use rustc_middle::mir::mono::MonoItem; use rustc_middle::ty::{self, Instance, Ty}; @@ -85,10 +85,7 @@ pub fn codegen_static_initializer( cx: &CodegenCx<'ll, 'tcx>, def_id: DefId, ) -> Result<(&'ll Value, &'tcx Allocation), ErrorHandled> { - let alloc = match cx.tcx.const_eval_poly(def_id)? { - ConstValue::ByRef { alloc, offset } if offset.bytes() == 0 => alloc, - val => bug!("static const eval returned {:#?}", val), - }; + let alloc = cx.tcx.eval_static_initializer(def_id)?; Ok((const_alloc_to_llvm(cx, alloc), alloc)) } diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 4639ce4a5ab..23269f7245d 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -13,7 +13,7 @@ use rustc_ast as ast; use rustc_hir::lang_items::LangItem; use rustc_index::vec::Idx; use rustc_middle::mir; -use rustc_middle::mir::interpret::{AllocId, ConstValue, Pointer, Scalar}; +use rustc_middle::mir::interpret::ConstValue; use rustc_middle::mir::AssertKind; use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt}; use rustc_middle::ty::print::with_no_trimmed_paths; @@ -867,24 +867,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let ty = constant.literal.ty; let size = bx.layout_of(ty).size; let scalar = match const_value { - // Promoted constants are evaluated into a ByRef instead of a Scalar, - // but we want the scalar value here. - ConstValue::ByRef { alloc, offset } => { - let ptr = Pointer::new(AllocId(0), offset); - alloc - .read_scalar(&bx, ptr, size) - .and_then(|s| s.check_init()) - .unwrap_or_else(|e| { - bx.tcx().sess.span_err( - span, - &format!("Could not evaluate asm const: {}", e), - ); - - // We are erroring out, just emit a dummy constant. - Scalar::from_u64(0) - }) - } - _ => span_bug!(span, "expected ByRef for promoted asm const"), + ConstValue::Scalar(s) => s, + _ => span_bug!( + span, + "expected Scalar for promoted asm const, but got {:#?}", + const_value + ), }; let value = scalar.assert_bits(size); let string = match ty.kind() { diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 5b5dbcf192c..71d4ae85d33 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1473,21 +1473,18 @@ declare_lint_pass!( UnusedBrokenConst => [] ); -fn check_const(cx: &LateContext<'_>, body_id: hir::BodyId) { - let def_id = cx.tcx.hir().body_owner_def_id(body_id).to_def_id(); - // trigger the query once for all constants since that will already report the errors - // FIXME: Use ensure here - let _ = cx.tcx.const_eval_poly(def_id); -} - impl<'tcx> LateLintPass<'tcx> for UnusedBrokenConst { fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { match it.kind { hir::ItemKind::Const(_, body_id) => { - check_const(cx, body_id); + let def_id = cx.tcx.hir().body_owner_def_id(body_id).to_def_id(); + // trigger the query once for all constants since that will already report the errors + // FIXME: Use ensure here + let _ = cx.tcx.const_eval_poly(def_id); } hir::ItemKind::Static(_, _, body_id) => { - check_const(cx, body_id); + let def_id = cx.tcx.hir().body_owner_def_id(body_id).to_def_id(); + let _ = cx.tcx.eval_static_initializer(def_id); } _ => {} } diff --git a/compiler/rustc_mir/src/const_eval/eval_queries.rs b/compiler/rustc_mir/src/const_eval/eval_queries.rs index dd2731fb0a0..013c6746605 100644 --- a/compiler/rustc_mir/src/const_eval/eval_queries.rs +++ b/compiler/rustc_mir/src/const_eval/eval_queries.rs @@ -182,7 +182,7 @@ pub(super) fn op_to_const<'tcx>( } } -fn validate_and_turn_into_const<'tcx>( +fn turn_into_const<'tcx>( tcx: TyCtxt<'tcx>, constant: RawConst<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, @@ -191,30 +191,21 @@ fn validate_and_turn_into_const<'tcx>( let def_id = cid.instance.def.def_id(); let is_static = tcx.is_static(def_id); let ecx = mk_eval_cx(tcx, tcx.def_span(key.value.instance.def_id()), key.param_env, is_static); - let val = (|| { - let mplace = ecx.raw_const_to_mplace(constant)?; - // Turn this into a proper constant. - // Statics/promoteds are always `ByRef`, for the rest `op_to_const` decides - // whether they become immediates. - if is_static || cid.promoted.is_some() { - let ptr = mplace.ptr.assert_ptr(); - Ok(ConstValue::ByRef { - alloc: ecx.tcx.global_alloc(ptr.alloc_id).unwrap_memory(), - offset: ptr.offset, - }) - } else { - Ok(op_to_const(&ecx, mplace.into())) - } - })(); - // FIXME: Can this ever be an error and not be a compiler bug or can we just ICE here? - val.map_err(|error| { + let mplace = ecx.raw_const_to_mplace(constant).map_err(|error| { + // FIXME: Can the above ever error and not be a compiler bug or can we just ICE here? let err = ConstEvalErr::new(&ecx, error, None); err.struct_error(ecx.tcx, "it is undefined behavior to use this value", |mut diag| { diag.note(note_on_undefined_behavior_error()); diag.emit(); }) - }) + })?; + assert!( + !is_static || cid.promoted.is_some(), + "the const eval query should not be used for statics, use `const_eval_raw` instead" + ); + // Turn this into a proper constant. + Ok(op_to_const(&ecx, mplace.into())) } pub fn const_eval_validated_provider<'tcx>( @@ -248,7 +239,7 @@ pub fn const_eval_validated_provider<'tcx>( }); } - tcx.const_eval_raw(key).and_then(|val| validate_and_turn_into_const(tcx, val, key)) + tcx.const_eval_raw(key).and_then(|val| turn_into_const(tcx, val, key)) } pub fn const_eval_raw_provider<'tcx>( diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index f2f6c893eda..b2901d8d6a2 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -914,13 +914,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } else { self.param_env }; - // We use `const_eval_raw` here, and get an unvalidated result. That is okay: - // Our result will later be validated anyway, and there seems no good reason - // to have to fail early here. This is also more consistent with - // `Memory::get_static_alloc` which has to use `const_eval_raw` to avoid cycles. - // FIXME: We can hit delay_span_bug if this is an invalid const, interning finds - // that problem, but we never run validation to show an error. Can we ensure - // this does not happen? let val = self.tcx.const_eval_raw(param_env.and(gid))?; self.raw_const_to_mplace(val) } diff --git a/compiler/rustc_mir/src/interpret/operand.rs b/compiler/rustc_mir/src/interpret/operand.rs index 57245696e57..2be771a58ef 100644 --- a/compiler/rustc_mir/src/interpret/operand.rs +++ b/compiler/rustc_mir/src/interpret/operand.rs @@ -554,11 +554,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ty::ConstKind::Unevaluated(def, substs, promoted) => { let instance = self.resolve(def.did, substs)?; // We use `const_eval` here and `const_eval_raw` elsewhere in mir interpretation. - // The reason we use `const_eval_raw` everywhere else is to prevent cycles during - // validation, because validation automatically reads through any references, thus - // potentially requiring the current static to be evaluated again. This is not a - // problem here, because we are building an operand which means an actual read is - // happening. + // The reason we use `const_eval` here is that there can never be a `ty::ConstKind` + // that directly mentions the initializer of a static. Statics are always encoded + // as constants with vaule `&STATIC`. return Ok(self.const_eval(GlobalId { instance, promoted }, val.ty)?); } ty::ConstKind::Infer(..) diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs index 0dbb4b1015e..4ef871b05f4 100644 --- a/compiler/rustc_mir/src/monomorphize/collector.rs +++ b/compiler/rustc_mir/src/monomorphize/collector.rs @@ -364,8 +364,10 @@ fn collect_items_rec<'tcx>( recursion_depth_reset = None; - if let Ok(val) = tcx.const_eval_poly(def_id) { - collect_const_value(tcx, val, &mut neighbors); + if let Ok(alloc) = tcx.eval_static_initializer(def_id) { + for &((), id) in alloc.relocations().values() { + collect_miri(tcx, id, &mut neighbors); + } } } MonoItem::Fn(instance) => { diff --git a/compiler/rustc_mir/src/util/pretty.rs b/compiler/rustc_mir/src/util/pretty.rs index 75567181b69..49c644a20bf 100644 --- a/compiler/rustc_mir/src/util/pretty.rs +++ b/compiler/rustc_mir/src/util/pretty.rs @@ -631,14 +631,11 @@ pub fn write_allocations<'tcx>( None => write!(w, " (deallocated)")?, Some(GlobalAlloc::Function(inst)) => write!(w, " (fn: {})", inst)?, Some(GlobalAlloc::Static(did)) if !tcx.is_foreign_item(did) => { - match tcx.const_eval_poly(did) { - Ok(ConstValue::ByRef { alloc, .. }) => { + match tcx.eval_static_initializer(did) { + Ok(alloc) => { write!(w, " (static: {}, ", tcx.def_path_str(did))?; write_allocation_track_relocs(w, alloc)?; } - Ok(_) => { - span_bug!(tcx.def_span(did), " static item without `ByRef` initializer") - } Err(_) => write!( w, " (static: {}, error during initializer evaluation)", diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs index 9a9e57638d7..e84cc3c9b86 100644 --- a/compiler/rustc_typeck/src/check/mod.rs +++ b/compiler/rustc_typeck/src/check/mod.rs @@ -111,7 +111,6 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc_infer::infer::{InferCtxt, InferOk, InferResult, RegionVariableOrigin, TyCtxtInferExt}; use rustc_middle::hir::map::blocks::FnLikeNode; -use rustc_middle::mir::interpret::ConstValue; use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, }; @@ -2070,8 +2069,8 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId, span: S // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is // the consumer's responsibility to ensure all bytes that have been read // have defined values. - match tcx.const_eval_poly(id.to_def_id()) { - Ok(ConstValue::ByRef { alloc, .. }) => { + match tcx.eval_static_initializer(id.to_def_id()) { + Ok(alloc) => { if alloc.relocations().len() != 0 { let msg = "statics with a custom `#[link_section]` must be a \ simple list of bytes on the wasm target with no \ @@ -2079,7 +2078,6 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId, span: S tcx.sess.span_err(span, msg); } } - Ok(_) => bug!("Matching on non-ByRef static"), Err(_) => {} } } diff --git a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr index d24491e1bc5..fb0ed1bd5aa 100644 --- a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr +++ b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr @@ -36,7 +36,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/const-pointer-values-in-various-types.rs:37:5 | LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uint_64 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc22, but expected initialized plain (non-pointer) bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc18, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. @@ -76,7 +76,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/const-pointer-values-in-various-types.rs:52:5 | LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc47, but expected initialized plain (non-pointer) bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc38, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. @@ -100,7 +100,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/const-pointer-values-in-various-types.rs:61:5 | LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc62, but expected initialized plain (non-pointer) bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc50, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. @@ -148,7 +148,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/const-pointer-values-in-various-types.rs:79:5 | LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc86, but expected initialized plain (non-pointer) bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc71, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. @@ -188,7 +188,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/const-pointer-values-in-various-types.rs:94:5 | LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc101, but expected initialized plain (non-pointer) bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc86, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. @@ -212,7 +212,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/const-pointer-values-in-various-types.rs:103:5 | LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc110, but expected initialized plain (non-pointer) bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc95, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. diff --git a/src/test/ui/consts/const-eval/ub-enum.stderr b/src/test/ui/consts/const-eval/ub-enum.stderr index 7b3ee535c8e..db95b996c18 100644 --- a/src/test/ui/consts/const-eval/ub-enum.stderr +++ b/src/test/ui/consts/const-eval/ub-enum.stderr @@ -18,7 +18,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:30:1 | LL | const BAD_ENUM_WRAPPED: Wrap = unsafe { mem::transmute(&1) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc13 at .0., but expected initialized plain (non-pointer) bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc12 at .0., but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. @@ -34,7 +34,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:44:1 | LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc20 at ., but expected initialized plain (non-pointer) bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc18 at ., but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. @@ -42,7 +42,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:47:1 | LL | const BAD_ENUM2_WRAPPED: Wrap = unsafe { mem::transmute(&0) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc25 at .0., but expected initialized plain (non-pointer) bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc22 at .0., but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. @@ -58,7 +58,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:60:1 | LL | const BAD_ENUM2_OPTION_PTR: Option = unsafe { mem::transmute(&0) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc32 at ., but expected initialized plain (non-pointer) bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc28 at ., but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. diff --git a/src/test/ui/consts/const-eval/ub-nonnull.stderr b/src/test/ui/consts/const-eval/ub-nonnull.stderr index 38e9bdecdb9..afd8a4b9e59 100644 --- a/src/test/ui/consts/const-eval/ub-nonnull.stderr +++ b/src/test/ui/consts/const-eval/ub-nonnull.stderr @@ -13,7 +13,7 @@ LL | / const OUT_OF_BOUNDS_PTR: NonNull = { unsafe { LL | | let ptr: &[u8; 256] = mem::transmute(&0u8); // &0 gets promoted so it does not dangle LL | | // Use address-of-element for pointer arithmetic. This could wrap around to NULL! LL | | let out_of_bounds_ptr = &ptr[255]; - | | ^^^^^^^^^ memory access failed: pointer must be in-bounds at offset 256, but is outside bounds of alloc11 which has size 1 + | | ^^^^^^^^^ memory access failed: pointer must be in-bounds at offset 256, but is outside bounds of alloc10 which has size 1 LL | | mem::transmute(out_of_bounds_ptr) LL | | } }; | |____- diff --git a/src/test/ui/consts/const-eval/ub-ref.stderr b/src/test/ui/consts/const-eval/ub-ref.stderr index cd270f2a533..429ae69eabf 100644 --- a/src/test/ui/consts/const-eval/ub-ref.stderr +++ b/src/test/ui/consts/const-eval/ub-ref.stderr @@ -34,7 +34,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-ref.rs:23:1 | LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc16, but expected initialized plain (non-pointer) bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc14, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. diff --git a/src/test/ui/consts/recursive-zst-static.default.stderr b/src/test/ui/consts/recursive-zst-static.default.stderr index 9042c6f6be1..d58f044cf6d 100644 --- a/src/test/ui/consts/recursive-zst-static.default.stderr +++ b/src/test/ui/consts/recursive-zst-static.default.stderr @@ -10,11 +10,7 @@ note: ...which requires const-evaluating `FOO`... LL | static FOO: () = FOO; | ^^^^^^^^^^^^^^^^^^^^^ = note: ...which again requires const-evaluating `FOO`, completing the cycle -note: cycle used when const-evaluating + checking `FOO` - --> $DIR/recursive-zst-static.rs:10:1 - | -LL | static FOO: () = FOO; - | ^^^^^^^^^^^^^^^^^^^^^ + = note: cycle used when running analysis passes on this crate error: aborting due to previous error diff --git a/src/test/ui/consts/recursive-zst-static.unleash.stderr b/src/test/ui/consts/recursive-zst-static.unleash.stderr index 9042c6f6be1..d58f044cf6d 100644 --- a/src/test/ui/consts/recursive-zst-static.unleash.stderr +++ b/src/test/ui/consts/recursive-zst-static.unleash.stderr @@ -10,11 +10,7 @@ note: ...which requires const-evaluating `FOO`... LL | static FOO: () = FOO; | ^^^^^^^^^^^^^^^^^^^^^ = note: ...which again requires const-evaluating `FOO`, completing the cycle -note: cycle used when const-evaluating + checking `FOO` - --> $DIR/recursive-zst-static.rs:10:1 - | -LL | static FOO: () = FOO; - | ^^^^^^^^^^^^^^^^^^^^^ + = note: cycle used when running analysis passes on this crate error: aborting due to previous error diff --git a/src/test/ui/recursion/recursive-static-definition.stderr b/src/test/ui/recursion/recursive-static-definition.stderr index 093606e100c..97e42a1f126 100644 --- a/src/test/ui/recursion/recursive-static-definition.stderr +++ b/src/test/ui/recursion/recursive-static-definition.stderr @@ -10,11 +10,7 @@ note: ...which requires const-evaluating `FOO`... LL | pub static FOO: u32 = FOO; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which again requires const-evaluating `FOO`, completing the cycle -note: cycle used when const-evaluating + checking `FOO` - --> $DIR/recursive-static-definition.rs:1:1 - | -LL | pub static FOO: u32 = FOO; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: cycle used when running analysis passes on this crate error: aborting due to previous error diff --git a/src/test/ui/write-to-static-mut-in-static.stderr b/src/test/ui/write-to-static-mut-in-static.stderr index 50dfce3448c..6f21539c119 100644 --- a/src/test/ui/write-to-static-mut-in-static.stderr +++ b/src/test/ui/write-to-static-mut-in-static.stderr @@ -16,11 +16,7 @@ note: ...which requires const-evaluating `C`... LL | pub static mut C: u32 = unsafe { C = 1; 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which again requires const-evaluating `C`, completing the cycle -note: cycle used when const-evaluating + checking `C` - --> $DIR/write-to-static-mut-in-static.rs:5:1 - | -LL | pub static mut C: u32 = unsafe { C = 1; 0 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: cycle used when running analysis passes on this crate error: aborting due to 2 previous errors From 6d3c7bb70ddedfd9770047d7b0b79dd2aae515af Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 31 Jul 2020 19:10:37 +0200 Subject: [PATCH 03/18] Update codegen tests --- src/test/codegen/consts.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/codegen/consts.rs b/src/test/codegen/consts.rs index 318f9b0eec3..a69a4885bb5 100644 --- a/src/test/codegen/consts.rs +++ b/src/test/codegen/consts.rs @@ -14,7 +14,7 @@ // This checks the constants from {low,high}_align_const, they share the same // constant, but the alignment differs, so the higher one should be used -// CHECK: [[LOW_HIGH:@[0-9]+]] = {{.*}} getelementptr inbounds (<{ [8 x i8] }>, <{ [8 x i8] }>* @alloc20, i32 0, i32 0, i32 0), {{.*}} +// CHECK: [[LOW_HIGH:@alloc[0-9]+]] = {{.*}}, align 4 #[derive(Copy, Clone)] // repr(i16) is required for the {low,high}_align_const test @@ -43,7 +43,7 @@ pub fn inline_enum_const() -> E { #[no_mangle] pub fn low_align_const() -> E { // Check that low_align_const and high_align_const use the same constant - // CHECK: load %"E"*, %"E"** bitcast (<{ i8*, [0 x i8] }>* [[LOW_HIGH]] to %"E"**), + // CHECK: memcpy.p0i8.p0i8.i64(i8* align 2 %1, i8* align 2 getelementptr inbounds (<{ [8 x i8] }>, <{ [8 x i8] }>* [[LOW_HIGH]], i32 0, i32 0, i32 0), i64 8, i1 false) *&E::A(0) } @@ -51,6 +51,6 @@ pub fn low_align_const() -> E { #[no_mangle] pub fn high_align_const() -> E { // Check that low_align_const and high_align_const use the same constant - // CHECK: load %"E"*, %"E"** bitcast (<{ i8*, [0 x i8] }>* [[LOW_HIGH]] to %"E"**), + // CHECK: memcpy.p0i8.p0i8.i64(i8* align 4 %1, i8* align 4 getelementptr inbounds (<{ [8 x i8] }>, <{ [8 x i8] }>* [[LOW_HIGH]], i32 0, i32 0, i32 0), i64 8, i1 false) *&E::A(0) } From 4397d66d428509ef6867bae78b13a33c828573d0 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 10 Aug 2020 11:48:52 +0200 Subject: [PATCH 04/18] Document `op_to_const`'s purpose --- compiler/rustc_mir/src/const_eval/eval_queries.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_mir/src/const_eval/eval_queries.rs b/compiler/rustc_mir/src/const_eval/eval_queries.rs index 013c6746605..8b0cbae4333 100644 --- a/compiler/rustc_mir/src/const_eval/eval_queries.rs +++ b/compiler/rustc_mir/src/const_eval/eval_queries.rs @@ -104,6 +104,8 @@ pub(super) fn mk_eval_cx<'mir, 'tcx>( ) } +/// This function converts an interpreter value into a constant that is meant for use in the +/// type system. pub(super) fn op_to_const<'tcx>( ecx: &CompileTimeEvalContext<'_, 'tcx>, op: OpTy<'tcx>, From b1bd34df0c0757f988353c30766d58df0b4ebe73 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 10 Aug 2020 11:57:20 +0200 Subject: [PATCH 05/18] `turn_into_const` is infallible --- .../rustc_mir/src/const_eval/eval_queries.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_mir/src/const_eval/eval_queries.rs b/compiler/rustc_mir/src/const_eval/eval_queries.rs index 8b0cbae4333..e52b90dffde 100644 --- a/compiler/rustc_mir/src/const_eval/eval_queries.rs +++ b/compiler/rustc_mir/src/const_eval/eval_queries.rs @@ -188,26 +188,22 @@ fn turn_into_const<'tcx>( tcx: TyCtxt<'tcx>, constant: RawConst<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, -) -> ::rustc_middle::mir::interpret::ConstEvalResult<'tcx> { +) -> ConstValue<'tcx> { let cid = key.value; let def_id = cid.instance.def.def_id(); let is_static = tcx.is_static(def_id); let ecx = mk_eval_cx(tcx, tcx.def_span(key.value.instance.def_id()), key.param_env, is_static); - let mplace = ecx.raw_const_to_mplace(constant).map_err(|error| { - // FIXME: Can the above ever error and not be a compiler bug or can we just ICE here? - let err = ConstEvalErr::new(&ecx, error, None); - err.struct_error(ecx.tcx, "it is undefined behavior to use this value", |mut diag| { - diag.note(note_on_undefined_behavior_error()); - diag.emit(); - }) - })?; + let mplace = ecx.raw_const_to_mplace(constant).expect( + "can only fail if layout computation failed, \ + which should have given a good error before ever invoking this function", + ); assert!( !is_static || cid.promoted.is_some(), "the const eval query should not be used for statics, use `const_eval_raw` instead" ); // Turn this into a proper constant. - Ok(op_to_const(&ecx, mplace.into())) + op_to_const(&ecx, mplace.into()) } pub fn const_eval_validated_provider<'tcx>( @@ -241,7 +237,7 @@ pub fn const_eval_validated_provider<'tcx>( }); } - tcx.const_eval_raw(key).and_then(|val| turn_into_const(tcx, val, key)) + tcx.const_eval_raw(key).map(|val| turn_into_const(tcx, val, key)) } pub fn const_eval_raw_provider<'tcx>( From 48f366fced077805b917448f7554a50d23160892 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 10 Aug 2020 12:04:01 +0200 Subject: [PATCH 06/18] Replace `and_then` `map_err` `and_then` chain with a match --- .../rustc_mir/src/const_eval/eval_queries.rs | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_mir/src/const_eval/eval_queries.rs b/compiler/rustc_mir/src/const_eval/eval_queries.rs index e52b90dffde..8f2a89d4676 100644 --- a/compiler/rustc_mir/src/const_eval/eval_queries.rs +++ b/compiler/rustc_mir/src/const_eval/eval_queries.rs @@ -294,8 +294,8 @@ pub fn const_eval_raw_provider<'tcx>( ); let res = ecx.load_mir(cid.instance.def, cid.promoted); - res.and_then(|body| eval_body_using_ecx(&mut ecx, cid, &body)) - .map_err(|error| { + match res.and_then(|body| eval_body_using_ecx(&mut ecx, cid, &body)) { + Err(error) => { let err = ConstEvalErr::new(&ecx, error, None); // errors in statics are always emitted as fatal errors if is_static { @@ -317,7 +317,7 @@ pub fn const_eval_raw_provider<'tcx>( ); } - v + Err(v) } else if let Some(def) = def.as_local() { // constant defined in this crate, we can figure out a lint level! match tcx.def_kind(def.did.to_def_id()) { @@ -331,12 +331,12 @@ pub fn const_eval_raw_provider<'tcx>( // compatibility hazard DefKind::Const | DefKind::AssocConst => { let hir_id = tcx.hir().local_def_id_to_hir_id(def.did); - err.report_as_lint( + Err(err.report_as_lint( tcx.at(tcx.def_span(def.did)), "any use of this value will cause an error", hir_id, Some(err.span), - ) + )) } // promoting runtime code is only allowed to error if it references broken // constants any other kind of error will be reported to the user as a @@ -345,34 +345,34 @@ pub fn const_eval_raw_provider<'tcx>( if let Some(p) = cid.promoted { let span = tcx.promoted_mir_of_opt_const_arg(def.to_global())[p].span; if let err_inval!(ReferencedConstant) = err.error { - err.report_as_error( + Err(err.report_as_error( tcx.at(span), "evaluation of constant expression failed", - ) + )) } else { - err.report_as_lint( + Err(err.report_as_lint( tcx.at(span), "reaching this expression at runtime will panic or abort", tcx.hir().local_def_id_to_hir_id(def.did), Some(err.span), - ) + )) } // anything else (array lengths, enum initializers, constant patterns) are // reported as hard errors } else { - err.report_as_error( + Err(err.report_as_error( ecx.tcx.at(ecx.cur_span()), "evaluation of constant value failed", - ) + )) } } } } else { // use of broken constant from other crate - err.report_as_error(ecx.tcx.at(ecx.cur_span()), "could not evaluate constant") + Err(err.report_as_error(ecx.tcx.at(ecx.cur_span()), "could not evaluate constant")) } - }) - .and_then(|mplace| { + } + Ok(mplace) => { // Since evaluation had no errors, valiate the resulting constant: let validation = try { // FIXME do not validate promoteds until a decision on @@ -404,5 +404,6 @@ pub fn const_eval_raw_provider<'tcx>( // Convert to raw constant Ok(RawConst { alloc_id: mplace.ptr.assert_ptr().alloc_id, ty: mplace.layout.ty }) } - }) + } + } } From a6c60bbe5de9a090c8da30d5edbd27582f6b19e6 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 10 Aug 2020 12:08:52 +0200 Subject: [PATCH 07/18] Clarify a statement in UB test --- src/test/ui/consts/const-eval/double_check2.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/ui/consts/const-eval/double_check2.rs b/src/test/ui/consts/const-eval/double_check2.rs index e1f3e5bb27a..b89db0b97d9 100644 --- a/src/test/ui/consts/const-eval/double_check2.rs +++ b/src/test/ui/consts/const-eval/double_check2.rs @@ -1,7 +1,9 @@ // check-pass // This test exhibits undefined behavior, but it is impossible to prevent generally during -// const eval, even if possible to prevent in the cases here. The reason it's impossible in general +// const eval, even if it could be prevented in the cases here if we added expensive and +// complex checks in rustc. +// The reason it's impossible in general // is that we run into query cycles even *without* UB, just because we're checking for UB. // We do not detect it if you create references to statics // in ways that are UB. From dd9702a059eae845624478bfa12b978e8e269157 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 10 Aug 2020 12:40:14 +0200 Subject: [PATCH 08/18] Do not call the `const_eval` query in mir interpretation except for caching of nulary intrinsics --- compiler/rustc_mir/src/const_eval/machine.rs | 2 +- .../rustc_mir/src/interpret/eval_context.rs | 29 ++----------------- .../rustc_mir/src/interpret/intrinsics.rs | 5 +++- compiler/rustc_mir/src/interpret/operand.rs | 6 +--- 4 files changed, 8 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_mir/src/const_eval/machine.rs b/compiler/rustc_mir/src/const_eval/machine.rs index 02e905505c0..8b0e993f02d 100644 --- a/compiler/rustc_mir/src/const_eval/machine.rs +++ b/compiler/rustc_mir/src/const_eval/machine.rs @@ -51,7 +51,7 @@ impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> { let gid = GlobalId { instance, promoted: None }; - let place = self.const_eval_raw(gid)?; + let place = self.const_eval(gid)?; self.copy_op(place.into(), dest)?; diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index b2901d8d6a2..2bf14cca877 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -20,7 +20,7 @@ use rustc_span::{Pos, Span}; use rustc_target::abi::{Align, HasDataLayout, LayoutOf, Size, TargetDataLayout}; use super::{ - Immediate, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Memory, OpTy, Operand, Place, PlaceTy, + Immediate, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Memory, Operand, Place, PlaceTy, ScalarMaybeUninit, StackPopJump, }; use crate::transform::validate::equal_up_to_regions; @@ -875,32 +875,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(()) } - pub(super) fn const_eval( - &self, - gid: GlobalId<'tcx>, - ty: Ty<'tcx>, - ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { - // For statics we pick `ParamEnv::reveal_all`, because statics don't have generics - // and thus don't care about the parameter environment. While we could just use - // `self.param_env`, that would mean we invoke the query to evaluate the static - // with different parameter environments, thus causing the static to be evaluated - // multiple times. - let param_env = if self.tcx.is_static(gid.instance.def_id()) { - ty::ParamEnv::reveal_all() - } else { - self.param_env - }; - let val = self.tcx.const_eval_global_id(param_env, gid, Some(self.tcx.span))?; - - // Even though `ecx.const_eval` is called from `const_to_op` we can never have a - // recursion deeper than one level, because the `tcx.const_eval` above is guaranteed to not - // return `ConstValue::Unevaluated`, which is the only way that `const_to_op` will call - // `ecx.const_eval`. - let const_ = ty::Const { val: ty::ConstKind::Value(val), ty }; - self.const_to_op(&const_, None) - } - - pub fn const_eval_raw( + pub fn const_eval( &self, gid: GlobalId<'tcx>, ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { diff --git a/compiler/rustc_mir/src/interpret/intrinsics.rs b/compiler/rustc_mir/src/interpret/intrinsics.rs index 47ca71d9642..0664f25e409 100644 --- a/compiler/rustc_mir/src/interpret/intrinsics.rs +++ b/compiler/rustc_mir/src/interpret/intrinsics.rs @@ -152,7 +152,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { sym::type_name => self.tcx.mk_static_str(), _ => bug!("already checked for nullary intrinsics"), }; - let val = self.const_eval(gid, ty)?; + let val = + self.tcx.const_eval_global_id(self.param_env, gid, Some(self.tcx.span))?; + let const_ = ty::Const { val: ty::ConstKind::Value(val), ty }; + let val = self.const_to_op(&const_, None)?; self.copy_op(val, dest)?; } diff --git a/compiler/rustc_mir/src/interpret/operand.rs b/compiler/rustc_mir/src/interpret/operand.rs index 2be771a58ef..54c43b518fd 100644 --- a/compiler/rustc_mir/src/interpret/operand.rs +++ b/compiler/rustc_mir/src/interpret/operand.rs @@ -553,11 +553,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ty::ConstKind::Error(_) => throw_inval!(TypeckError(ErrorReported)), ty::ConstKind::Unevaluated(def, substs, promoted) => { let instance = self.resolve(def.did, substs)?; - // We use `const_eval` here and `const_eval_raw` elsewhere in mir interpretation. - // The reason we use `const_eval` here is that there can never be a `ty::ConstKind` - // that directly mentions the initializer of a static. Statics are always encoded - // as constants with vaule `&STATIC`. - return Ok(self.const_eval(GlobalId { instance, promoted }, val.ty)?); + return Ok(self.const_eval(GlobalId { instance, promoted })?.into()); } ty::ConstKind::Infer(..) | ty::ConstKind::Bound(..) From 40c2087eb5623a724d0a24db925f9c9afcd4df0d Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 10 Aug 2020 12:40:29 +0200 Subject: [PATCH 09/18] We can make const eval sound, it's just super expensive --- src/test/ui/consts/const-eval/double_check2.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/test/ui/consts/const-eval/double_check2.rs b/src/test/ui/consts/const-eval/double_check2.rs index b89db0b97d9..81f5dde450b 100644 --- a/src/test/ui/consts/const-eval/double_check2.rs +++ b/src/test/ui/consts/const-eval/double_check2.rs @@ -1,12 +1,8 @@ // check-pass -// This test exhibits undefined behavior, but it is impossible to prevent generally during -// const eval, even if it could be prevented in the cases here if we added expensive and -// complex checks in rustc. -// The reason it's impossible in general -// is that we run into query cycles even *without* UB, just because we're checking for UB. -// We do not detect it if you create references to statics -// in ways that are UB. +// This test exhibits undefined behavior, but it is very expensive and complex to check for such +// UB in constants. +// Thus, we do not detect it if you create references to statics in ways that are UB. enum Foo { A = 5, From 69a6be73e619299a22a8ee7f64bb5532395f938d Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 10 Aug 2020 15:11:40 +0200 Subject: [PATCH 10/18] Rename const eval queries to reflect the validation changes --- .../rustc_middle/src/mir/interpret/queries.rs | 6 +++--- compiler/rustc_middle/src/query/mod.rs | 19 ++++++------------- .../rustc_mir/src/const_eval/eval_queries.rs | 14 +++++++------- .../rustc_mir/src/interpret/eval_context.rs | 2 +- compiler/rustc_mir/src/interpret/memory.rs | 2 +- compiler/rustc_mir/src/lib.rs | 4 ++-- 6 files changed, 20 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index dcc1f8b1a4b..20577bdc6bd 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -69,9 +69,9 @@ impl<'tcx> TyCtxt<'tcx> { // improve caching of queries. let inputs = self.erase_regions(¶m_env.and(cid)); if let Some(span) = span { - self.at(span).const_eval_validated(inputs) + self.at(span).const_eval_for_ty(inputs) } else { - self.const_eval_validated(inputs) + self.const_eval_for_ty(inputs) } } @@ -94,7 +94,7 @@ impl<'tcx> TyCtxt<'tcx> { param_env: ty::ParamEnv<'tcx>, ) -> Result<&'tcx mir::Allocation, ErrorHandled> { trace!("eval_to_allocation: Need to compute {:?}", gid); - let raw_const = self.const_eval_raw(param_env.and(gid))?; + let raw_const = self.const_eval(param_env.and(gid))?; Ok(self.global_alloc(raw_const.alloc_id).unwrap_memory()) } } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 44d906dada5..dc89cf35648 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -707,13 +707,8 @@ rustc_queries! { } Other { - /// Evaluates a constant without running sanity checks. - /// - /// **Do not use this** outside const eval. Const eval uses this to break query cycles - /// during validation. Please add a comment to every use site explaining why using - /// `const_eval_validated` isn't sufficient. The returned constant also isn't in a suitable - /// form to be used outside of const eval. - query const_eval_raw(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) + /// Evaluates a constant and returns the computed allocation. + query const_eval(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> ConstEvalRawResult<'tcx> { desc { |tcx| "const-evaluating `{}`", @@ -721,15 +716,13 @@ rustc_queries! { } } - /// Results of evaluating const items or constants embedded in - /// other items (such as enum variant explicit discriminants). - /// - /// In contrast to `const_eval_raw` this performs some validation on the constant, and - /// returns a proper constant that is usable by the rest of the compiler. + /// Evaluates const items or anonymous constants + /// (such as enum variant explicit discriminants or array lengths) + /// into a representation suitable for the type system and const generics. /// /// **Do not use this** directly, use one of the following wrappers: `tcx.const_eval_poly`, /// `tcx.const_eval_resolve`, `tcx.const_eval_instance`, or `tcx.const_eval_global_id`. - query const_eval_validated(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) + query const_eval_for_ty(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> ConstEvalResult<'tcx> { desc { |tcx| "const-evaluating + checking `{}`", diff --git a/compiler/rustc_mir/src/const_eval/eval_queries.rs b/compiler/rustc_mir/src/const_eval/eval_queries.rs index 8f2a89d4676..3b01328df56 100644 --- a/compiler/rustc_mir/src/const_eval/eval_queries.rs +++ b/compiler/rustc_mir/src/const_eval/eval_queries.rs @@ -200,21 +200,21 @@ fn turn_into_const<'tcx>( ); assert!( !is_static || cid.promoted.is_some(), - "the const eval query should not be used for statics, use `const_eval_raw` instead" + "the `const_eval_for_ty` query should not be used for statics, use `const_eval` instead" ); // Turn this into a proper constant. op_to_const(&ecx, mplace.into()) } -pub fn const_eval_validated_provider<'tcx>( +pub fn const_eval_for_ty_provider<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, ) -> ::rustc_middle::mir::interpret::ConstEvalResult<'tcx> { - // see comment in const_eval_raw_provider for what we're doing here + // see comment in const_eval_provider for what we're doing here if key.param_env.reveal() == Reveal::All { let mut key = key; key.param_env = key.param_env.with_user_facing(); - match tcx.const_eval_validated(key) { + match tcx.const_eval_for_ty(key) { // try again with reveal all as requested Err(ErrorHandled::TooGeneric) => {} // deduplicate calls @@ -237,10 +237,10 @@ pub fn const_eval_validated_provider<'tcx>( }); } - tcx.const_eval_raw(key).map(|val| turn_into_const(tcx, val, key)) + tcx.const_eval(key).map(|val| turn_into_const(tcx, val, key)) } -pub fn const_eval_raw_provider<'tcx>( +pub fn const_eval_provider<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, ) -> ::rustc_middle::mir::interpret::ConstEvalRawResult<'tcx> { @@ -255,7 +255,7 @@ pub fn const_eval_raw_provider<'tcx>( if key.param_env.reveal() == Reveal::All { let mut key = key; key.param_env = key.param_env.with_user_facing(); - match tcx.const_eval_raw(key) { + match tcx.const_eval(key) { // try again with reveal all as requested Err(ErrorHandled::TooGeneric) => {} // deduplicate calls diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index 2bf14cca877..ef05d136da1 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -889,7 +889,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } else { self.param_env }; - let val = self.tcx.const_eval_raw(param_env.and(gid))?; + let val = self.tcx.const_eval(param_env.and(gid))?; self.raw_const_to_mplace(val) } diff --git a/compiler/rustc_mir/src/interpret/memory.rs b/compiler/rustc_mir/src/interpret/memory.rs index d4be2ce0568..64918a76857 100644 --- a/compiler/rustc_mir/src/interpret/memory.rs +++ b/compiler/rustc_mir/src/interpret/memory.rs @@ -469,7 +469,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // Notice that every static has two `AllocId` that will resolve to the same // thing here: one maps to `GlobalAlloc::Static`, this is the "lazy" ID, // and the other one is maps to `GlobalAlloc::Memory`, this is returned by - // `const_eval_raw` and it is the "resolved" ID. + // `const_eval` and it is the "resolved" ID. // The resolved ID is never used by the interpreted program, it is hidden. // This is relied upon for soundness of const-patterns; a pointer to the resolved // ID would "sidestep" the checks that make sure consts do not point to statics! diff --git a/compiler/rustc_mir/src/lib.rs b/compiler/rustc_mir/src/lib.rs index 42717f27384..07defa2d66d 100644 --- a/compiler/rustc_mir/src/lib.rs +++ b/compiler/rustc_mir/src/lib.rs @@ -52,8 +52,8 @@ pub fn provide(providers: &mut Providers) { transform::provide(providers); monomorphize::partitioning::provide(providers); monomorphize::polymorphize::provide(providers); - providers.const_eval_validated = const_eval::const_eval_validated_provider; - providers.const_eval_raw = const_eval::const_eval_raw_provider; + providers.const_eval_for_ty = const_eval::const_eval_for_ty_provider; + providers.const_eval = const_eval::const_eval_provider; providers.const_caller_location = const_eval::const_caller_location; providers.destructure_const = |tcx, param_env_and_value| { let (param_env, value) = param_env_and_value.into_parts(); From 888afd50d97f0a92fbbbafb703b3225dc1bb1a70 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 20 Aug 2020 18:55:07 +0200 Subject: [PATCH 11/18] Unify the names of const eval queries and their return types --- compiler/rustc_infer/src/infer/mod.rs | 4 ++-- .../rustc_middle/src/mir/interpret/error.rs | 4 ++-- compiler/rustc_middle/src/mir/interpret/mod.rs | 6 +++--- .../rustc_middle/src/mir/interpret/queries.rs | 16 ++++++++-------- .../rustc_middle/src/mir/interpret/value.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 10 ++++++---- compiler/rustc_middle/src/ty/query/mod.rs | 2 +- .../rustc_mir/src/const_eval/eval_queries.rs | 18 +++++++++--------- compiler/rustc_mir/src/const_eval/machine.rs | 2 +- .../rustc_mir/src/interpret/eval_context.rs | 4 ++-- compiler/rustc_mir/src/interpret/operand.rs | 2 +- compiler/rustc_mir/src/lib.rs | 4 ++-- 12 files changed, 38 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 685d2bac94e..2cbdc954e20 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -21,7 +21,7 @@ use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues}; use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue}; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType}; use rustc_middle::mir; -use rustc_middle::mir::interpret::ConstEvalResult; +use rustc_middle::mir::interpret::EvalToConstValueResult; use rustc_middle::traits::select; use rustc_middle::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric}; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder}; @@ -1542,7 +1542,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { substs: SubstsRef<'tcx>, promoted: Option, span: Option, - ) -> ConstEvalResult<'tcx> { + ) -> EvalToConstValueResult<'tcx> { let mut original_values = OriginalQueryValues::default(); let canonical = self.canonicalize_query(&(param_env, substs), &mut original_values); diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 059925088ce..62d02250fe0 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -27,8 +27,8 @@ CloneTypeFoldableAndLiftImpls! { ErrorHandled, } -pub type ConstEvalRawResult<'tcx> = Result, ErrorHandled>; -pub type ConstEvalResult<'tcx> = Result, ErrorHandled>; +pub type EvalToAllocationRawResult<'tcx> = Result, ErrorHandled>; +pub type EvalToConstValueResult<'tcx> = Result, ErrorHandled>; pub fn struct_error<'tcx>(tcx: TyCtxtAt<'tcx>, msg: &str) -> DiagnosticBuilder<'tcx> { struct_span_err!(tcx.sess, tcx.span, E0080, "{}", msg) diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index cbc362d934f..71a99cf95f8 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -118,9 +118,9 @@ use crate::ty::subst::GenericArgKind; use crate::ty::{self, Instance, Ty, TyCtxt}; pub use self::error::{ - struct_error, CheckInAllocMsg, ConstEvalRawResult, ConstEvalResult, ErrorHandled, InterpError, - InterpErrorInfo, InterpResult, InvalidProgramInfo, MachineStopType, ResourceExhaustionInfo, - UndefinedBehaviorInfo, UninitBytesAccess, UnsupportedOpInfo, + struct_error, CheckInAllocMsg, ErrorHandled, EvalToAllocationRawResult, EvalToConstValueResult, + InterpError, InterpErrorInfo, InterpResult, InvalidProgramInfo, MachineStopType, + ResourceExhaustionInfo, UndefinedBehaviorInfo, UninitBytesAccess, UnsupportedOpInfo, }; pub use self::value::{get_slice_bytes, ConstValue, RawConst, Scalar, ScalarMaybeUninit}; diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 20577bdc6bd..d545cf6865d 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -1,4 +1,4 @@ -use super::{ConstEvalResult, ErrorHandled, GlobalId}; +use super::{ErrorHandled, EvalToConstValueResult, GlobalId}; use crate::mir; use crate::ty::subst::{InternalSubsts, SubstsRef}; @@ -10,7 +10,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Evaluates a constant without providing any substitutions. This is useful to evaluate consts /// that can't take any generic arguments like statics, const items or enum discriminants. If a /// generic parameter is used within the constant `ErrorHandled::ToGeneric` will be returned. - pub fn const_eval_poly(self, def_id: DefId) -> ConstEvalResult<'tcx> { + pub fn const_eval_poly(self, def_id: DefId) -> EvalToConstValueResult<'tcx> { // In some situations def_id will have substitutions within scope, but they aren't allowed // to be used. So we can't use `Instance::mono`, instead we feed unresolved substitutions // into `const_eval` which will return `ErrorHandled::ToGeneric` if any of them are @@ -38,7 +38,7 @@ impl<'tcx> TyCtxt<'tcx> { substs: SubstsRef<'tcx>, promoted: Option, span: Option, - ) -> ConstEvalResult<'tcx> { + ) -> EvalToConstValueResult<'tcx> { match ty::Instance::resolve_opt_const_arg(self, param_env, def, substs) { Ok(Some(instance)) => { let cid = GlobalId { instance, promoted }; @@ -54,7 +54,7 @@ impl<'tcx> TyCtxt<'tcx> { param_env: ty::ParamEnv<'tcx>, instance: ty::Instance<'tcx>, span: Option, - ) -> ConstEvalResult<'tcx> { + ) -> EvalToConstValueResult<'tcx> { self.const_eval_global_id(param_env, GlobalId { instance, promoted: None }, span) } @@ -64,14 +64,14 @@ impl<'tcx> TyCtxt<'tcx> { param_env: ty::ParamEnv<'tcx>, cid: GlobalId<'tcx>, span: Option, - ) -> ConstEvalResult<'tcx> { + ) -> EvalToConstValueResult<'tcx> { // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should // improve caching of queries. let inputs = self.erase_regions(¶m_env.and(cid)); if let Some(span) = span { - self.at(span).const_eval_for_ty(inputs) + self.at(span).eval_to_const_value(inputs) } else { - self.const_eval_for_ty(inputs) + self.eval_to_const_value(inputs) } } @@ -94,7 +94,7 @@ impl<'tcx> TyCtxt<'tcx> { param_env: ty::ParamEnv<'tcx>, ) -> Result<&'tcx mir::Allocation, ErrorHandled> { trace!("eval_to_allocation: Need to compute {:?}", gid); - let raw_const = self.const_eval(param_env.and(gid))?; + let raw_const = self.eval_to_allocation_raw(param_env.and(gid))?; Ok(self.global_alloc(raw_const.alloc_id).unwrap_memory()) } } diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index 7d6ff3eb5c1..930487153c3 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -12,7 +12,7 @@ use crate::ty::{ParamEnv, Ty, TyCtxt}; use super::{sign_extend, truncate, AllocId, Allocation, InterpResult, Pointer, PointerArithmetic}; -/// Represents the result of a raw const operation, pre-validation. +/// Represents the result of const evaluation via the `eval_to_allocation` query. #[derive(Clone, HashStable)] pub struct RawConst<'tcx> { // the value lives here, at offset 0, and that allocation definitely is a `AllocKind::Memory` diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index dc89cf35648..ece9dcf66a3 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -708,8 +708,10 @@ rustc_queries! { Other { /// Evaluates a constant and returns the computed allocation. - query const_eval(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) - -> ConstEvalRawResult<'tcx> { + /// + /// **Do not use this** directly, use the `tcx.eval_static_initializer` wrapper. + query eval_to_allocation_raw(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) + -> EvalToAllocationRawResult<'tcx> { desc { |tcx| "const-evaluating `{}`", key.value.display(tcx) @@ -722,8 +724,8 @@ rustc_queries! { /// /// **Do not use this** directly, use one of the following wrappers: `tcx.const_eval_poly`, /// `tcx.const_eval_resolve`, `tcx.const_eval_instance`, or `tcx.const_eval_global_id`. - query const_eval_for_ty(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) - -> ConstEvalResult<'tcx> { + query eval_to_const_value(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) + -> EvalToConstValueResult<'tcx> { desc { |tcx| "const-evaluating + checking `{}`", key.value.display(tcx) diff --git a/compiler/rustc_middle/src/ty/query/mod.rs b/compiler/rustc_middle/src/ty/query/mod.rs index ee9b203b151..d3a7412ef14 100644 --- a/compiler/rustc_middle/src/ty/query/mod.rs +++ b/compiler/rustc_middle/src/ty/query/mod.rs @@ -14,7 +14,7 @@ use crate::middle::resolve_lifetime::{ObjectLifetimeDefault, Region, ResolveLife use crate::middle::stability::{self, DeprecationEntry}; use crate::mir; use crate::mir::interpret::GlobalId; -use crate::mir::interpret::{ConstEvalRawResult, ConstEvalResult, ConstValue}; +use crate::mir::interpret::{ConstValue, EvalToAllocationRawResult, EvalToConstValueResult}; use crate::mir::interpret::{LitToConstError, LitToConstInput}; use crate::mir::mono::CodegenUnit; use crate::traits::query::{ diff --git a/compiler/rustc_mir/src/const_eval/eval_queries.rs b/compiler/rustc_mir/src/const_eval/eval_queries.rs index 3b01328df56..7dae12cf411 100644 --- a/compiler/rustc_mir/src/const_eval/eval_queries.rs +++ b/compiler/rustc_mir/src/const_eval/eval_queries.rs @@ -200,21 +200,21 @@ fn turn_into_const<'tcx>( ); assert!( !is_static || cid.promoted.is_some(), - "the `const_eval_for_ty` query should not be used for statics, use `const_eval` instead" + "the `eval_to_const_value` query should not be used for statics, use `eval_to_allocation` instead" ); // Turn this into a proper constant. op_to_const(&ecx, mplace.into()) } -pub fn const_eval_for_ty_provider<'tcx>( +pub fn eval_to_const_value_provider<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, -) -> ::rustc_middle::mir::interpret::ConstEvalResult<'tcx> { - // see comment in const_eval_provider for what we're doing here +) -> ::rustc_middle::mir::interpret::EvalToConstValueResult<'tcx> { + // see comment in const_eval_raw_provider for what we're doing here if key.param_env.reveal() == Reveal::All { let mut key = key; key.param_env = key.param_env.with_user_facing(); - match tcx.const_eval_for_ty(key) { + match tcx.eval_to_const_value(key) { // try again with reveal all as requested Err(ErrorHandled::TooGeneric) => {} // deduplicate calls @@ -237,13 +237,13 @@ pub fn const_eval_for_ty_provider<'tcx>( }); } - tcx.const_eval(key).map(|val| turn_into_const(tcx, val, key)) + tcx.eval_to_allocation_raw(key).map(|val| turn_into_const(tcx, val, key)) } -pub fn const_eval_provider<'tcx>( +pub fn eval_to_allocation_raw_provider<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, -) -> ::rustc_middle::mir::interpret::ConstEvalRawResult<'tcx> { +) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> { // Because the constant is computed twice (once per value of `Reveal`), we are at risk of // reporting the same error twice here. To resolve this, we check whether we can evaluate the // constant in the more restrictive `Reveal::UserFacing`, which most likely already was @@ -255,7 +255,7 @@ pub fn const_eval_provider<'tcx>( if key.param_env.reveal() == Reveal::All { let mut key = key; key.param_env = key.param_env.with_user_facing(); - match tcx.const_eval(key) { + match tcx.eval_to_allocation_raw(key) { // try again with reveal all as requested Err(ErrorHandled::TooGeneric) => {} // deduplicate calls diff --git a/compiler/rustc_mir/src/const_eval/machine.rs b/compiler/rustc_mir/src/const_eval/machine.rs index 8b0e993f02d..73ca7e0d471 100644 --- a/compiler/rustc_mir/src/const_eval/machine.rs +++ b/compiler/rustc_mir/src/const_eval/machine.rs @@ -51,7 +51,7 @@ impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> { let gid = GlobalId { instance, promoted: None }; - let place = self.const_eval(gid)?; + let place = self.eval_to_allocation(gid)?; self.copy_op(place.into(), dest)?; diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index ef05d136da1..00d6ffb14ea 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -875,7 +875,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(()) } - pub fn const_eval( + pub fn eval_to_allocation( &self, gid: GlobalId<'tcx>, ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { @@ -889,7 +889,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } else { self.param_env }; - let val = self.tcx.const_eval(param_env.and(gid))?; + let val = self.tcx.eval_to_allocation_raw(param_env.and(gid))?; self.raw_const_to_mplace(val) } diff --git a/compiler/rustc_mir/src/interpret/operand.rs b/compiler/rustc_mir/src/interpret/operand.rs index 54c43b518fd..8c4bb19866e 100644 --- a/compiler/rustc_mir/src/interpret/operand.rs +++ b/compiler/rustc_mir/src/interpret/operand.rs @@ -553,7 +553,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ty::ConstKind::Error(_) => throw_inval!(TypeckError(ErrorReported)), ty::ConstKind::Unevaluated(def, substs, promoted) => { let instance = self.resolve(def.did, substs)?; - return Ok(self.const_eval(GlobalId { instance, promoted })?.into()); + return Ok(self.eval_to_allocation(GlobalId { instance, promoted })?.into()); } ty::ConstKind::Infer(..) | ty::ConstKind::Bound(..) diff --git a/compiler/rustc_mir/src/lib.rs b/compiler/rustc_mir/src/lib.rs index 07defa2d66d..bbbb25117c0 100644 --- a/compiler/rustc_mir/src/lib.rs +++ b/compiler/rustc_mir/src/lib.rs @@ -52,8 +52,8 @@ pub fn provide(providers: &mut Providers) { transform::provide(providers); monomorphize::partitioning::provide(providers); monomorphize::polymorphize::provide(providers); - providers.const_eval_for_ty = const_eval::const_eval_for_ty_provider; - providers.const_eval = const_eval::const_eval_provider; + providers.eval_to_const_value = const_eval::eval_to_const_value_provider; + providers.eval_to_allocation_raw = const_eval::eval_to_allocation_raw_provider; providers.const_caller_location = const_eval::const_caller_location; providers.destructure_const = |tcx, param_env_and_value| { let (param_env, value) = param_env_and_value.into_parts(); From 90708c15c45572842f2abd60ce32c672d80bdbf8 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 21 Aug 2020 10:33:28 +0200 Subject: [PATCH 12/18] Fix rebase fallout and make the test work with debug info --- src/test/ui/consts/const-eval/const-eval-query-stack.stderr | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr index dc2661ee796..672076f0aff 100644 --- a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr +++ b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr @@ -9,9 +9,9 @@ LL | let x: &'static i32 = &(1 / 0); = note: `#[deny(const_err)]` on by default query stack during panic: -#0 [const_eval_raw] const-evaluating `main::promoted[1]` -#1 [const_eval_validated] const-evaluating + checking `main::promoted[1]` -#2 [const_eval_validated] const-evaluating + checking `main::promoted[1]` +#0 [eval_to_allocation_raw] const-evaluating `main::promoted[1]` +#1 [eval_to_const_value] const-evaluating + checking `main::promoted[1]` +#2 [eval_to_const_value] const-evaluating + checking `main::promoted[1]` #3 [normalize_generic_arg_after_erasing_regions] normalizing `main::promoted[1]` #4 [optimized_mir] optimizing MIR for `main` #5 [collect_and_partition_mono_items] collect_and_partition_mono_items From 182ed8544d2f2ecd4690535a7fcdb809d72e4a86 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 7 Sep 2020 17:30:38 +0200 Subject: [PATCH 13/18] Address review comments --- .../rustc_middle/src/mir/interpret/error.rs | 4 +-- .../rustc_middle/src/mir/interpret/mod.rs | 2 +- .../rustc_middle/src/mir/interpret/value.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 4 +-- .../rustc_mir/src/const_eval/eval_queries.rs | 10 +++--- compiler/rustc_mir/src/interpret/memory.rs | 2 +- compiler/rustc_mir/src/interpret/place.rs | 8 ++--- compiler/rustc_mir/src/interpret/validity.rs | 34 +++++++++---------- .../defaults-cyclic-fail.stderr | 26 +++++++------- ...9-assoc-const-static-recursion-impl.stderr | 26 +++++++------- ...onst-static-recursion-trait-default.stderr | 26 +++++++------- ...-assoc-const-static-recursion-trait.stderr | 26 +++++++------- .../const-eval/const-eval-query-stack.stderr | 6 ++-- src/test/ui/consts/const-size_of-cycle.stderr | 18 +++++----- .../recursive-zst-static.default.stderr | 6 ++-- src/test/ui/consts/recursive-zst-static.rs | 2 +- .../recursive-zst-static.unleash.stderr | 6 ++-- .../infinite/infinite-recursion-const-fn.rs | 11 ++++-- .../infinite-recursion-const-fn.stderr | 16 ++++----- src/test/ui/issues/issue-17252.stderr | 14 ++++---- src/test/ui/issues/issue-23302-1.stderr | 14 ++++---- src/test/ui/issues/issue-23302-2.stderr | 14 ++++---- src/test/ui/issues/issue-23302-3.stderr | 26 +++++++------- src/test/ui/issues/issue-36163.stderr | 26 +++++++------- .../recursion/recursive-static-definition.rs | 2 +- .../recursive-static-definition.stderr | 6 ++-- .../self-in-enum-definition.rs | 4 +-- .../self-in-enum-definition.stderr | 16 ++++----- .../ui/write-to-static-mut-in-static.stderr | 6 ++-- 29 files changed, 184 insertions(+), 179 deletions(-) diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 62d02250fe0..13333dc45de 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -1,4 +1,4 @@ -use super::{AllocId, Pointer, RawConst, Scalar}; +use super::{AllocId, ConstAlloc, Pointer, Scalar}; use crate::mir::interpret::ConstValue; use crate::ty::{layout, query::TyCtxtAt, tls, FnSig, Ty}; @@ -27,7 +27,7 @@ CloneTypeFoldableAndLiftImpls! { ErrorHandled, } -pub type EvalToAllocationRawResult<'tcx> = Result, ErrorHandled>; +pub type EvalToAllocationRawResult<'tcx> = Result, ErrorHandled>; pub type EvalToConstValueResult<'tcx> = Result, ErrorHandled>; pub fn struct_error<'tcx>(tcx: TyCtxtAt<'tcx>, msg: &str) -> DiagnosticBuilder<'tcx> { diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 71a99cf95f8..adf551ee433 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -123,7 +123,7 @@ pub use self::error::{ ResourceExhaustionInfo, UndefinedBehaviorInfo, UninitBytesAccess, UnsupportedOpInfo, }; -pub use self::value::{get_slice_bytes, ConstValue, RawConst, Scalar, ScalarMaybeUninit}; +pub use self::value::{get_slice_bytes, ConstAlloc, ConstValue, Scalar, ScalarMaybeUninit}; pub use self::allocation::{Allocation, AllocationExtra, InitMask, Relocations}; diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index 930487153c3..ded1a9c6276 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -14,7 +14,7 @@ use super::{sign_extend, truncate, AllocId, Allocation, InterpResult, Pointer, P /// Represents the result of const evaluation via the `eval_to_allocation` query. #[derive(Clone, HashStable)] -pub struct RawConst<'tcx> { +pub struct ConstAlloc<'tcx> { // the value lives here, at offset 0, and that allocation definitely is a `AllocKind::Memory` // (so you can use `AllocMap::unwrap_memory`). pub alloc_id: AllocId, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index ece9dcf66a3..dbc0e73968b 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -713,7 +713,7 @@ rustc_queries! { query eval_to_allocation_raw(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> EvalToAllocationRawResult<'tcx> { desc { |tcx| - "const-evaluating `{}`", + "const-evaluating + checking `{}`", key.value.display(tcx) } } @@ -727,7 +727,7 @@ rustc_queries! { query eval_to_const_value(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> EvalToConstValueResult<'tcx> { desc { |tcx| - "const-evaluating + checking `{}`", + "simplifying constant for the type system `{}`", key.value.display(tcx) } cache_on_disk_if(_, opt_result) { diff --git a/compiler/rustc_mir/src/const_eval/eval_queries.rs b/compiler/rustc_mir/src/const_eval/eval_queries.rs index 7dae12cf411..00b675dbc4a 100644 --- a/compiler/rustc_mir/src/const_eval/eval_queries.rs +++ b/compiler/rustc_mir/src/const_eval/eval_queries.rs @@ -2,7 +2,7 @@ use super::{CompileTimeEvalContext, CompileTimeInterpreter, ConstEvalErr, Memory use crate::interpret::eval_nullary_intrinsic; use crate::interpret::{ intern_const_alloc_recursive, Allocation, ConstValue, GlobalId, Immediate, InternKind, - InterpCx, InterpResult, MPlaceTy, MemoryKind, OpTy, RawConst, RefTracking, Scalar, + InterpCx, InterpResult, MPlaceTy, MemoryKind, OpTy, ConstAlloc, RefTracking, Scalar, ScalarMaybeUninit, StackPopCleanup, }; @@ -184,9 +184,9 @@ pub(super) fn op_to_const<'tcx>( } } -fn turn_into_const<'tcx>( +fn turn_into_const_value<'tcx>( tcx: TyCtxt<'tcx>, - constant: RawConst<'tcx>, + constant: ConstAlloc<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, ) -> ConstValue<'tcx> { let cid = key.value; @@ -237,7 +237,7 @@ pub fn eval_to_const_value_provider<'tcx>( }); } - tcx.eval_to_allocation_raw(key).map(|val| turn_into_const(tcx, val, key)) + tcx.eval_to_allocation_raw(key).map(|val| turn_into_const_value(tcx, val, key)) } pub fn eval_to_allocation_raw_provider<'tcx>( @@ -402,7 +402,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>( )) } else { // Convert to raw constant - Ok(RawConst { alloc_id: mplace.ptr.assert_ptr().alloc_id, ty: mplace.layout.ty }) + Ok(ConstAlloc { alloc_id: mplace.ptr.assert_ptr().alloc_id, ty: mplace.layout.ty }) } } } diff --git a/compiler/rustc_mir/src/interpret/memory.rs b/compiler/rustc_mir/src/interpret/memory.rs index 64918a76857..86e242c67d5 100644 --- a/compiler/rustc_mir/src/interpret/memory.rs +++ b/compiler/rustc_mir/src/interpret/memory.rs @@ -469,7 +469,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // Notice that every static has two `AllocId` that will resolve to the same // thing here: one maps to `GlobalAlloc::Static`, this is the "lazy" ID, // and the other one is maps to `GlobalAlloc::Memory`, this is returned by - // `const_eval` and it is the "resolved" ID. + // `eval_static_initializer` and it is the "resolved" ID. // The resolved ID is never used by the interpreted program, it is hidden. // This is relied upon for soundness of const-patterns; a pointer to the resolved // ID would "sidestep" the checks that make sure consts do not point to statics! diff --git a/compiler/rustc_mir/src/interpret/place.rs b/compiler/rustc_mir/src/interpret/place.rs index 9e16063bd21..055141a3de6 100644 --- a/compiler/rustc_mir/src/interpret/place.rs +++ b/compiler/rustc_mir/src/interpret/place.rs @@ -13,9 +13,9 @@ use rustc_target::abi::{Abi, Align, FieldsShape, TagEncoding}; use rustc_target::abi::{HasDataLayout, LayoutOf, Size, VariantIdx, Variants}; use super::{ - mir_assign_valid_types, truncate, AllocId, AllocMap, Allocation, AllocationExtra, ImmTy, - Immediate, InterpCx, InterpResult, LocalValue, Machine, MemoryKind, OpTy, Operand, Pointer, - PointerArithmetic, RawConst, Scalar, ScalarMaybeUninit, + mir_assign_valid_types, truncate, AllocId, AllocMap, Allocation, AllocationExtra, ConstAlloc, + ImmTy, Immediate, InterpCx, InterpResult, LocalValue, Machine, MemoryKind, OpTy, Operand, + Pointer, PointerArithmetic, Scalar, ScalarMaybeUninit, }; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)] @@ -1122,7 +1122,7 @@ where pub fn raw_const_to_mplace( &self, - raw: RawConst<'tcx>, + raw: ConstAlloc<'tcx>, ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { // This must be an allocation in `tcx` let _ = self.tcx.global_alloc(raw.alloc_id); diff --git a/compiler/rustc_mir/src/interpret/validity.rs b/compiler/rustc_mir/src/interpret/validity.rs index 7d9507c08fa..2b83e1c8134 100644 --- a/compiler/rustc_mir/src/interpret/validity.rs +++ b/compiler/rustc_mir/src/interpret/validity.rs @@ -426,27 +426,27 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' if let Some(GlobalAlloc::Static(did)) = alloc_kind { assert!(!self.ecx.tcx.is_thread_local_static(did)); assert!(self.ecx.tcx.is_static(did)); - // See const_eval::machine::MemoryExtra::can_access_statics for why - // this check is so important. - // This check is reachable when the const just referenced the static, - // but never read it (so we never entered `before_access_global`). - // We also need to do it here instead of going on to avoid running - // into the `before_access_global` check during validation. - if !self.may_ref_to_static { + if self.may_ref_to_static { + // We skip checking other statics. These statics must be sound by + // themselves, and the only way to get broken statics here is by using + // unsafe code. + // The reasons we don't check other statics is twofold. For one, in all + // sound cases, the static was already validated on its own, and second, we + // trigger cycle errors if we try to compute the value of the other static + // and that static refers back to us. + // We might miss const-invalid data, + // but things are still sound otherwise (in particular re: consts + // referring to statics). + return Ok(()); + } else { + // See const_eval::machine::MemoryExtra::can_access_statics for why + // this check is so important. + // This check is reachable when the const just referenced the static, + // but never read it (so we never entered `before_access_global`). throw_validation_failure!(self.path, { "a {} pointing to a static variable", kind } ); } - // We skip checking other statics. These statics must be sound by themselves, - // and the only way to get broken statics here is by using unsafe code. - // The reasons we don't check other statics is twofold. For one, in all sound - // cases, the static was already validated on its own, and second, we trigger - // cycle errors if we try to compute the value of the other static and that - // static refers back to us. - // We might miss const-invalid data, - // but things are still sound otherwise (in particular re: consts - // referring to statics). - return Ok(()); } } // Proceed recursively even for ZST, no reason to skip them! diff --git a/src/test/ui/associated-const/defaults-cyclic-fail.stderr b/src/test/ui/associated-const/defaults-cyclic-fail.stderr index e6075f74577..616ac9053fd 100644 --- a/src/test/ui/associated-const/defaults-cyclic-fail.stderr +++ b/src/test/ui/associated-const/defaults-cyclic-fail.stderr @@ -1,6 +1,11 @@ error[E0391]: cycle detected when normalizing `<() as Tr>::A` | -note: ...which requires const-evaluating + checking `Tr::A`... +note: ...which requires simplifying constant for the type system `Tr::A`... + --> $DIR/defaults-cyclic-fail.rs:6:5 + | +LL | const A: u8 = Self::B; + | ^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires simplifying constant for the type system `Tr::A`... --> $DIR/defaults-cyclic-fail.rs:6:5 | LL | const A: u8 = Self::B; @@ -8,15 +13,15 @@ LL | const A: u8 = Self::B; note: ...which requires const-evaluating + checking `Tr::A`... --> $DIR/defaults-cyclic-fail.rs:6:5 | -LL | const A: u8 = Self::B; - | ^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires const-evaluating `Tr::A`... - --> $DIR/defaults-cyclic-fail.rs:6:5 - | LL | const A: u8 = Self::B; | ^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires normalizing `<() as Tr>::B`... -note: ...which requires const-evaluating + checking `Tr::B`... +note: ...which requires simplifying constant for the type system `Tr::B`... + --> $DIR/defaults-cyclic-fail.rs:8:5 + | +LL | const B: u8 = Self::A; + | ^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires simplifying constant for the type system `Tr::B`... --> $DIR/defaults-cyclic-fail.rs:8:5 | LL | const B: u8 = Self::A; @@ -24,15 +29,10 @@ LL | const B: u8 = Self::A; note: ...which requires const-evaluating + checking `Tr::B`... --> $DIR/defaults-cyclic-fail.rs:8:5 | -LL | const B: u8 = Self::A; - | ^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires const-evaluating `Tr::B`... - --> $DIR/defaults-cyclic-fail.rs:8:5 - | LL | const B: u8 = Self::A; | ^^^^^^^^^^^^^^^^^^^^^^ = note: ...which again requires normalizing `<() as Tr>::A`, completing the cycle -note: cycle used when const-evaluating `main::promoted[2]` +note: cycle used when const-evaluating + checking `main::promoted[2]` --> $DIR/defaults-cyclic-fail.rs:14:1 | LL | fn main() { diff --git a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr index 1b4326ea56a..d9bb7386565 100644 --- a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr +++ b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr @@ -1,21 +1,26 @@ -error[E0391]: cycle detected when const-evaluating + checking `IMPL_REF_BAR` +error[E0391]: cycle detected when simplifying constant for the type system `IMPL_REF_BAR` --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1 | LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | +note: ...which requires simplifying constant for the type system `IMPL_REF_BAR`... + --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1 + | +LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `IMPL_REF_BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1 | -LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires const-evaluating `IMPL_REF_BAR`... - --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1 - | LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires normalizing `::BAR`... -note: ...which requires const-evaluating + checking `::BAR`... +note: ...which requires simplifying constant for the type system `::BAR`... + --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5 + | +LL | const BAR: u32 = IMPL_REF_BAR; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires simplifying constant for the type system `::BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5 | LL | const BAR: u32 = IMPL_REF_BAR; @@ -25,18 +30,13 @@ note: ...which requires const-evaluating + checking `::BAR`... - --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5 - | -LL | const BAR: u32 = IMPL_REF_BAR; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires optimizing MIR for `::BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5 | LL | const BAR: u32 = IMPL_REF_BAR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires normalizing `IMPL_REF_BAR`... - = note: ...which again requires const-evaluating + checking `IMPL_REF_BAR`, completing the cycle + = note: ...which again requires simplifying constant for the type system `IMPL_REF_BAR`, completing the cycle = note: cycle used when running analysis passes on this crate error: aborting due to previous error diff --git a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr index 8efa56a9a2e..d000d8ac097 100644 --- a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr +++ b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr @@ -1,21 +1,26 @@ -error[E0391]: cycle detected when const-evaluating + checking `DEFAULT_REF_BAR` +error[E0391]: cycle detected when simplifying constant for the type system `DEFAULT_REF_BAR` --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:1 | LL | const DEFAULT_REF_BAR: u32 = ::BAR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | +note: ...which requires simplifying constant for the type system `DEFAULT_REF_BAR`... + --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:1 + | +LL | const DEFAULT_REF_BAR: u32 = ::BAR; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `DEFAULT_REF_BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:1 | -LL | const DEFAULT_REF_BAR: u32 = ::BAR; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires const-evaluating `DEFAULT_REF_BAR`... - --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:1 - | LL | const DEFAULT_REF_BAR: u32 = ::BAR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires normalizing `::BAR`... -note: ...which requires const-evaluating + checking `FooDefault::BAR`... +note: ...which requires simplifying constant for the type system `FooDefault::BAR`... + --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5 + | +LL | const BAR: u32 = DEFAULT_REF_BAR; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires simplifying constant for the type system `FooDefault::BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5 | LL | const BAR: u32 = DEFAULT_REF_BAR; @@ -25,18 +30,13 @@ note: ...which requires const-evaluating + checking `FooDefault::BAR`... | LL | const BAR: u32 = DEFAULT_REF_BAR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires const-evaluating `FooDefault::BAR`... - --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5 - | -LL | const BAR: u32 = DEFAULT_REF_BAR; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires optimizing MIR for `FooDefault::BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5 | LL | const BAR: u32 = DEFAULT_REF_BAR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires normalizing `DEFAULT_REF_BAR`... - = note: ...which again requires const-evaluating + checking `DEFAULT_REF_BAR`, completing the cycle + = note: ...which again requires simplifying constant for the type system `DEFAULT_REF_BAR`, completing the cycle = note: cycle used when running analysis passes on this crate error: aborting due to previous error diff --git a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr index 78ce1a28a3f..62d2051b6c2 100644 --- a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr +++ b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr @@ -1,21 +1,26 @@ -error[E0391]: cycle detected when const-evaluating + checking `TRAIT_REF_BAR` +error[E0391]: cycle detected when simplifying constant for the type system `TRAIT_REF_BAR` --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1 | LL | const TRAIT_REF_BAR: u32 = ::BAR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | +note: ...which requires simplifying constant for the type system `TRAIT_REF_BAR`... + --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1 + | +LL | const TRAIT_REF_BAR: u32 = ::BAR; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `TRAIT_REF_BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1 | -LL | const TRAIT_REF_BAR: u32 = ::BAR; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires const-evaluating `TRAIT_REF_BAR`... - --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1 - | LL | const TRAIT_REF_BAR: u32 = ::BAR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires normalizing `::BAR`... -note: ...which requires const-evaluating + checking `::BAR`... +note: ...which requires simplifying constant for the type system `::BAR`... + --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5 + | +LL | const BAR: u32 = TRAIT_REF_BAR; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires simplifying constant for the type system `::BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5 | LL | const BAR: u32 = TRAIT_REF_BAR; @@ -25,18 +30,13 @@ note: ...which requires const-evaluating + checking `::BAR`... - --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5 - | -LL | const BAR: u32 = TRAIT_REF_BAR; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires optimizing MIR for `::BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5 | LL | const BAR: u32 = TRAIT_REF_BAR; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires normalizing `TRAIT_REF_BAR`... - = note: ...which again requires const-evaluating + checking `TRAIT_REF_BAR`, completing the cycle + = note: ...which again requires simplifying constant for the type system `TRAIT_REF_BAR`, completing the cycle = note: cycle used when running analysis passes on this crate error: aborting due to previous error diff --git a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr index 672076f0aff..26d396a1819 100644 --- a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr +++ b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr @@ -9,9 +9,9 @@ LL | let x: &'static i32 = &(1 / 0); = note: `#[deny(const_err)]` on by default query stack during panic: -#0 [eval_to_allocation_raw] const-evaluating `main::promoted[1]` -#1 [eval_to_const_value] const-evaluating + checking `main::promoted[1]` -#2 [eval_to_const_value] const-evaluating + checking `main::promoted[1]` +#0 [eval_to_allocation_raw] const-evaluating + checking `main::promoted[1]` +#1 [eval_to_const_value] simplifying constant for the type system `main::promoted[1]` +#2 [eval_to_const_value] simplifying constant for the type system `main::promoted[1]` #3 [normalize_generic_arg_after_erasing_regions] normalizing `main::promoted[1]` #4 [optimized_mir] optimizing MIR for `main` #5 [collect_and_partition_mono_items] collect_and_partition_mono_items diff --git a/src/test/ui/consts/const-size_of-cycle.stderr b/src/test/ui/consts/const-size_of-cycle.stderr index f4bff31c995..58d5e9ac58c 100644 --- a/src/test/ui/consts/const-size_of-cycle.stderr +++ b/src/test/ui/consts/const-size_of-cycle.stderr @@ -1,32 +1,32 @@ -error[E0391]: cycle detected when const-evaluating + checking `Foo::bytes::{{constant}}#0` +error[E0391]: cycle detected when simplifying constant for the type system `Foo::bytes::{{constant}}#0` --> $DIR/const-size_of-cycle.rs:4:17 | LL | bytes: [u8; std::mem::size_of::()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | +note: ...which requires simplifying constant for the type system `Foo::bytes::{{constant}}#0`... + --> $DIR/const-size_of-cycle.rs:4:17 + | +LL | bytes: [u8; std::mem::size_of::()] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}#0`... --> $DIR/const-size_of-cycle.rs:4:17 | LL | bytes: [u8; std::mem::size_of::()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires const-evaluating `Foo::bytes::{{constant}}#0`... - --> $DIR/const-size_of-cycle.rs:4:17 - | -LL | bytes: [u8; std::mem::size_of::()] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires const-evaluating `std::mem::size_of`... +note: ...which requires const-evaluating + checking `std::mem::size_of`... --> $SRC_DIR/core/src/mem/mod.rs:LL:COL | LL | pub const fn size_of() -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires const-evaluating + checking `std::intrinsics::size_of`... +note: ...which requires simplifying constant for the type system `std::intrinsics::size_of`... --> $SRC_DIR/core/src/intrinsics.rs:LL:COL | LL | pub fn size_of() -> usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires computing layout of `Foo`... = note: ...which requires normalizing `[u8; _]`... - = note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}#0`, completing the cycle + = note: ...which again requires simplifying constant for the type system `Foo::bytes::{{constant}}#0`, completing the cycle note: cycle used when checking that `Foo` is well-formed --> $DIR/const-size_of-cycle.rs:3:1 | diff --git a/src/test/ui/consts/recursive-zst-static.default.stderr b/src/test/ui/consts/recursive-zst-static.default.stderr index d58f044cf6d..03f8f5c5a0e 100644 --- a/src/test/ui/consts/recursive-zst-static.default.stderr +++ b/src/test/ui/consts/recursive-zst-static.default.stderr @@ -1,15 +1,15 @@ -error[E0391]: cycle detected when const-evaluating `FOO` +error[E0391]: cycle detected when const-evaluating + checking `FOO` --> $DIR/recursive-zst-static.rs:10:1 | LL | static FOO: () = FOO; | ^^^^^^^^^^^^^^^^^^^^^ | -note: ...which requires const-evaluating `FOO`... +note: ...which requires const-evaluating + checking `FOO`... --> $DIR/recursive-zst-static.rs:10:1 | LL | static FOO: () = FOO; | ^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires const-evaluating `FOO`, completing the cycle + = note: ...which again requires const-evaluating + checking `FOO`, completing the cycle = note: cycle used when running analysis passes on this crate error: aborting due to previous error diff --git a/src/test/ui/consts/recursive-zst-static.rs b/src/test/ui/consts/recursive-zst-static.rs index 29a467c006a..4e61634b349 100644 --- a/src/test/ui/consts/recursive-zst-static.rs +++ b/src/test/ui/consts/recursive-zst-static.rs @@ -7,7 +7,7 @@ // can depend on this fact and will thus do unsound things when it is violated. // See https://github.com/rust-lang/rust/issues/71078 for more details. -static FOO: () = FOO; //~ cycle detected when const-evaluating `FOO` +static FOO: () = FOO; //~ cycle detected when const-evaluating + checking `FOO` fn main() { FOO diff --git a/src/test/ui/consts/recursive-zst-static.unleash.stderr b/src/test/ui/consts/recursive-zst-static.unleash.stderr index d58f044cf6d..03f8f5c5a0e 100644 --- a/src/test/ui/consts/recursive-zst-static.unleash.stderr +++ b/src/test/ui/consts/recursive-zst-static.unleash.stderr @@ -1,15 +1,15 @@ -error[E0391]: cycle detected when const-evaluating `FOO` +error[E0391]: cycle detected when const-evaluating + checking `FOO` --> $DIR/recursive-zst-static.rs:10:1 | LL | static FOO: () = FOO; | ^^^^^^^^^^^^^^^^^^^^^ | -note: ...which requires const-evaluating `FOO`... +note: ...which requires const-evaluating + checking `FOO`... --> $DIR/recursive-zst-static.rs:10:1 | LL | static FOO: () = FOO; | ^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires const-evaluating `FOO`, completing the cycle + = note: ...which again requires const-evaluating + checking `FOO`, completing the cycle = note: cycle used when running analysis passes on this crate error: aborting due to previous error diff --git a/src/test/ui/infinite/infinite-recursion-const-fn.rs b/src/test/ui/infinite/infinite-recursion-const-fn.rs index 8289a3db6fc..34580407926 100644 --- a/src/test/ui/infinite/infinite-recursion-const-fn.rs +++ b/src/test/ui/infinite/infinite-recursion-const-fn.rs @@ -1,7 +1,12 @@ //https://github.com/rust-lang/rust/issues/31364 -const fn a() -> usize { b() } //~ ERROR cycle detected when const-evaluating `a` [E0391] -const fn b() -> usize { a() } +const fn a() -> usize { + //~^ ERROR cycle detected when const-evaluating + checking `a` [E0391] + b() +} +const fn b() -> usize { + a() +} const ARR: [i32; a()] = [5; 6]; -fn main(){} +fn main() {} diff --git a/src/test/ui/infinite/infinite-recursion-const-fn.stderr b/src/test/ui/infinite/infinite-recursion-const-fn.stderr index de0c579f630..3c106895305 100644 --- a/src/test/ui/infinite/infinite-recursion-const-fn.stderr +++ b/src/test/ui/infinite/infinite-recursion-const-fn.stderr @@ -1,17 +1,17 @@ -error[E0391]: cycle detected when const-evaluating `a` +error[E0391]: cycle detected when const-evaluating + checking `a` --> $DIR/infinite-recursion-const-fn.rs:3:1 | -LL | const fn a() -> usize { b() } +LL | const fn a() -> usize { | ^^^^^^^^^^^^^^^^^^^^^ | -note: ...which requires const-evaluating `b`... - --> $DIR/infinite-recursion-const-fn.rs:4:1 +note: ...which requires const-evaluating + checking `b`... + --> $DIR/infinite-recursion-const-fn.rs:7:1 | -LL | const fn b() -> usize { a() } +LL | const fn b() -> usize { | ^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires const-evaluating `a`, completing the cycle -note: cycle used when const-evaluating `ARR::{{constant}}#0` - --> $DIR/infinite-recursion-const-fn.rs:5:18 + = note: ...which again requires const-evaluating + checking `a`, completing the cycle +note: cycle used when const-evaluating + checking `ARR::{{constant}}#0` + --> $DIR/infinite-recursion-const-fn.rs:10:18 | LL | const ARR: [i32; a()] = [5; 6]; | ^^^ diff --git a/src/test/ui/issues/issue-17252.stderr b/src/test/ui/issues/issue-17252.stderr index ee621a8cb14..0a27848b801 100644 --- a/src/test/ui/issues/issue-17252.stderr +++ b/src/test/ui/issues/issue-17252.stderr @@ -1,6 +1,11 @@ error[E0391]: cycle detected when normalizing `FOO` | -note: ...which requires const-evaluating + checking `FOO`... +note: ...which requires simplifying constant for the type system `FOO`... + --> $DIR/issue-17252.rs:1:1 + | +LL | const FOO: usize = FOO; + | ^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires simplifying constant for the type system `FOO`... --> $DIR/issue-17252.rs:1:1 | LL | const FOO: usize = FOO; @@ -8,15 +13,10 @@ LL | const FOO: usize = FOO; note: ...which requires const-evaluating + checking `FOO`... --> $DIR/issue-17252.rs:1:1 | -LL | const FOO: usize = FOO; - | ^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires const-evaluating `FOO`... - --> $DIR/issue-17252.rs:1:1 - | LL | const FOO: usize = FOO; | ^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which again requires normalizing `FOO`, completing the cycle -note: cycle used when const-evaluating `main::{{constant}}#0` +note: cycle used when const-evaluating + checking `main::{{constant}}#0` --> $DIR/issue-17252.rs:4:18 | LL | let _x: [u8; FOO]; // caused stack overflow prior to fix diff --git a/src/test/ui/issues/issue-23302-1.stderr b/src/test/ui/issues/issue-23302-1.stderr index b6c85b9e227..45372c7f53b 100644 --- a/src/test/ui/issues/issue-23302-1.stderr +++ b/src/test/ui/issues/issue-23302-1.stderr @@ -1,21 +1,21 @@ -error[E0391]: cycle detected when const-evaluating + checking `X::A::{{constant}}#0` +error[E0391]: cycle detected when simplifying constant for the type system `X::A::{{constant}}#0` --> $DIR/issue-23302-1.rs:4:9 | LL | A = X::A as isize, | ^^^^^^^^^^^^^ | +note: ...which requires simplifying constant for the type system `X::A::{{constant}}#0`... + --> $DIR/issue-23302-1.rs:4:9 + | +LL | A = X::A as isize, + | ^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `X::A::{{constant}}#0`... --> $DIR/issue-23302-1.rs:4:9 | -LL | A = X::A as isize, - | ^^^^^^^^^^^^^ -note: ...which requires const-evaluating `X::A::{{constant}}#0`... - --> $DIR/issue-23302-1.rs:4:9 - | LL | A = X::A as isize, | ^^^^^^^^^^^^^ = note: ...which requires normalizing `X::A as isize`... - = note: ...which again requires const-evaluating + checking `X::A::{{constant}}#0`, completing the cycle + = note: ...which again requires simplifying constant for the type system `X::A::{{constant}}#0`, completing the cycle note: cycle used when collecting item types in top-level module --> $DIR/issue-23302-1.rs:3:1 | diff --git a/src/test/ui/issues/issue-23302-2.stderr b/src/test/ui/issues/issue-23302-2.stderr index d014922fe20..33bc1f6c48d 100644 --- a/src/test/ui/issues/issue-23302-2.stderr +++ b/src/test/ui/issues/issue-23302-2.stderr @@ -1,21 +1,21 @@ -error[E0391]: cycle detected when const-evaluating + checking `Y::A::{{constant}}#0` +error[E0391]: cycle detected when simplifying constant for the type system `Y::A::{{constant}}#0` --> $DIR/issue-23302-2.rs:4:9 | LL | A = Y::B as isize, | ^^^^^^^^^^^^^ | +note: ...which requires simplifying constant for the type system `Y::A::{{constant}}#0`... + --> $DIR/issue-23302-2.rs:4:9 + | +LL | A = Y::B as isize, + | ^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `Y::A::{{constant}}#0`... --> $DIR/issue-23302-2.rs:4:9 | -LL | A = Y::B as isize, - | ^^^^^^^^^^^^^ -note: ...which requires const-evaluating `Y::A::{{constant}}#0`... - --> $DIR/issue-23302-2.rs:4:9 - | LL | A = Y::B as isize, | ^^^^^^^^^^^^^ = note: ...which requires normalizing `Y::B as isize`... - = note: ...which again requires const-evaluating + checking `Y::A::{{constant}}#0`, completing the cycle + = note: ...which again requires simplifying constant for the type system `Y::A::{{constant}}#0`, completing the cycle note: cycle used when collecting item types in top-level module --> $DIR/issue-23302-2.rs:3:1 | diff --git a/src/test/ui/issues/issue-23302-3.stderr b/src/test/ui/issues/issue-23302-3.stderr index b30b1214271..5233b832ecc 100644 --- a/src/test/ui/issues/issue-23302-3.stderr +++ b/src/test/ui/issues/issue-23302-3.stderr @@ -1,21 +1,26 @@ -error[E0391]: cycle detected when const-evaluating + checking `A` +error[E0391]: cycle detected when simplifying constant for the type system `A` --> $DIR/issue-23302-3.rs:1:1 | LL | const A: i32 = B; | ^^^^^^^^^^^^^^^^^ | +note: ...which requires simplifying constant for the type system `A`... + --> $DIR/issue-23302-3.rs:1:1 + | +LL | const A: i32 = B; + | ^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `A`... --> $DIR/issue-23302-3.rs:1:1 | -LL | const A: i32 = B; - | ^^^^^^^^^^^^^^^^^ -note: ...which requires const-evaluating `A`... - --> $DIR/issue-23302-3.rs:1:1 - | LL | const A: i32 = B; | ^^^^^^^^^^^^^^^^^ = note: ...which requires normalizing `B`... -note: ...which requires const-evaluating + checking `B`... +note: ...which requires simplifying constant for the type system `B`... + --> $DIR/issue-23302-3.rs:3:1 + | +LL | const B: i32 = A; + | ^^^^^^^^^^^^^^^^^ +note: ...which requires simplifying constant for the type system `B`... --> $DIR/issue-23302-3.rs:3:1 | LL | const B: i32 = A; @@ -23,15 +28,10 @@ LL | const B: i32 = A; note: ...which requires const-evaluating + checking `B`... --> $DIR/issue-23302-3.rs:3:1 | -LL | const B: i32 = A; - | ^^^^^^^^^^^^^^^^^ -note: ...which requires const-evaluating `B`... - --> $DIR/issue-23302-3.rs:3:1 - | LL | const B: i32 = A; | ^^^^^^^^^^^^^^^^^ = note: ...which requires normalizing `A`... - = note: ...which again requires const-evaluating + checking `A`, completing the cycle + = note: ...which again requires simplifying constant for the type system `A`, completing the cycle = note: cycle used when running analysis passes on this crate error: aborting due to previous error diff --git a/src/test/ui/issues/issue-36163.stderr b/src/test/ui/issues/issue-36163.stderr index 7c2da9dce6e..3fd1f4b59be 100644 --- a/src/test/ui/issues/issue-36163.stderr +++ b/src/test/ui/issues/issue-36163.stderr @@ -1,21 +1,26 @@ -error[E0391]: cycle detected when const-evaluating + checking `Foo::B::{{constant}}#0` +error[E0391]: cycle detected when simplifying constant for the type system `Foo::B::{{constant}}#0` --> $DIR/issue-36163.rs:4:9 | LL | B = A, | ^ | +note: ...which requires simplifying constant for the type system `Foo::B::{{constant}}#0`... + --> $DIR/issue-36163.rs:4:9 + | +LL | B = A, + | ^ note: ...which requires const-evaluating + checking `Foo::B::{{constant}}#0`... --> $DIR/issue-36163.rs:4:9 | -LL | B = A, - | ^ -note: ...which requires const-evaluating `Foo::B::{{constant}}#0`... - --> $DIR/issue-36163.rs:4:9 - | LL | B = A, | ^ = note: ...which requires normalizing `A`... -note: ...which requires const-evaluating + checking `A`... +note: ...which requires simplifying constant for the type system `A`... + --> $DIR/issue-36163.rs:1:1 + | +LL | const A: isize = Foo::B as isize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires simplifying constant for the type system `A`... --> $DIR/issue-36163.rs:1:1 | LL | const A: isize = Foo::B as isize; @@ -23,15 +28,10 @@ LL | const A: isize = Foo::B as isize; note: ...which requires const-evaluating + checking `A`... --> $DIR/issue-36163.rs:1:1 | -LL | const A: isize = Foo::B as isize; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires const-evaluating `A`... - --> $DIR/issue-36163.rs:1:1 - | LL | const A: isize = Foo::B as isize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires normalizing `A`... - = note: ...which again requires const-evaluating + checking `Foo::B::{{constant}}#0`, completing the cycle + = note: ...which again requires simplifying constant for the type system `Foo::B::{{constant}}#0`, completing the cycle note: cycle used when collecting item types in top-level module --> $DIR/issue-36163.rs:1:1 | diff --git a/src/test/ui/recursion/recursive-static-definition.rs b/src/test/ui/recursion/recursive-static-definition.rs index e816ce4e0c4..f59ef7316d8 100644 --- a/src/test/ui/recursion/recursive-static-definition.rs +++ b/src/test/ui/recursion/recursive-static-definition.rs @@ -1,4 +1,4 @@ pub static FOO: u32 = FOO; -//~^ ERROR cycle detected when const-evaluating `FOO` +//~^ ERROR cycle detected when const-evaluating + checking `FOO` fn main() {} diff --git a/src/test/ui/recursion/recursive-static-definition.stderr b/src/test/ui/recursion/recursive-static-definition.stderr index 97e42a1f126..ee73b026a0b 100644 --- a/src/test/ui/recursion/recursive-static-definition.stderr +++ b/src/test/ui/recursion/recursive-static-definition.stderr @@ -1,15 +1,15 @@ -error[E0391]: cycle detected when const-evaluating `FOO` +error[E0391]: cycle detected when const-evaluating + checking `FOO` --> $DIR/recursive-static-definition.rs:1:1 | LL | pub static FOO: u32 = FOO; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: ...which requires const-evaluating `FOO`... +note: ...which requires const-evaluating + checking `FOO`... --> $DIR/recursive-static-definition.rs:1:1 | LL | pub static FOO: u32 = FOO; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires const-evaluating `FOO`, completing the cycle + = note: ...which again requires const-evaluating + checking `FOO`, completing the cycle = note: cycle used when running analysis passes on this crate error: aborting due to previous error diff --git a/src/test/ui/type-alias-enum-variants/self-in-enum-definition.rs b/src/test/ui/type-alias-enum-variants/self-in-enum-definition.rs index 63b21faa62b..8dadd77fc16 100644 --- a/src/test/ui/type-alias-enum-variants/self-in-enum-definition.rs +++ b/src/test/ui/type-alias-enum-variants/self-in-enum-definition.rs @@ -1,8 +1,8 @@ #[repr(u8)] enum Alpha { V1 = 41, - V2 = Self::V1 as u8 + 1, // OK; See #50072. - V3 = Self::V1 {} as u8 + 2, //~ ERROR cycle detected when const-evaluating + V2 = Self::V1 as u8 + 1, // OK; See #50072. + V3 = Self::V1 {} as u8 + 2, //~ ERROR cycle detected when simplifying constant } fn main() {} diff --git a/src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr b/src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr index db535b53fcf..fbe6279ca92 100644 --- a/src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr +++ b/src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr @@ -1,28 +1,28 @@ -error[E0391]: cycle detected when const-evaluating + checking `Alpha::V3::{{constant}}#0` +error[E0391]: cycle detected when simplifying constant for the type system `Alpha::V3::{{constant}}#0` --> $DIR/self-in-enum-definition.rs:5:10 | LL | V3 = Self::V1 {} as u8 + 2, | ^^^^^^^^ | +note: ...which requires simplifying constant for the type system `Alpha::V3::{{constant}}#0`... + --> $DIR/self-in-enum-definition.rs:5:10 + | +LL | V3 = Self::V1 {} as u8 + 2, + | ^^^^^^^^ note: ...which requires const-evaluating + checking `Alpha::V3::{{constant}}#0`... --> $DIR/self-in-enum-definition.rs:5:10 | -LL | V3 = Self::V1 {} as u8 + 2, - | ^^^^^^^^ -note: ...which requires const-evaluating `Alpha::V3::{{constant}}#0`... - --> $DIR/self-in-enum-definition.rs:5:10 - | LL | V3 = Self::V1 {} as u8 + 2, | ^^^^^^^^ = note: ...which requires computing layout of `Alpha`... - = note: ...which again requires const-evaluating + checking `Alpha::V3::{{constant}}#0`, completing the cycle + = note: ...which again requires simplifying constant for the type system `Alpha::V3::{{constant}}#0`, completing the cycle note: cycle used when collecting item types in top-level module --> $DIR/self-in-enum-definition.rs:1:1 | LL | / #[repr(u8)] LL | | enum Alpha { LL | | V1 = 41, -LL | | V2 = Self::V1 as u8 + 1, // OK; See #50072. +LL | | V2 = Self::V1 as u8 + 1, // OK; See #50072. ... | LL | | LL | | fn main() {} diff --git a/src/test/ui/write-to-static-mut-in-static.stderr b/src/test/ui/write-to-static-mut-in-static.stderr index 6f21539c119..789919bd166 100644 --- a/src/test/ui/write-to-static-mut-in-static.stderr +++ b/src/test/ui/write-to-static-mut-in-static.stderr @@ -4,18 +4,18 @@ error[E0080]: could not evaluate static initializer LL | pub static mut B: () = unsafe { A = 1; }; | ^^^^^ modifying a static's initial value from another static's initializer -error[E0391]: cycle detected when const-evaluating `C` +error[E0391]: cycle detected when const-evaluating + checking `C` --> $DIR/write-to-static-mut-in-static.rs:5:1 | LL | pub static mut C: u32 = unsafe { C = 1; 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: ...which requires const-evaluating `C`... +note: ...which requires const-evaluating + checking `C`... --> $DIR/write-to-static-mut-in-static.rs:5:1 | LL | pub static mut C: u32 = unsafe { C = 1; 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires const-evaluating `C`, completing the cycle + = note: ...which again requires const-evaluating + checking `C`, completing the cycle = note: cycle used when running analysis passes on this crate error: aborting due to 2 previous errors From c3c8c981a859d6190adeec0dc32b2765bace1b3d Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 9 Sep 2020 11:40:09 +0200 Subject: [PATCH 14/18] Rustfmt --- compiler/rustc_mir/src/const_eval/eval_queries.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir/src/const_eval/eval_queries.rs b/compiler/rustc_mir/src/const_eval/eval_queries.rs index 00b675dbc4a..753917d7a3e 100644 --- a/compiler/rustc_mir/src/const_eval/eval_queries.rs +++ b/compiler/rustc_mir/src/const_eval/eval_queries.rs @@ -1,8 +1,8 @@ use super::{CompileTimeEvalContext, CompileTimeInterpreter, ConstEvalErr, MemoryExtra}; use crate::interpret::eval_nullary_intrinsic; use crate::interpret::{ - intern_const_alloc_recursive, Allocation, ConstValue, GlobalId, Immediate, InternKind, - InterpCx, InterpResult, MPlaceTy, MemoryKind, OpTy, ConstAlloc, RefTracking, Scalar, + intern_const_alloc_recursive, Allocation, ConstAlloc, ConstValue, GlobalId, Immediate, + InternKind, InterpCx, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, Scalar, ScalarMaybeUninit, StackPopCleanup, }; From ef04e68462914c8e0c45736852758b012e809590 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 9 Sep 2020 12:25:55 +0200 Subject: [PATCH 15/18] Update compile-fail tests --- src/test/compile-fail/issue-44415.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/compile-fail/issue-44415.rs b/src/test/compile-fail/issue-44415.rs index 763f8574873..71e764620d1 100644 --- a/src/test/compile-fail/issue-44415.rs +++ b/src/test/compile-fail/issue-44415.rs @@ -4,7 +4,7 @@ use std::intrinsics; struct Foo { bytes: [u8; unsafe { intrinsics::size_of::() }], - //~^ ERROR cycle detected when const-evaluating + checking + //~^ ERROR cycle detected when simplifying constant for the type system x: usize, } From c5889e4dabf4c7a40785949ff16a0c6f80bd8062 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 9 Sep 2020 14:04:27 +0200 Subject: [PATCH 16/18] Update incremental tests --- src/test/incremental/issue-54242.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/incremental/issue-54242.rs b/src/test/incremental/issue-54242.rs index 1c700d44dd8..25dc7cdf129 100644 --- a/src/test/incremental/issue-54242.rs +++ b/src/test/incremental/issue-54242.rs @@ -11,7 +11,7 @@ impl Tr for str { type Arr = [u8; 8]; #[cfg(cfail)] type Arr = [u8; Self::C]; - //[cfail]~^ ERROR cycle detected when const-evaluating + //[cfail]~^ ERROR cycle detected when simplifying constant } fn main() {} From b8e6883a2fb1e43747f410d3e906ec6371215d49 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sat, 19 Sep 2020 10:57:14 +0200 Subject: [PATCH 17/18] Reflect the "do not call this query directly" mentality in its name --- compiler/rustc_lint/src/builtin.rs | 1 + compiler/rustc_middle/src/mir/interpret/queries.rs | 4 ++-- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_mir/src/const_eval/eval_queries.rs | 6 +++--- compiler/rustc_mir/src/lib.rs | 2 +- src/test/ui/consts/const-eval/const-eval-query-stack.stderr | 4 ++-- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 71d4ae85d33..8c4c4b61daa 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1484,6 +1484,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedBrokenConst { } hir::ItemKind::Static(_, _, body_id) => { let def_id = cx.tcx.hir().body_owner_def_id(body_id).to_def_id(); + // FIXME: Use ensure here let _ = cx.tcx.eval_static_initializer(def_id); } _ => {} diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index d545cf6865d..f366681bc75 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -69,9 +69,9 @@ impl<'tcx> TyCtxt<'tcx> { // improve caching of queries. let inputs = self.erase_regions(¶m_env.and(cid)); if let Some(span) = span { - self.at(span).eval_to_const_value(inputs) + self.at(span).eval_to_const_value_raw(inputs) } else { - self.eval_to_const_value(inputs) + self.eval_to_const_value_raw(inputs) } } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index dbc0e73968b..c0a606a586b 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -724,7 +724,7 @@ rustc_queries! { /// /// **Do not use this** directly, use one of the following wrappers: `tcx.const_eval_poly`, /// `tcx.const_eval_resolve`, `tcx.const_eval_instance`, or `tcx.const_eval_global_id`. - query eval_to_const_value(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) + query eval_to_const_value_raw(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> EvalToConstValueResult<'tcx> { desc { |tcx| "simplifying constant for the type system `{}`", diff --git a/compiler/rustc_mir/src/const_eval/eval_queries.rs b/compiler/rustc_mir/src/const_eval/eval_queries.rs index 753917d7a3e..a0ee7fdc072 100644 --- a/compiler/rustc_mir/src/const_eval/eval_queries.rs +++ b/compiler/rustc_mir/src/const_eval/eval_queries.rs @@ -200,13 +200,13 @@ fn turn_into_const_value<'tcx>( ); assert!( !is_static || cid.promoted.is_some(), - "the `eval_to_const_value` query should not be used for statics, use `eval_to_allocation` instead" + "the `eval_to_const_value_raw` query should not be used for statics, use `eval_to_allocation` instead" ); // Turn this into a proper constant. op_to_const(&ecx, mplace.into()) } -pub fn eval_to_const_value_provider<'tcx>( +pub fn eval_to_const_value_raw_provider<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, ) -> ::rustc_middle::mir::interpret::EvalToConstValueResult<'tcx> { @@ -214,7 +214,7 @@ pub fn eval_to_const_value_provider<'tcx>( if key.param_env.reveal() == Reveal::All { let mut key = key; key.param_env = key.param_env.with_user_facing(); - match tcx.eval_to_const_value(key) { + match tcx.eval_to_const_value_raw(key) { // try again with reveal all as requested Err(ErrorHandled::TooGeneric) => {} // deduplicate calls diff --git a/compiler/rustc_mir/src/lib.rs b/compiler/rustc_mir/src/lib.rs index bbbb25117c0..49770b96a99 100644 --- a/compiler/rustc_mir/src/lib.rs +++ b/compiler/rustc_mir/src/lib.rs @@ -52,7 +52,7 @@ pub fn provide(providers: &mut Providers) { transform::provide(providers); monomorphize::partitioning::provide(providers); monomorphize::polymorphize::provide(providers); - providers.eval_to_const_value = const_eval::eval_to_const_value_provider; + providers.eval_to_const_value_raw = const_eval::eval_to_const_value_raw_provider; providers.eval_to_allocation_raw = const_eval::eval_to_allocation_raw_provider; providers.const_caller_location = const_eval::const_caller_location; providers.destructure_const = |tcx, param_env_and_value| { diff --git a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr index 26d396a1819..8c57fd37e88 100644 --- a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr +++ b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr @@ -10,8 +10,8 @@ LL | let x: &'static i32 = &(1 / 0); query stack during panic: #0 [eval_to_allocation_raw] const-evaluating + checking `main::promoted[1]` -#1 [eval_to_const_value] simplifying constant for the type system `main::promoted[1]` -#2 [eval_to_const_value] simplifying constant for the type system `main::promoted[1]` +#1 [eval_to_const_value_raw] simplifying constant for the type system `main::promoted[1]` +#2 [eval_to_const_value_raw] simplifying constant for the type system `main::promoted[1]` #3 [normalize_generic_arg_after_erasing_regions] normalizing `main::promoted[1]` #4 [optimized_mir] optimizing MIR for `main` #5 [collect_and_partition_mono_items] collect_and_partition_mono_items From 34785fcc4a56c4f705a1f5c9929689e5c46e1fbc Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sun, 20 Sep 2020 09:09:56 +0200 Subject: [PATCH 18/18] Make codegen test bitwidth-independent --- src/test/codegen/consts.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/codegen/consts.rs b/src/test/codegen/consts.rs index a69a4885bb5..fcb9002986a 100644 --- a/src/test/codegen/consts.rs +++ b/src/test/codegen/consts.rs @@ -43,7 +43,7 @@ pub fn inline_enum_const() -> E { #[no_mangle] pub fn low_align_const() -> E { // Check that low_align_const and high_align_const use the same constant - // CHECK: memcpy.p0i8.p0i8.i64(i8* align 2 %1, i8* align 2 getelementptr inbounds (<{ [8 x i8] }>, <{ [8 x i8] }>* [[LOW_HIGH]], i32 0, i32 0, i32 0), i64 8, i1 false) + // CHECK: memcpy.p0i8.p0i8.i{{(32|64)}}(i8* align 2 %1, i8* align 2 getelementptr inbounds (<{ [8 x i8] }>, <{ [8 x i8] }>* [[LOW_HIGH]], i32 0, i32 0, i32 0), i{{(32|64)}} 8, i1 false) *&E::A(0) } @@ -51,6 +51,6 @@ pub fn low_align_const() -> E { #[no_mangle] pub fn high_align_const() -> E { // Check that low_align_const and high_align_const use the same constant - // CHECK: memcpy.p0i8.p0i8.i64(i8* align 4 %1, i8* align 4 getelementptr inbounds (<{ [8 x i8] }>, <{ [8 x i8] }>* [[LOW_HIGH]], i32 0, i32 0, i32 0), i64 8, i1 false) + // CHECK: memcpy.p0i8.p0i8.i{{(32|64)}}(i8* align 4 %1, i8* align 4 getelementptr inbounds (<{ [8 x i8] }>, <{ [8 x i8] }>* [[LOW_HIGH]], i32 0, i32 0, i32 0), i{{(32|64)}} 8, i1 false) *&E::A(0) }