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_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_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 8c8487dc8a1..9824ec06db4 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1474,21 +1474,19 @@ 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(); + // FIXME: Use ensure here + let _ = cx.tcx.eval_static_initializer(def_id); } _ => {} } diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 059925088ce..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,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..adf551ee433 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -118,12 +118,12 @@ 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}; +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/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index dcc1f8b1a4b..f366681bc75 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_validated(inputs) + self.at(span).eval_to_const_value_raw(inputs) } else { - self.const_eval_validated(inputs) + self.eval_to_const_value_raw(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.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 7741c76ff3e..1f547d9dc3a 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -12,9 +12,9 @@ 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> { +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 44d906dada5..c0a606a586b 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -707,32 +707,27 @@ rustc_queries! { } Other { - /// Evaluates a constant without running sanity checks. + /// Evaluates a constant and returns the computed allocation. /// - /// **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>>) - -> 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 `{}`", + "const-evaluating + checking `{}`", key.value.display(tcx) } } - /// 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>>) - -> ConstEvalResult<'tcx> { + query eval_to_const_value_raw(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_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 72151df7230..a0ee7fdc072 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, RawConst, RefTracking, Scalar, + intern_const_alloc_recursive, Allocation, ConstAlloc, ConstValue, GlobalId, Immediate, + InternKind, InterpCx, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, Scalar, ScalarMaybeUninit, StackPopCleanup, }; @@ -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>, @@ -182,63 +184,37 @@ pub(super) fn op_to_const<'tcx>( } } -fn validate_and_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>>, -) -> ::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 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. - // 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())) - } - })(); - - 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| { - 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 `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 const_eval_validated_provider<'tcx>( +pub fn eval_to_const_value_raw_provider<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, -) -> ::rustc_middle::mir::interpret::ConstEvalResult<'tcx> { +) -> ::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_validated(key) { + match tcx.eval_to_const_value_raw(key) { // try again with reveal all as requested Err(ErrorHandled::TooGeneric) => {} // deduplicate calls @@ -261,13 +237,13 @@ pub fn const_eval_validated_provider<'tcx>( }); } - tcx.const_eval_raw(key).and_then(|val| validate_and_turn_into_const(tcx, val, key)) + tcx.eval_to_allocation_raw(key).map(|val| turn_into_const_value(tcx, val, key)) } -pub fn const_eval_raw_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 @@ -279,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.eval_to_allocation_raw(key) { // try again with reveal all as requested Err(ErrorHandled::TooGeneric) => {} // deduplicate calls @@ -318,9 +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(|place| RawConst { alloc_id: place.ptr.assert_ptr().alloc_id, ty: place.layout.ty }) - .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 { @@ -342,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()) { @@ -356,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 @@ -370,31 +345,65 @@ 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")) } - }) + } + Ok(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(ConstAlloc { alloc_id: mplace.ptr.assert_ptr().alloc_id, ty: mplace.layout.ty }) + } + } + } } diff --git a/compiler/rustc_mir/src/const_eval/machine.rs b/compiler/rustc_mir/src/const_eval/machine.rs index 02e905505c0..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_raw(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 f2f6c893eda..00d6ffb14ea 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 eval_to_allocation( &self, gid: GlobalId<'tcx>, ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { @@ -914,14 +889,7 @@ 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))?; + 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/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/memory.rs b/compiler/rustc_mir/src/interpret/memory.rs index d4be2ce0568..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_raw` 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/operand.rs b/compiler/rustc_mir/src/interpret/operand.rs index 57245696e57..8c4bb19866e 100644 --- a/compiler/rustc_mir/src/interpret/operand.rs +++ b/compiler/rustc_mir/src/interpret/operand.rs @@ -553,13 +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_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. - return Ok(self.const_eval(GlobalId { instance, promoted }, val.ty)?); + return Ok(self.eval_to_allocation(GlobalId { instance, promoted })?.into()); } ty::ConstKind::Infer(..) | ty::ConstKind::Bound(..) diff --git a/compiler/rustc_mir/src/interpret/place.rs b/compiler/rustc_mir/src/interpret/place.rs index 3b22eb5d987..72551b23370 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)] @@ -1120,7 +1120,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 ca62f0347ff..2b83e1c8134 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)); - // 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) { + assert!(self.ecx.tcx.is_static(did)); + 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 } ); } - // `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, - // 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(()); - } } } // Proceed recursively even for ZST, no reason to skip them! diff --git a/compiler/rustc_mir/src/lib.rs b/compiler/rustc_mir/src/lib.rs index 251037792c9..03e6f8414b9 100644 --- a/compiler/rustc_mir/src/lib.rs +++ b/compiler/rustc_mir/src/lib.rs @@ -53,8 +53,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.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| { let (param_env, value) = param_env_and_value.into_parts(); 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/codegen/consts.rs b/src/test/codegen/consts.rs index 318f9b0eec3..fcb9002986a 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.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: load %"E"*, %"E"** bitcast (<{ i8*, [0 x i8] }>* [[LOW_HIGH]] to %"E"**), + // 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) } 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, } 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() {} 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 dc2661ee796..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 @@ -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 + checking `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 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/double_check2.rs b/src/test/ui/consts/const-eval/double_check2.rs index 8402d628856..81f5dde450b 100644 --- a/src/test/ui/consts/const-eval/double_check2.rs +++ b/src/test/ui/consts/const-eval/double_check2.rs @@ -1,3 +1,9 @@ +// check-pass + +// 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, B = 42, @@ -13,11 +19,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`. 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/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 9042c6f6be1..03f8f5c5a0e 100644 --- a/src/test/ui/consts/recursive-zst-static.default.stderr +++ b/src/test/ui/consts/recursive-zst-static.default.stderr @@ -1,20 +1,16 @@ -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`... - --> $DIR/recursive-zst-static.rs:10:1 - | -LL | static FOO: () = FOO; - | ^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires const-evaluating `FOO`, completing the cycle -note: cycle used when const-evaluating + checking `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 + 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 9042c6f6be1..03f8f5c5a0e 100644 --- a/src/test/ui/consts/recursive-zst-static.unleash.stderr +++ b/src/test/ui/consts/recursive-zst-static.unleash.stderr @@ -1,20 +1,16 @@ -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`... - --> $DIR/recursive-zst-static.rs:10:1 - | -LL | static FOO: () = FOO; - | ^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires const-evaluating `FOO`, completing the cycle -note: cycle used when const-evaluating + checking `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 + 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 093606e100c..ee73b026a0b 100644 --- a/src/test/ui/recursion/recursive-static-definition.stderr +++ b/src/test/ui/recursion/recursive-static-definition.stderr @@ -1,20 +1,16 @@ -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`... - --> $DIR/recursive-static-definition.rs:1:1 - | -LL | pub static FOO: u32 = FOO; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires const-evaluating `FOO`, completing the cycle -note: cycle used when const-evaluating + checking `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 + 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 50dfce3448c..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,23 +4,19 @@ 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`... - --> $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: cycle used when const-evaluating + checking `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 + checking `C`, completing the cycle + = note: cycle used when running analysis passes on this crate error: aborting due to 2 previous errors