From 4e77e368ebc1bf21ae23137c253138c9ffbc3c7f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 5 Jan 2024 12:18:11 +0100 Subject: [PATCH 1/5] unstably allow constants to refer to statics and read from immutable statics --- compiler/rustc_const_eval/messages.ftl | 13 ++- .../rustc_const_eval/src/const_eval/error.rs | 6 +- .../src/const_eval/eval_queries.rs | 14 +-- .../src/const_eval/machine.rs | 38 +++----- .../rustc_const_eval/src/const_eval/mod.rs | 57 ++++------- .../src/const_eval/valtrees.rs | 96 ++++++++++++++----- compiler/rustc_const_eval/src/errors.rs | 22 ++--- .../src/interpret/validity.rs | 15 --- .../src/transform/check_consts/ops.rs | 17 ++-- .../src/util/caller_location.rs | 4 +- .../src/util/check_validity_requirement.rs | 4 +- .../src/error_codes/E0013.md | 4 +- compiler/rustc_feature/src/unstable.rs | 2 + compiler/rustc_span/src/symbol.rs | 1 + tests/ui/asm/x86_64/type-check-4.rs | 6 +- tests/ui/asm/x86_64/type-check-4.stderr | 23 +++-- .../const-prop-read-static-in-const.rs | 10 -- .../const-prop-read-static-in-const.stderr | 17 ---- .../ui/consts/const-fn-not-safe-for-const.rs | 4 +- .../consts/const-fn-not-safe-for-const.stderr | 18 ++-- tests/ui/consts/const_refs_to_static.rs | 19 ++++ tests/ui/consts/const_refs_to_static_fail.rs | 19 ++++ .../consts/const_refs_to_static_fail.stderr | 15 +++ .../const_refs_to_static_fail_pattern.rs | 15 +++ .../const_refs_to_static_fail_pattern.stderr | 14 +++ .../ui/consts/issue-17718-const-bad-values.rs | 6 +- .../issue-17718-const-bad-values.stderr | 18 ++-- tests/ui/consts/issue-17718-references.rs | 6 +- tests/ui/consts/issue-17718-references.stderr | 23 +++-- tests/ui/consts/issue-52060.rs | 2 +- tests/ui/consts/issue-52060.stderr | 9 +- tests/ui/consts/min_const_fn/min_const_fn.rs | 4 +- .../consts/min_const_fn/min_const_fn.stderr | 18 ++-- .../const_refers_to_static.32bit.stderr | 58 ++--------- .../const_refers_to_static.64bit.stderr | 58 ++--------- .../miri_unleashed/const_refers_to_static.rs | 14 +-- ..._refers_to_static_cross_crate.32bit.stderr | 86 ++++++++--------- ..._refers_to_static_cross_crate.64bit.stderr | 86 ++++++++--------- .../const_refers_to_static_cross_crate.rs | 14 +-- .../mutable_references_err.32bit.stderr | 57 +++++------ .../mutable_references_err.64bit.stderr | 57 +++++------ .../miri_unleashed/mutable_references_err.rs | 9 +- tests/ui/error-codes/E0013.rs | 4 - tests/ui/error-codes/E0013.stderr | 11 --- .../feature-gate-const-refs-to-static.rs | 12 +++ .../feature-gate-const-refs-to-static.stderr | 37 +++++++ tests/ui/static/issue-18118-2.rs | 2 +- tests/ui/static/issue-18118-2.stderr | 9 +- tests/ui/thread-local/thread-local-static.rs | 2 +- .../thread-local/thread-local-static.stderr | 11 ++- 50 files changed, 542 insertions(+), 524 deletions(-) delete mode 100644 tests/ui/const_prop/const-prop-read-static-in-const.rs delete mode 100644 tests/ui/const_prop/const-prop-read-static-in-const.stderr create mode 100644 tests/ui/consts/const_refs_to_static.rs create mode 100644 tests/ui/consts/const_refs_to_static_fail.rs create mode 100644 tests/ui/consts/const_refs_to_static_fail.stderr create mode 100644 tests/ui/consts/const_refs_to_static_fail_pattern.rs create mode 100644 tests/ui/consts/const_refs_to_static_fail_pattern.stderr delete mode 100644 tests/ui/error-codes/E0013.rs delete mode 100644 tests/ui/error-codes/E0013.stderr create mode 100644 tests/ui/feature-gates/feature-gate-const-refs-to-static.rs create mode 100644 tests/ui/feature-gates/feature-gate-const-refs-to-static.stderr diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index e7e8b2b36006d..d932bf3c2a25d 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -30,7 +30,9 @@ const_eval_closure_non_const = cannot call non-const closure in {const_eval_const_context}s const_eval_consider_dereferencing = consider dereferencing here -const_eval_const_accesses_static = constant accesses static + +const_eval_const_accesses_mut_global = + constant accesses mutable global memory const_eval_const_context = {$kind -> [const] constant @@ -213,6 +215,9 @@ const_eval_modified_global = const_eval_mut_deref = mutation through a reference is not allowed in {const_eval_const_context}s +const_eval_mutable_data_in_const = + constant refers to mutable data + const_eval_mutable_ptr_in_final = encountered mutable pointer in final value of {const_eval_intern_kind} const_eval_non_const_fmt_macro_call = @@ -319,12 +324,6 @@ const_eval_size_overflow = const_eval_stack_frame_limit_reached = reached the configured maximum number of stack frames -const_eval_static_access = - {const_eval_const_context}s cannot refer to statics - .help = consider extracting the value of the `static` to a `const`, and referring to that - .teach_note = `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. - .teach_help = To fix this, the value can be extracted to a `const` and then used. - const_eval_thread_local_access = thread-local statics cannot be accessed at compile-time diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 62af21396ab4b..71085c2b2a5cf 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -17,7 +17,7 @@ use crate::interpret::{ErrorHandled, InterpError, InterpErrorInfo, MachineStopTy /// The CTFE machine has some custom error kinds. #[derive(Clone, Debug)] pub enum ConstEvalErrKind { - ConstAccessesStatic, + ConstAccessesMutGlobal, ModifiedGlobal, AssertFailure(AssertKind), Panic { msg: Symbol, line: u32, col: u32, file: Symbol }, @@ -28,7 +28,7 @@ impl MachineStopType for ConstEvalErrKind { use crate::fluent_generated::*; use ConstEvalErrKind::*; match self { - ConstAccessesStatic => const_eval_const_accesses_static, + ConstAccessesMutGlobal => const_eval_const_accesses_mut_global, ModifiedGlobal => const_eval_modified_global, Panic { .. } => const_eval_panic, AssertFailure(x) => x.diagnostic_message(), @@ -37,7 +37,7 @@ impl MachineStopType for ConstEvalErrKind { fn add_args(self: Box, adder: &mut dyn FnMut(DiagnosticArgName, DiagnosticArgValue)) { use ConstEvalErrKind::*; match *self { - ConstAccessesStatic | ModifiedGlobal => {} + ConstAccessesMutGlobal | ModifiedGlobal => {} AssertFailure(kind) => kind.add_args(adder), Panic { msg, line, col, file } => { adder("msg".into(), msg.into_diagnostic_arg()); diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index a2d0f1c5583f3..52060a8693f1b 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -11,7 +11,7 @@ use rustc_middle::ty::{self, TyCtxt}; use rustc_span::Span; use rustc_target::abi::{self, Abi}; -use super::{CanAccessStatics, CompileTimeEvalContext, CompileTimeInterpreter}; +use super::{CanAccessMutGlobal, CompileTimeEvalContext, CompileTimeInterpreter}; use crate::const_eval::CheckAlignment; use crate::errors; use crate::errors::ConstEvalError; @@ -90,14 +90,14 @@ pub(crate) fn mk_eval_cx<'mir, 'tcx>( tcx: TyCtxt<'tcx>, root_span: Span, param_env: ty::ParamEnv<'tcx>, - can_access_statics: CanAccessStatics, + can_access_mut_global: CanAccessMutGlobal, ) -> CompileTimeEvalContext<'mir, 'tcx> { debug!("mk_eval_cx: {:?}", param_env); InterpCx::new( tcx, root_span, param_env, - CompileTimeInterpreter::new(can_access_statics, CheckAlignment::No), + CompileTimeInterpreter::new(can_access_mut_global, CheckAlignment::No), ) } @@ -200,7 +200,7 @@ pub(crate) fn turn_into_const_value<'tcx>( tcx, tcx.def_span(key.value.instance.def_id()), key.param_env, - CanAccessStatics::from(is_static), + CanAccessMutGlobal::from(is_static), ); let mplace = ecx.raw_const_to_mplace(constant).expect( @@ -277,9 +277,11 @@ pub fn eval_to_allocation_raw_provider<'tcx>( tcx, tcx.def_span(def), key.param_env, - // Statics (and promoteds inside statics) may access other statics, because unlike consts + // Statics (and promoteds inside statics) may access mutable global memory, because unlike consts // they do not have to behave "as if" they were evaluated at runtime. - CompileTimeInterpreter::new(CanAccessStatics::from(is_static), CheckAlignment::Error), + // For consts however we want to ensure they behave "as if" they were evaluated at runtime, + // so we have to reject reading mutable global memory. + CompileTimeInterpreter::new(CanAccessMutGlobal::from(is_static), CheckAlignment::Error), ); eval_in_interpreter(ecx, cid, is_static) } diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 274ff25fb9b58..d08985edb76b0 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -51,13 +51,10 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> { /// The virtual call stack. pub(super) stack: Vec>, - /// We need to make sure consts never point to anything mutable, even recursively. That is - /// relied on for pattern matching on consts with references. - /// To achieve this, two pieces have to work together: - /// * Interning makes everything outside of statics immutable. - /// * Pointers to allocations inside of statics can never leak outside, to a non-static global. - /// This boolean here controls the second part. - pub(super) can_access_statics: CanAccessStatics, + /// Pattern matching on consts with references would be unsound if those references + /// could point to anything mutable. Therefore, when evaluating consts and when constructing valtrees, + /// we ensure that only immutable global memory can be accessed. + pub(super) can_access_mut_global: CanAccessMutGlobal, /// Whether to check alignment during evaluation. pub(super) check_alignment: CheckAlignment, @@ -73,12 +70,12 @@ pub enum CheckAlignment { } #[derive(Copy, Clone, PartialEq)] -pub(crate) enum CanAccessStatics { +pub(crate) enum CanAccessMutGlobal { No, Yes, } -impl From for CanAccessStatics { +impl From for CanAccessMutGlobal { fn from(value: bool) -> Self { if value { Self::Yes } else { Self::No } } @@ -86,13 +83,13 @@ impl From for CanAccessStatics { impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> { pub(crate) fn new( - can_access_statics: CanAccessStatics, + can_access_mut_global: CanAccessMutGlobal, check_alignment: CheckAlignment, ) -> Self { CompileTimeInterpreter { num_evaluated_steps: 0, stack: Vec::new(), - can_access_statics, + can_access_mut_global, check_alignment, } } @@ -680,7 +677,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, machine: &Self, alloc_id: AllocId, alloc: ConstAllocation<'tcx>, - static_def_id: Option, + _static_def_id: Option, is_write: bool, ) -> InterpResult<'tcx> { let alloc = alloc.inner(); @@ -692,22 +689,15 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, } } else { // Read access. These are usually allowed, with some exceptions. - if machine.can_access_statics == CanAccessStatics::Yes { + if machine.can_access_mut_global == CanAccessMutGlobal::Yes { // Machine configuration allows us read from anything (e.g., `static` initializer). Ok(()) - } else if static_def_id.is_some() { - // Machine configuration does not allow us to read statics - // (e.g., `const` initializer). - // See const_eval::machine::MemoryExtra::can_access_statics for why - // this check is so important: if we could read statics, we could read pointers - // to mutable allocations *inside* statics. These allocations are not themselves - // statics, so pointers to them can get around the check in `validity.rs`. - Err(ConstEvalErrKind::ConstAccessesStatic.into()) + } else if alloc.mutability == Mutability::Mut { + // Machine configuration does not allow us to read statics (e.g., `const` + // initializer). + Err(ConstEvalErrKind::ConstAccessesMutGlobal.into()) } else { // Immutable global, this read is fine. - // But make sure we never accept a read from something mutable, that would be - // unsound. The reason is that as the content of this allocation may be different - // now and at run-time, so if we permit reading now we might return the wrong value. assert_eq!(alloc.mutability, Mutability::Not); Ok(()) } diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 29cbb7f07e87a..826b4b278ed61 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -1,12 +1,10 @@ // Not in interpret to make sure we do not use private implementation details -use crate::errors::MaxNumNodesInConstErr; use crate::interpret::InterpCx; use rustc_middle::mir; -use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId}; +use rustc_middle::mir::interpret::{InterpError, InterpErrorInfo}; use rustc_middle::query::TyCtxtAt; -use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_span::DUMMY_SP; +use rustc_middle::ty::{self, Ty}; mod error; mod eval_queries; @@ -18,55 +16,32 @@ pub use error::*; pub use eval_queries::*; pub use fn_queries::*; pub use machine::*; -pub(crate) use valtrees::{const_to_valtree_inner, valtree_to_const_value}; +pub(crate) use valtrees::{eval_to_valtree, valtree_to_const_value}; // We forbid type-level constants that contain more than `VALTREE_MAX_NODES` nodes. const VALTREE_MAX_NODES: usize = 100000; pub(crate) enum ValTreeCreationError { NodesOverflow, + /// Values of this type, or this particular value, are not supported as valtrees. NonSupportedType, + /// The value pointed to non-read-only memory, so we cannot make it a valtree. + NotReadOnly, Other, } pub(crate) type ValTreeCreationResult<'tcx> = Result, ValTreeCreationError>; -/// Evaluates a constant and turns it into a type-level constant value. -pub(crate) fn eval_to_valtree<'tcx>( - tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - cid: GlobalId<'tcx>, -) -> EvalToValTreeResult<'tcx> { - let const_alloc = tcx.eval_to_allocation_raw(param_env.and(cid))?; - - // FIXME Need to provide a span to `eval_to_valtree` - let ecx = mk_eval_cx( - tcx, - DUMMY_SP, - param_env, - // It is absolutely crucial for soundness that - // we do not read from static items or other mutable memory. - CanAccessStatics::No, - ); - let place = ecx.raw_const_to_mplace(const_alloc).unwrap(); - debug!(?place); - - let mut num_nodes = 0; - let valtree_result = const_to_valtree_inner(&ecx, &place, &mut num_nodes); - - match valtree_result { - Ok(valtree) => Ok(Some(valtree)), - Err(err) => { - let did = cid.instance.def_id(); - let global_const_id = cid.display(tcx); - match err { - ValTreeCreationError::NodesOverflow => { - let span = tcx.hir().span_if_local(did); - tcx.dcx().emit_err(MaxNumNodesInConstErr { span, global_const_id }); - - Ok(None) +impl From> for ValTreeCreationError { + fn from(err: InterpErrorInfo<'_>) -> Self { + match err.kind() { + InterpError::MachineStop(err) => { + let err = err.downcast_ref::().unwrap(); + match err { + ConstEvalErrKind::ConstAccessesMutGlobal => ValTreeCreationError::NotReadOnly, + _ => ValTreeCreationError::Other, } - ValTreeCreationError::NonSupportedType | ValTreeCreationError::Other => Ok(None), } + _ => ValTreeCreationError::Other, } } } @@ -78,7 +53,7 @@ pub(crate) fn try_destructure_mir_constant_for_user_output<'tcx>( ty: Ty<'tcx>, ) -> Option> { let param_env = ty::ParamEnv::reveal_all(); - let ecx = mk_eval_cx(tcx.tcx, tcx.span, param_env, CanAccessStatics::No); + let ecx = mk_eval_cx(tcx.tcx, tcx.span, param_env, CanAccessMutGlobal::No); let op = ecx.const_val_to_op(val, ty, None).ok()?; // We go to `usize` as we cannot allocate anything bigger anyway. diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index 5c2bf4626c4c3..31fcdc9a3bd13 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -1,17 +1,20 @@ +use rustc_middle::mir; +use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId}; +use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout}; +use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt}; +use rustc_span::DUMMY_SP; +use rustc_target::abi::{Abi, VariantIdx}; + use super::eval_queries::{mk_eval_cx, op_to_const}; use super::machine::CompileTimeEvalContext; use super::{ValTreeCreationError, ValTreeCreationResult, VALTREE_MAX_NODES}; -use crate::const_eval::CanAccessStatics; +use crate::const_eval::CanAccessMutGlobal; +use crate::errors::{MaxNumNodesInConstErr, MutableDataInConstErr}; use crate::interpret::MPlaceTy; use crate::interpret::{ intern_const_alloc_recursive, ImmTy, Immediate, InternKind, MemPlaceMeta, MemoryKind, PlaceTy, Projectable, Scalar, }; -use rustc_middle::mir; -use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout}; -use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt}; -use rustc_span::DUMMY_SP; -use rustc_target::abi::{Abi, VariantIdx}; #[instrument(skip(ecx), level = "debug")] fn branches<'tcx>( @@ -70,7 +73,7 @@ fn slice_branches<'tcx>( } #[instrument(skip(ecx), level = "debug")] -pub(crate) fn const_to_valtree_inner<'tcx>( +fn const_to_valtree_inner<'tcx>( ecx: &CompileTimeEvalContext<'tcx, 'tcx>, place: &MPlaceTy<'tcx>, num_nodes: &mut usize, @@ -88,9 +91,7 @@ pub(crate) fn const_to_valtree_inner<'tcx>( Ok(ty::ValTree::zst()) } ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => { - let Ok(val) = ecx.read_immediate(place) else { - return Err(ValTreeCreationError::Other); - }; + let val = ecx.read_immediate(place)?; let val = val.to_scalar(); *num_nodes += 1; @@ -102,19 +103,17 @@ pub(crate) fn const_to_valtree_inner<'tcx>( // equality at compile-time (see `ptr_guaranteed_cmp`). // However we allow those that are just integers in disguise. // First, get the pointer. Remember it might be wide! - let Ok(val) = ecx.read_immediate(place) else { - return Err(ValTreeCreationError::Other); - }; + let val = ecx.read_immediate(place)?; // We could allow wide raw pointers where both sides are integers in the future, // but for now we reject them. if matches!(val.layout.abi, Abi::ScalarPair(..)) { - return Err(ValTreeCreationError::Other); + return Err(ValTreeCreationError::NonSupportedType); } let val = val.to_scalar(); // We are in the CTFE machine, so ptr-to-int casts will fail. // This can only be `Ok` if `val` already is an integer. let Ok(val) = val.try_to_int() else { - return Err(ValTreeCreationError::Other); + return Err(ValTreeCreationError::NonSupportedType); }; // It's just a ScalarInt! Ok(ty::ValTree::Leaf(val)) @@ -125,11 +124,7 @@ pub(crate) fn const_to_valtree_inner<'tcx>( ty::FnPtr(_) => Err(ValTreeCreationError::NonSupportedType), ty::Ref(_, _, _) => { - let Ok(derefd_place)= ecx.deref_pointer(place) else { - return Err(ValTreeCreationError::Other); - }; - debug!(?derefd_place); - + let derefd_place = ecx.deref_pointer(place)?; const_to_valtree_inner(ecx, &derefd_place, num_nodes) } @@ -153,9 +148,7 @@ pub(crate) fn const_to_valtree_inner<'tcx>( bug!("uninhabited types should have errored and never gotten converted to valtree") } - let Ok(variant) = ecx.read_discriminant(place) else { - return Err(ValTreeCreationError::Other); - }; + let variant = ecx.read_discriminant(place)?; branches(ecx, place, def.variant(variant).fields.len(), def.is_enum().then_some(variant), num_nodes) } @@ -221,6 +214,59 @@ fn create_valtree_place<'tcx>( ecx.allocate_dyn(layout, MemoryKind::Stack, meta).unwrap() } +/// Evaluates a constant and turns it into a type-level constant value. +pub(crate) fn eval_to_valtree<'tcx>( + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + cid: GlobalId<'tcx>, +) -> EvalToValTreeResult<'tcx> { + let const_alloc = tcx.eval_to_allocation_raw(param_env.and(cid))?; + + // FIXME Need to provide a span to `eval_to_valtree` + let ecx = mk_eval_cx( + tcx, + DUMMY_SP, + param_env, + // It is absolutely crucial for soundness that + // we do not read from mutable memory. + CanAccessMutGlobal::No, + ); + let place = ecx.raw_const_to_mplace(const_alloc).unwrap(); + debug!(?place); + + let mut num_nodes = 0; + let valtree_result = const_to_valtree_inner(&ecx, &place, &mut num_nodes); + + match valtree_result { + Ok(valtree) => Ok(Some(valtree)), + Err(err) => { + let did = cid.instance.def_id(); + let global_const_id = cid.display(tcx); + let span = tcx.hir().span_if_local(did); + match err { + ValTreeCreationError::NodesOverflow => { + let handled = + tcx.dcx().emit_err(MaxNumNodesInConstErr { span, global_const_id }); + Err(handled.into()) + } + ValTreeCreationError::NotReadOnly => { + let handled = + tcx.dcx().emit_err(MutableDataInConstErr { span, global_const_id }); + Err(handled.into()) + } + ValTreeCreationError::Other => { + let handled = tcx.dcx().span_delayed_bug( + span.unwrap_or(DUMMY_SP), + "unexpected error during valtree construction", + ); + Err(handled.into()) + } + ValTreeCreationError::NonSupportedType => Ok(None), + } + } + } +} + /// Converts a `ValTree` to a `ConstValue`, which is needed after mir /// construction has finished. // FIXME Merge `valtree_to_const_value` and `valtree_into_mplace` into one function @@ -253,7 +299,7 @@ pub fn valtree_to_const_value<'tcx>( } } ty::Ref(_, inner_ty, _) => { - let mut ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, CanAccessStatics::No); + let mut ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, CanAccessMutGlobal::No); let imm = valtree_to_ref(&mut ecx, valtree, *inner_ty); let imm = ImmTy::from_immediate(imm, tcx.layout_of(param_env_ty).unwrap()); op_to_const(&ecx, &imm.into(), /* for diagnostics */ false) @@ -280,7 +326,7 @@ pub fn valtree_to_const_value<'tcx>( bug!("could not find non-ZST field during in {layout:#?}"); } - let mut ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, CanAccessStatics::No); + let mut ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, CanAccessMutGlobal::No); // Need to create a place for this valtree. let place = create_valtree_place(&mut ecx, layout, valtree); diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 4d2b1ba3eec89..296329f5d1e78 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -56,23 +56,11 @@ pub(crate) struct UnstableInStable { #[derive(Diagnostic)] #[diag(const_eval_thread_local_access, code = E0625)] -pub(crate) struct NonConstOpErr { +pub(crate) struct ThreadLocalAccessErr { #[primary_span] pub span: Span, } -#[derive(Diagnostic)] -#[diag(const_eval_static_access, code = E0013)] -#[help] -pub(crate) struct StaticAccessErr { - #[primary_span] - pub span: Span, - pub kind: ConstContext, - #[note(const_eval_teach_note)] - #[help(const_eval_teach_help)] - pub teach: Option<()>, -} - #[derive(Diagnostic)] #[diag(const_eval_raw_ptr_to_int)] #[note] @@ -129,6 +117,14 @@ pub(crate) struct MaxNumNodesInConstErr { pub global_const_id: String, } +#[derive(Diagnostic)] +#[diag(const_eval_mutable_data_in_const)] +pub(crate) struct MutableDataInConstErr { + #[primary_span] + pub span: Option, + pub global_const_id: String, +} + #[derive(Diagnostic)] #[diag(const_eval_unallowed_fn_pointer_call)] pub(crate) struct UnallowedFnPointerCall { diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 90cde81c01874..67665c4aed2cf 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -132,7 +132,6 @@ pub enum CtfeValidationMode { /// `allow_immutable_unsafe_cell` says whether we allow `UnsafeCell` in immutable memory (which is the /// case for the top-level allocation of a `const`, where this is fine because the allocation will be /// copied at each use site). - /// `allow_static_ptrs` says if pointers to statics are permitted (which is the case for promoteds in statics). Const { allow_immutable_unsafe_cell: bool, allow_static_ptrs: bool }, } @@ -146,13 +145,6 @@ impl CtfeValidationMode { } } - fn allow_static_ptrs(self) -> bool { - match self { - CtfeValidationMode::Static { .. } => true, // statics can point to statics - CtfeValidationMode::Const { allow_static_ptrs, .. } => allow_static_ptrs, - } - } - fn may_contain_mutable_ref(self) -> bool { match self { CtfeValidationMode::Static { mutbl } => mutbl == Mutability::Mut, @@ -468,13 +460,6 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' // Special handling for pointers to statics (irrespective of their type). assert!(!self.ecx.tcx.is_thread_local_static(did)); assert!(self.ecx.tcx.is_static(did)); - if self.ctfe_mode.is_some_and(|c| !c.allow_static_ptrs()) { - // 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, PtrToStatic { ptr_kind }); - } // Mutability check. if ptr_expected_mutbl == Mutability::Mut { if matches!( diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index fb705d91977d7..a9d472d377cd6 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -580,16 +580,21 @@ impl<'tcx> NonConstOp<'tcx> for StaticAccess { if let hir::ConstContext::Static(_) = ccx.const_kind() { Status::Allowed } else { - Status::Forbidden + Status::Unstable(sym::const_refs_to_static) } } fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { - ccx.dcx().create_err(errors::StaticAccessErr { + let mut err = feature_err( + &ccx.tcx.sess, + sym::const_refs_to_static, span, - kind: ccx.const_kind(), - teach: ccx.tcx.sess.teach(E0013).then_some(()), - }) + format!("referencing statics in {}s is unstable", ccx.const_kind(),), + ); + err + .note("`static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable.") + .help("to fix this, the value can be extracted to a `const` and then used."); + err } } @@ -598,7 +603,7 @@ impl<'tcx> NonConstOp<'tcx> for StaticAccess { pub struct ThreadLocalAccess; impl<'tcx> NonConstOp<'tcx> for ThreadLocalAccess { fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { - ccx.dcx().create_err(errors::NonConstOpErr { span }) + ccx.dcx().create_err(errors::ThreadLocalAccessErr { span }) } } diff --git a/compiler/rustc_const_eval/src/util/caller_location.rs b/compiler/rustc_const_eval/src/util/caller_location.rs index 36a315b8f3078..d1c2d22b5a912 100644 --- a/compiler/rustc_const_eval/src/util/caller_location.rs +++ b/compiler/rustc_const_eval/src/util/caller_location.rs @@ -6,7 +6,7 @@ use rustc_middle::ty::layout::LayoutOf; use rustc_span::symbol::Symbol; use rustc_type_ir::Mutability; -use crate::const_eval::{mk_eval_cx, CanAccessStatics, CompileTimeEvalContext}; +use crate::const_eval::{mk_eval_cx, CanAccessMutGlobal, CompileTimeEvalContext}; use crate::interpret::*; /// Allocate a `const core::panic::Location` with the provided filename and line/column numbers. @@ -57,7 +57,7 @@ pub(crate) fn const_caller_location_provider( col: u32, ) -> mir::ConstValue<'_> { trace!("const_caller_location: {}:{}:{}", file, line, col); - let mut ecx = mk_eval_cx(tcx.tcx, tcx.span, ty::ParamEnv::reveal_all(), CanAccessStatics::No); + let mut ecx = mk_eval_cx(tcx.tcx, tcx.span, ty::ParamEnv::reveal_all(), CanAccessMutGlobal::No); let loc_place = alloc_caller_location(&mut ecx, file, line, col); if intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &loc_place).is_err() { diff --git a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs index e9e0690f07df1..8c4af5e513217 100644 --- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs +++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs @@ -2,7 +2,7 @@ use rustc_middle::ty::layout::{LayoutCx, LayoutError, LayoutOf, TyAndLayout, Val use rustc_middle::ty::{ParamEnv, ParamEnvAnd, Ty, TyCtxt}; use rustc_target::abi::{Abi, FieldsShape, Scalar, Variants}; -use crate::const_eval::{CanAccessStatics, CheckAlignment, CompileTimeInterpreter}; +use crate::const_eval::{CanAccessMutGlobal, CheckAlignment, CompileTimeInterpreter}; use crate::interpret::{InterpCx, MemoryKind, OpTy}; /// Determines if this type permits "raw" initialization by just transmuting some memory into an @@ -44,7 +44,7 @@ fn might_permit_raw_init_strict<'tcx>( tcx: TyCtxt<'tcx>, kind: ValidityRequirement, ) -> Result> { - let machine = CompileTimeInterpreter::new(CanAccessStatics::No, CheckAlignment::Error); + let machine = CompileTimeInterpreter::new(CanAccessMutGlobal::No, CheckAlignment::Error); let mut cx = InterpCx::new(tcx, rustc_span::DUMMY_SP, ParamEnv::reveal_all(), machine); diff --git a/compiler/rustc_error_codes/src/error_codes/E0013.md b/compiler/rustc_error_codes/src/error_codes/E0013.md index 5605302772ff6..9f4848343ff1c 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0013.md +++ b/compiler/rustc_error_codes/src/error_codes/E0013.md @@ -1,9 +1,11 @@ +#### Note: this error code is no longer emitted by the compiler + Static and const variables can refer to other const variables. But a const variable cannot refer to a static variable. Erroneous code example: -```compile_fail,E0013 +```compile_fail,E0658 static X: i32 = 42; const Y: i32 = X; ``` diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 42fc24c937bfc..efb0b1fbabbc8 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -409,6 +409,8 @@ declare_features! ( (unstable, const_precise_live_drops, "1.46.0", Some(73255)), /// Allows references to types with interior mutability within constants (unstable, const_refs_to_cell, "1.51.0", Some(80384)), + /// Allows creating pointers and references to `static` items in constants. + (unstable, const_refs_to_static, "CURRENT_RUSTC_VERSION", Some(119618)), /// Allows `impl const Trait for T` syntax. (unstable, const_trait_impl, "1.42.0", Some(67792)), /// Allows the `?` operator in const contexts. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index ed6e69d919949..aa912c93c08c6 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -582,6 +582,7 @@ symbols! { const_raw_ptr_deref, const_raw_ptr_to_usize_cast, const_refs_to_cell, + const_refs_to_static, const_trait, const_trait_bound_opt_out, const_trait_impl, diff --git a/tests/ui/asm/x86_64/type-check-4.rs b/tests/ui/asm/x86_64/type-check-4.rs index 3d5d3807c530e..d0dacda4afb78 100644 --- a/tests/ui/asm/x86_64/type-check-4.rs +++ b/tests/ui/asm/x86_64/type-check-4.rs @@ -19,10 +19,10 @@ const fn const_bar(x: T) -> T { x } global_asm!("{}", const S); -//~^ ERROR constants cannot refer to statics +//~^ ERROR referencing statics global_asm!("{}", const const_foo(0)); global_asm!("{}", const const_foo(S)); -//~^ ERROR constants cannot refer to statics +//~^ ERROR referencing statics global_asm!("{}", const const_bar(0)); global_asm!("{}", const const_bar(S)); -//~^ ERROR constants cannot refer to statics +//~^ ERROR referencing statics diff --git a/tests/ui/asm/x86_64/type-check-4.stderr b/tests/ui/asm/x86_64/type-check-4.stderr index 3875bcc211252..fbca868c0838b 100644 --- a/tests/ui/asm/x86_64/type-check-4.stderr +++ b/tests/ui/asm/x86_64/type-check-4.stderr @@ -1,27 +1,36 @@ -error[E0013]: constants cannot refer to statics +error[E0658]: referencing statics in constants is unstable --> $DIR/type-check-4.rs:21:25 | LL | global_asm!("{}", const S); | ^ | - = help: consider extracting the value of the `static` to a `const`, and referring to that + = note: see issue #119618 for more information + = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. + = help: to fix this, the value can be extracted to a `const` and then used. -error[E0013]: constants cannot refer to statics +error[E0658]: referencing statics in constants is unstable --> $DIR/type-check-4.rs:24:35 | LL | global_asm!("{}", const const_foo(S)); | ^ | - = help: consider extracting the value of the `static` to a `const`, and referring to that + = note: see issue #119618 for more information + = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. + = help: to fix this, the value can be extracted to a `const` and then used. -error[E0013]: constants cannot refer to statics +error[E0658]: referencing statics in constants is unstable --> $DIR/type-check-4.rs:27:35 | LL | global_asm!("{}", const const_bar(S)); | ^ | - = help: consider extracting the value of the `static` to a `const`, and referring to that + = note: see issue #119618 for more information + = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. + = help: to fix this, the value can be extracted to a `const` and then used. error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0013`. +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/const_prop/const-prop-read-static-in-const.rs b/tests/ui/const_prop/const-prop-read-static-in-const.rs deleted file mode 100644 index 21426205955be..0000000000000 --- a/tests/ui/const_prop/const-prop-read-static-in-const.rs +++ /dev/null @@ -1,10 +0,0 @@ -// compile-flags: -Zunleash-the-miri-inside-of-you - -#![allow(dead_code)] - -const TEST: u8 = MY_STATIC; //~ ERROR constant - -static MY_STATIC: u8 = 4; - -fn main() { -} diff --git a/tests/ui/const_prop/const-prop-read-static-in-const.stderr b/tests/ui/const_prop/const-prop-read-static-in-const.stderr deleted file mode 100644 index 9af1f7e3a241c..0000000000000 --- a/tests/ui/const_prop/const-prop-read-static-in-const.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0080]: evaluation of constant value failed - --> $DIR/const-prop-read-static-in-const.rs:5:18 - | -LL | const TEST: u8 = MY_STATIC; - | ^^^^^^^^^ constant accesses static - -warning: skipping const checks - | -help: skipping check that does not even have a feature gate - --> $DIR/const-prop-read-static-in-const.rs:5:18 - | -LL | const TEST: u8 = MY_STATIC; - | ^^^^^^^^^ - -error: aborting due to 1 previous error; 1 warning emitted - -For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-fn-not-safe-for-const.rs b/tests/ui/consts/const-fn-not-safe-for-const.rs index b2fe73ae9302c..6d8404880ca30 100644 --- a/tests/ui/consts/const-fn-not-safe-for-const.rs +++ b/tests/ui/consts/const-fn-not-safe-for-const.rs @@ -18,12 +18,12 @@ static Y: u32 = 0; const fn get_Y() -> u32 { Y - //~^ ERROR E0013 + //~^ ERROR referencing statics in constant functions } const fn get_Y_addr() -> &'static u32 { &Y - //~^ ERROR E0013 + //~^ ERROR referencing statics in constant functions } const fn get() -> u32 { diff --git a/tests/ui/consts/const-fn-not-safe-for-const.stderr b/tests/ui/consts/const-fn-not-safe-for-const.stderr index 4c7effc0d1586..1793c7342806f 100644 --- a/tests/ui/consts/const-fn-not-safe-for-const.stderr +++ b/tests/ui/consts/const-fn-not-safe-for-const.stderr @@ -6,23 +6,29 @@ LL | random() | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error[E0013]: constant functions cannot refer to statics +error[E0658]: referencing statics in constant functions is unstable --> $DIR/const-fn-not-safe-for-const.rs:20:5 | LL | Y | ^ | - = help: consider extracting the value of the `static` to a `const`, and referring to that + = note: see issue #119618 for more information + = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. + = help: to fix this, the value can be extracted to a `const` and then used. -error[E0013]: constant functions cannot refer to statics +error[E0658]: referencing statics in constant functions is unstable --> $DIR/const-fn-not-safe-for-const.rs:25:6 | LL | &Y | ^ | - = help: consider extracting the value of the `static` to a `const`, and referring to that + = note: see issue #119618 for more information + = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. + = help: to fix this, the value can be extracted to a `const` and then used. error: aborting due to 3 previous errors -Some errors have detailed explanations: E0013, E0015. -For more information about an error, try `rustc --explain E0013`. +Some errors have detailed explanations: E0015, E0658. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/const_refs_to_static.rs b/tests/ui/consts/const_refs_to_static.rs new file mode 100644 index 0000000000000..f5e5ef5f699e2 --- /dev/null +++ b/tests/ui/consts/const_refs_to_static.rs @@ -0,0 +1,19 @@ +// run-pass +#![feature(const_refs_to_static)] + +static S: i32 = 0; +static mut S_MUT: i32 = 0; + +const C1: &i32 = &S; +#[allow(unused)] +const C1_READ: () = { + assert!(*C1 == 0); +}; +const C2: *const i32 = unsafe { std::ptr::addr_of!(S_MUT) }; + +fn main() { + assert_eq!(*C1, 0); + assert_eq!(unsafe { *C2 }, 0); + // Computing this pattern will read from an immutable static. That's fine. + assert!(matches!(&0, C1)); +} diff --git a/tests/ui/consts/const_refs_to_static_fail.rs b/tests/ui/consts/const_refs_to_static_fail.rs new file mode 100644 index 0000000000000..95ffcce43660f --- /dev/null +++ b/tests/ui/consts/const_refs_to_static_fail.rs @@ -0,0 +1,19 @@ +#![feature(const_refs_to_static, const_mut_refs, sync_unsafe_cell)] +use std::cell::SyncUnsafeCell; + +static S: SyncUnsafeCell = SyncUnsafeCell::new(0); +static mut S_MUT: i32 = 0; + +const C1: &SyncUnsafeCell = &S; +const C1_READ: () = unsafe { + assert!(*C1.get() == 0); //~ERROR evaluation of constant value failed + //~^ constant accesses mutable global memory +}; +const C2: *const i32 = unsafe { std::ptr::addr_of!(S_MUT) }; +const C2_READ: () = unsafe { + assert!(*C2 == 0); //~ERROR evaluation of constant value failed + //~^ constant accesses mutable global memory +}; + +fn main() { +} diff --git a/tests/ui/consts/const_refs_to_static_fail.stderr b/tests/ui/consts/const_refs_to_static_fail.stderr new file mode 100644 index 0000000000000..d27aebc5c1268 --- /dev/null +++ b/tests/ui/consts/const_refs_to_static_fail.stderr @@ -0,0 +1,15 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/const_refs_to_static_fail.rs:9:13 + | +LL | assert!(*C1.get() == 0); + | ^^^^^^^^^ constant accesses mutable global memory + +error[E0080]: evaluation of constant value failed + --> $DIR/const_refs_to_static_fail.rs:14:13 + | +LL | assert!(*C2 == 0); + | ^^^ constant accesses mutable global memory + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const_refs_to_static_fail_pattern.rs b/tests/ui/consts/const_refs_to_static_fail_pattern.rs new file mode 100644 index 0000000000000..21dc08066a24a --- /dev/null +++ b/tests/ui/consts/const_refs_to_static_fail_pattern.rs @@ -0,0 +1,15 @@ +#![feature(const_refs_to_static)] + +static mut S_MUT: i32 = 0; + +const C: &i32 = unsafe { &S_MUT }; +//~^ERROR: constant refers to mutable data + +fn main() { + // This *must not build*, the constant we are matching against + // could change its value! + match &42 { + C => {}, //~ERROR: could not evaluate constant pattern + _ => {}, + } +} diff --git a/tests/ui/consts/const_refs_to_static_fail_pattern.stderr b/tests/ui/consts/const_refs_to_static_fail_pattern.stderr new file mode 100644 index 0000000000000..d6697b8782667 --- /dev/null +++ b/tests/ui/consts/const_refs_to_static_fail_pattern.stderr @@ -0,0 +1,14 @@ +error: constant refers to mutable data + --> $DIR/const_refs_to_static_fail_pattern.rs:5:1 + | +LL | const C: &i32 = unsafe { &S_MUT }; + | ^^^^^^^^^^^^^ + +error: could not evaluate constant pattern + --> $DIR/const_refs_to_static_fail_pattern.rs:12:9 + | +LL | C => {}, + | ^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/consts/issue-17718-const-bad-values.rs b/tests/ui/consts/issue-17718-const-bad-values.rs index 4fedc48452bec..af50fed972df8 100644 --- a/tests/ui/consts/issue-17718-const-bad-values.rs +++ b/tests/ui/consts/issue-17718-const-bad-values.rs @@ -3,8 +3,8 @@ const C1: &'static mut [usize] = &mut []; static mut S: usize = 3; const C2: &'static mut usize = unsafe { &mut S }; -//~^ WARN mutable reference of mutable static is discouraged [static_mut_ref] -//~^^ ERROR: constants cannot refer to statics -//~| ERROR: constants cannot refer to statics +//~^ ERROR: referencing statics in constants +//~| ERROR: referencing statics in constants +//~| WARN mutable reference of mutable static is discouraged [static_mut_ref] fn main() {} diff --git a/tests/ui/consts/issue-17718-const-bad-values.stderr b/tests/ui/consts/issue-17718-const-bad-values.stderr index 2dc91f52669e7..248cd999bb620 100644 --- a/tests/ui/consts/issue-17718-const-bad-values.stderr +++ b/tests/ui/consts/issue-17718-const-bad-values.stderr @@ -19,24 +19,30 @@ error[E0764]: mutable references are not allowed in the final value of constants LL | const C1: &'static mut [usize] = &mut []; | ^^^^^^^ -error[E0013]: constants cannot refer to statics +error[E0658]: referencing statics in constants is unstable --> $DIR/issue-17718-const-bad-values.rs:5:46 | LL | const C2: &'static mut usize = unsafe { &mut S }; | ^ | - = help: consider extracting the value of the `static` to a `const`, and referring to that + = note: see issue #119618 for more information + = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. + = help: to fix this, the value can be extracted to a `const` and then used. -error[E0013]: constants cannot refer to statics +error[E0658]: referencing statics in constants is unstable --> $DIR/issue-17718-const-bad-values.rs:5:46 | LL | const C2: &'static mut usize = unsafe { &mut S }; | ^ | - = help: consider extracting the value of the `static` to a `const`, and referring to that + = note: see issue #119618 for more information + = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. + = help: to fix this, the value can be extracted to a `const` and then used. = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 3 previous errors; 1 warning emitted -Some errors have detailed explanations: E0013, E0764. -For more information about an error, try `rustc --explain E0013`. +Some errors have detailed explanations: E0658, E0764. +For more information about an error, try `rustc --explain E0658`. diff --git a/tests/ui/consts/issue-17718-references.rs b/tests/ui/consts/issue-17718-references.rs index 03d5f8bb3f1c9..6a8955f463433 100644 --- a/tests/ui/consts/issue-17718-references.rs +++ b/tests/ui/consts/issue-17718-references.rs @@ -6,18 +6,18 @@ const C: usize = 1; static S: usize = 1; const T1: &'static usize = &C; -const T2: &'static usize = &S; //~ ERROR: constants cannot refer to statics +const T2: &'static usize = &S; //~ ERROR: referencing statics in constants static T3: &'static usize = &C; static T4: &'static usize = &S; const T5: usize = C; -const T6: usize = S; //~ ERROR: constants cannot refer to statics +const T6: usize = S; //~ ERROR: referencing statics in constants static T7: usize = C; static T8: usize = S; const T9: Struct = Struct { a: C }; const T10: Struct = Struct { a: S }; -//~^ ERROR: constants cannot refer to statics +//~^ ERROR: referencing statics in constants static T11: Struct = Struct { a: C }; static T12: Struct = Struct { a: S }; diff --git a/tests/ui/consts/issue-17718-references.stderr b/tests/ui/consts/issue-17718-references.stderr index e3c3b369ffb32..4e5a44f6b6efd 100644 --- a/tests/ui/consts/issue-17718-references.stderr +++ b/tests/ui/consts/issue-17718-references.stderr @@ -1,27 +1,36 @@ -error[E0013]: constants cannot refer to statics +error[E0658]: referencing statics in constants is unstable --> $DIR/issue-17718-references.rs:9:29 | LL | const T2: &'static usize = &S; | ^ | - = help: consider extracting the value of the `static` to a `const`, and referring to that + = note: see issue #119618 for more information + = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. + = help: to fix this, the value can be extracted to a `const` and then used. -error[E0013]: constants cannot refer to statics +error[E0658]: referencing statics in constants is unstable --> $DIR/issue-17718-references.rs:14:19 | LL | const T6: usize = S; | ^ | - = help: consider extracting the value of the `static` to a `const`, and referring to that + = note: see issue #119618 for more information + = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. + = help: to fix this, the value can be extracted to a `const` and then used. -error[E0013]: constants cannot refer to statics +error[E0658]: referencing statics in constants is unstable --> $DIR/issue-17718-references.rs:19:33 | LL | const T10: Struct = Struct { a: S }; | ^ | - = help: consider extracting the value of the `static` to a `const`, and referring to that + = note: see issue #119618 for more information + = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. + = help: to fix this, the value can be extracted to a `const` and then used. error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0013`. +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/consts/issue-52060.rs b/tests/ui/consts/issue-52060.rs index 13b914c0331d1..0f16ede040010 100644 --- a/tests/ui/consts/issue-52060.rs +++ b/tests/ui/consts/issue-52060.rs @@ -2,6 +2,6 @@ // The compiler shouldn't ICE in this case static A: &'static [u32] = &[1]; static B: [u32; 1] = [0; A.len()]; -//~^ ERROR [E0013] +//~^ ERROR referencing statics in constants fn main() {} diff --git a/tests/ui/consts/issue-52060.stderr b/tests/ui/consts/issue-52060.stderr index 27d00ad044259..9d5dff1ef2276 100644 --- a/tests/ui/consts/issue-52060.stderr +++ b/tests/ui/consts/issue-52060.stderr @@ -1,11 +1,14 @@ -error[E0013]: constants cannot refer to statics +error[E0658]: referencing statics in constants is unstable --> $DIR/issue-52060.rs:4:26 | LL | static B: [u32; 1] = [0; A.len()]; | ^ | - = help: consider extracting the value of the `static` to a `const`, and referring to that + = note: see issue #119618 for more information + = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. + = help: to fix this, the value can be extracted to a `const` and then used. error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0013`. +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/consts/min_const_fn/min_const_fn.rs b/tests/ui/consts/min_const_fn/min_const_fn.rs index c2891488c7f1b..76245c08ffc8c 100644 --- a/tests/ui/consts/min_const_fn/min_const_fn.rs +++ b/tests/ui/consts/min_const_fn/min_const_fn.rs @@ -86,8 +86,8 @@ const fn foo11_2(t: T) -> T { t } // not ok static BAR: u32 = 42; -const fn foo25() -> u32 { BAR } //~ ERROR cannot refer to statics -const fn foo26() -> &'static u32 { &BAR } //~ ERROR cannot refer to statics +const fn foo25() -> u32 { BAR } //~ ERROR referencing statics in constant functions +const fn foo26() -> &'static u32 { &BAR } //~ ERROR referencing statics in constant functions const fn foo30(x: *const u32) -> usize { x as usize } //~^ ERROR pointers cannot be cast to integers const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } } diff --git a/tests/ui/consts/min_const_fn/min_const_fn.stderr b/tests/ui/consts/min_const_fn/min_const_fn.stderr index d646c7de8da7b..64b13e941a527 100644 --- a/tests/ui/consts/min_const_fn/min_const_fn.stderr +++ b/tests/ui/consts/min_const_fn/min_const_fn.stderr @@ -142,21 +142,27 @@ LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 } = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0013]: constant functions cannot refer to statics +error[E0658]: referencing statics in constant functions is unstable --> $DIR/min_const_fn.rs:89:27 | LL | const fn foo25() -> u32 { BAR } | ^^^ | - = help: consider extracting the value of the `static` to a `const`, and referring to that + = note: see issue #119618 for more information + = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. + = help: to fix this, the value can be extracted to a `const` and then used. -error[E0013]: constant functions cannot refer to statics +error[E0658]: referencing statics in constant functions is unstable --> $DIR/min_const_fn.rs:90:37 | LL | const fn foo26() -> &'static u32 { &BAR } | ^^^ | - = help: consider extracting the value of the `static` to a `const`, and referring to that + = note: see issue #119618 for more information + = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. + = help: to fix this, the value can be extracted to a `const` and then used. error: pointers cannot be cast to integers during const eval --> $DIR/min_const_fn.rs:91:42 @@ -222,5 +228,5 @@ LL | const fn no_apit(_x: impl std::fmt::Debug) {} error: aborting due to 24 previous errors -Some errors have detailed explanations: E0013, E0493, E0658. -For more information about an error, try `rustc --explain E0013`. +Some errors have detailed explanations: E0493, E0658. +For more information about an error, try `rustc --explain E0493`. diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static.32bit.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static.32bit.stderr index 5fe8e250df912..2e2e97dde0e65 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static.32bit.stderr +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static.32bit.stderr @@ -8,50 +8,17 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_refers_to_static.rs:14:14 | LL | unsafe { *(&FOO as *const _ as *const usize) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses mutable global memory error[E0080]: evaluation of constant value failed --> $DIR/const_refers_to_static.rs:18:32 | LL | const READ_MUT: u32 = unsafe { MUTABLE }; - | ^^^^^^^ constant accesses static - -error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refers_to_static.rs:20:1 - | -LL | const REF_INTERIOR_MUT: &usize = { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant - | - = 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. - = note: the raw bytes of the constant (size: 4, align: 4) { - ╾ALLOC0╼ │ ╾──╼ - } - -error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refers_to_static.rs:27:1 - | -LL | const READ_IMMUT: &usize = { - | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant - | - = 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. - = note: the raw bytes of the constant (size: 4, align: 4) { - ╾ALLOC1╼ │ ╾──╼ - } - -error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refers_to_static.rs:34:1 - | -LL | const REF_IMMUT: &u8 = &MY_STATIC; - | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant - | - = 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. - = note: the raw bytes of the constant (size: 4, align: 4) { - ╾ALLOC2╼ │ ╾──╼ - } + | ^^^^^^^ constant accesses mutable global memory warning: skipping const checks | -help: skipping check that does not even have a feature gate +help: skipping check for `const_refs_to_static` feature --> $DIR/const_refers_to_static.rs:9:5 | LL | FOO.fetch_add(1, Ordering::Relaxed) @@ -61,37 +28,32 @@ help: skipping check that does not even have a feature gate | LL | FOO.fetch_add(1, Ordering::Relaxed) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate +help: skipping check for `const_refs_to_static` feature --> $DIR/const_refers_to_static.rs:14:17 | LL | unsafe { *(&FOO as *const _ as *const usize) } | ^^^ -help: skipping check that does not even have a feature gate +help: skipping check for `const_refs_to_static` feature --> $DIR/const_refers_to_static.rs:18:32 | LL | const READ_MUT: u32 = unsafe { MUTABLE }; | ^^^^^^^ -help: skipping check that does not even have a feature gate +help: skipping check for `const_refs_to_static` feature --> $DIR/const_refers_to_static.rs:18:32 | LL | const READ_MUT: u32 = unsafe { MUTABLE }; | ^^^^^^^ -help: skipping check that does not even have a feature gate +help: skipping check for `const_refs_to_static` feature --> $DIR/const_refers_to_static.rs:23:18 | LL | unsafe { &*(&FOO as *const _ as *const usize) } | ^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static.rs:30:6 - | -LL | &FOO - | ^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static.rs:34:25 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static.rs:27:25 | LL | const REF_IMMUT: &u8 = &MY_STATIC; | ^^^^^^^^^ -error: aborting due to 6 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static.64bit.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static.64bit.stderr index a80b07056a30f..2e2e97dde0e65 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static.64bit.stderr +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static.64bit.stderr @@ -8,50 +8,17 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_refers_to_static.rs:14:14 | LL | unsafe { *(&FOO as *const _ as *const usize) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses mutable global memory error[E0080]: evaluation of constant value failed --> $DIR/const_refers_to_static.rs:18:32 | LL | const READ_MUT: u32 = unsafe { MUTABLE }; - | ^^^^^^^ constant accesses static - -error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refers_to_static.rs:20:1 - | -LL | const REF_INTERIOR_MUT: &usize = { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant - | - = 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. - = note: the raw bytes of the constant (size: 8, align: 8) { - ╾ALLOC0╼ │ ╾──────╼ - } - -error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refers_to_static.rs:27:1 - | -LL | const READ_IMMUT: &usize = { - | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant - | - = 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. - = note: the raw bytes of the constant (size: 8, align: 8) { - ╾ALLOC1╼ │ ╾──────╼ - } - -error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refers_to_static.rs:34:1 - | -LL | const REF_IMMUT: &u8 = &MY_STATIC; - | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant - | - = 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. - = note: the raw bytes of the constant (size: 8, align: 8) { - ╾ALLOC2╼ │ ╾──────╼ - } + | ^^^^^^^ constant accesses mutable global memory warning: skipping const checks | -help: skipping check that does not even have a feature gate +help: skipping check for `const_refs_to_static` feature --> $DIR/const_refers_to_static.rs:9:5 | LL | FOO.fetch_add(1, Ordering::Relaxed) @@ -61,37 +28,32 @@ help: skipping check that does not even have a feature gate | LL | FOO.fetch_add(1, Ordering::Relaxed) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate +help: skipping check for `const_refs_to_static` feature --> $DIR/const_refers_to_static.rs:14:17 | LL | unsafe { *(&FOO as *const _ as *const usize) } | ^^^ -help: skipping check that does not even have a feature gate +help: skipping check for `const_refs_to_static` feature --> $DIR/const_refers_to_static.rs:18:32 | LL | const READ_MUT: u32 = unsafe { MUTABLE }; | ^^^^^^^ -help: skipping check that does not even have a feature gate +help: skipping check for `const_refs_to_static` feature --> $DIR/const_refers_to_static.rs:18:32 | LL | const READ_MUT: u32 = unsafe { MUTABLE }; | ^^^^^^^ -help: skipping check that does not even have a feature gate +help: skipping check for `const_refs_to_static` feature --> $DIR/const_refers_to_static.rs:23:18 | LL | unsafe { &*(&FOO as *const _ as *const usize) } | ^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static.rs:30:6 - | -LL | &FOO - | ^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static.rs:34:25 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static.rs:27:25 | LL | const REF_IMMUT: &u8 = &MY_STATIC; | ^^^^^^^^^ -error: aborting due to 6 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static.rs b/tests/ui/consts/miri_unleashed/const_refers_to_static.rs index df2563d8d7f2d..d426d7eb184f1 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static.rs +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static.rs @@ -17,22 +17,14 @@ const READ_INTERIOR_MUT: usize = { static mut MUTABLE: u32 = 0; const READ_MUT: u32 = unsafe { MUTABLE }; //~ERROR evaluation of constant value failed -const REF_INTERIOR_MUT: &usize = { //~ ERROR undefined behavior to use this value -//~| encountered a reference pointing to a static variable +// Not actually reading from anything mutable, so these are fine. +const REF_INTERIOR_MUT: &usize = { static FOO: AtomicUsize = AtomicUsize::new(0); unsafe { &*(&FOO as *const _ as *const usize) } }; -// ok some day perhaps -const READ_IMMUT: &usize = { //~ ERROR it is undefined behavior to use this value -//~| encountered a reference pointing to a static variable - static FOO: usize = 0; - &FOO -}; - static MY_STATIC: u8 = 4; const REF_IMMUT: &u8 = &MY_STATIC; -//~^ ERROR it is undefined behavior to use this value -//~| encountered a reference pointing to a static variable +const READ_IMMUT: u8 = *REF_IMMUT; fn main() {} diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr index ed9db67542641..682b53edf6fa3 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr @@ -1,5 +1,5 @@ warning: shared reference of mutable static is discouraged - --> $DIR/const_refers_to_static_cross_crate.rs:13:14 + --> $DIR/const_refers_to_static_cross_crate.rs:11:14 | LL | unsafe { &static_cross_crate::ZERO } | ^^^^^^^^^^^^^^^^^^^^^^^^^ shared reference of mutable static @@ -13,118 +13,108 @@ help: shared references are dangerous since if there's any kind of mutation of t LL | unsafe { addr_of!(static_cross_crate::ZERO) } | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -error[E0080]: it is undefined behavior to use this value +error: constant refers to mutable data --> $DIR/const_refers_to_static_cross_crate.rs:10:1 | LL | const SLICE_MUT: &[u8; 1] = { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant - | - = 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. - = note: the raw bytes of the constant (size: 4, align: 4) { - ╾ALLOC0╼ │ ╾──╼ - } + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:42:9 + --> $DIR/const_refers_to_static_cross_crate.rs:36:9 | LL | SLICE_MUT => true, | ^^^^^^^^^ -error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refers_to_static_cross_crate.rs:17:1 +error: constant refers to mutable data + --> $DIR/const_refers_to_static_cross_crate.rs:15:1 | LL | const U8_MUT: &u8 = { - | ^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant - | - = 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. - = note: the raw bytes of the constant (size: 4, align: 4) { - ╾ALLOC0╼ │ ╾──╼ - } + | ^^^^^^^^^^^^^^^^^ error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:50:9 + --> $DIR/const_refers_to_static_cross_crate.rs:44:9 | LL | U8_MUT => true, | ^^^^^^ -error[E0080]: evaluation of constant value failed - --> $DIR/const_refers_to_static_cross_crate.rs:25:15 +error: constant refers to mutable data + --> $DIR/const_refers_to_static_cross_crate.rs:20:1 | -LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static +LL | const U8_MUT2: &u8 = { + | ^^^^^^^^^^^^^^^^^^ error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:60:9 + --> $DIR/const_refers_to_static_cross_crate.rs:54:9 | LL | U8_MUT2 => true, | ^^^^^^^ error[E0080]: evaluation of constant value failed - --> $DIR/const_refers_to_static_cross_crate.rs:31:15 + --> $DIR/const_refers_to_static_cross_crate.rs:25:15 | LL | match static_cross_crate::OPT_ZERO { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses mutable global memory error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:67:9 + --> $DIR/const_refers_to_static_cross_crate.rs:61:9 | LL | U8_MUT3 => true, | ^^^^^^^ warning: skipping const checks | -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:13:15 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static_cross_crate.rs:11:15 | LL | unsafe { &static_cross_crate::ZERO } | ^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:13:15 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static_cross_crate.rs:11:15 | LL | unsafe { &static_cross_crate::ZERO } | ^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:20:15 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static_cross_crate.rs:16:15 | LL | unsafe { &static_cross_crate::ZERO[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:20:15 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static_cross_crate.rs:16:15 | LL | unsafe { &static_cross_crate::ZERO[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:20:15 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static_cross_crate.rs:16:15 | LL | unsafe { &static_cross_crate::ZERO[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:25:17 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static_cross_crate.rs:21:17 | LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:31:15 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static_cross_crate.rs:25:15 | LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:31:15 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static_cross_crate.rs:25:15 | LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:31:15 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static_cross_crate.rs:25:15 | LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:31:15 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static_cross_crate.rs:25:15 | LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:31:15 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static_cross_crate.rs:25:15 | LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr index 275323bc286c0..682b53edf6fa3 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr @@ -1,5 +1,5 @@ warning: shared reference of mutable static is discouraged - --> $DIR/const_refers_to_static_cross_crate.rs:13:14 + --> $DIR/const_refers_to_static_cross_crate.rs:11:14 | LL | unsafe { &static_cross_crate::ZERO } | ^^^^^^^^^^^^^^^^^^^^^^^^^ shared reference of mutable static @@ -13,118 +13,108 @@ help: shared references are dangerous since if there's any kind of mutation of t LL | unsafe { addr_of!(static_cross_crate::ZERO) } | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -error[E0080]: it is undefined behavior to use this value +error: constant refers to mutable data --> $DIR/const_refers_to_static_cross_crate.rs:10:1 | LL | const SLICE_MUT: &[u8; 1] = { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant - | - = 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. - = note: the raw bytes of the constant (size: 8, align: 8) { - ╾ALLOC0╼ │ ╾──────╼ - } + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:42:9 + --> $DIR/const_refers_to_static_cross_crate.rs:36:9 | LL | SLICE_MUT => true, | ^^^^^^^^^ -error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refers_to_static_cross_crate.rs:17:1 +error: constant refers to mutable data + --> $DIR/const_refers_to_static_cross_crate.rs:15:1 | LL | const U8_MUT: &u8 = { - | ^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant - | - = 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. - = note: the raw bytes of the constant (size: 8, align: 8) { - ╾ALLOC0╼ │ ╾──────╼ - } + | ^^^^^^^^^^^^^^^^^ error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:50:9 + --> $DIR/const_refers_to_static_cross_crate.rs:44:9 | LL | U8_MUT => true, | ^^^^^^ -error[E0080]: evaluation of constant value failed - --> $DIR/const_refers_to_static_cross_crate.rs:25:15 +error: constant refers to mutable data + --> $DIR/const_refers_to_static_cross_crate.rs:20:1 | -LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static +LL | const U8_MUT2: &u8 = { + | ^^^^^^^^^^^^^^^^^^ error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:60:9 + --> $DIR/const_refers_to_static_cross_crate.rs:54:9 | LL | U8_MUT2 => true, | ^^^^^^^ error[E0080]: evaluation of constant value failed - --> $DIR/const_refers_to_static_cross_crate.rs:31:15 + --> $DIR/const_refers_to_static_cross_crate.rs:25:15 | LL | match static_cross_crate::OPT_ZERO { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses mutable global memory error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:67:9 + --> $DIR/const_refers_to_static_cross_crate.rs:61:9 | LL | U8_MUT3 => true, | ^^^^^^^ warning: skipping const checks | -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:13:15 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static_cross_crate.rs:11:15 | LL | unsafe { &static_cross_crate::ZERO } | ^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:13:15 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static_cross_crate.rs:11:15 | LL | unsafe { &static_cross_crate::ZERO } | ^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:20:15 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static_cross_crate.rs:16:15 | LL | unsafe { &static_cross_crate::ZERO[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:20:15 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static_cross_crate.rs:16:15 | LL | unsafe { &static_cross_crate::ZERO[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:20:15 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static_cross_crate.rs:16:15 | LL | unsafe { &static_cross_crate::ZERO[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:25:17 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static_cross_crate.rs:21:17 | LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:31:15 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static_cross_crate.rs:25:15 | LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:31:15 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static_cross_crate.rs:25:15 | LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:31:15 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static_cross_crate.rs:25:15 | LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:31:15 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static_cross_crate.rs:25:15 | LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:31:15 +help: skipping check for `const_refs_to_static` feature + --> $DIR/const_refers_to_static_cross_crate.rs:25:15 | LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs index 3eafa58d9f9fd..7c10a3fd19c62 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs @@ -7,30 +7,24 @@ extern crate static_cross_crate; // Sneaky: reference to a mutable static. // Allowing this would be a disaster for pattern matching, we could violate exhaustiveness checking! -const SLICE_MUT: &[u8; 1] = { - //~^ ERROR undefined behavior to use this value - //~| encountered a reference pointing to a static variable +const SLICE_MUT: &[u8; 1] = { //~ ERROR constant refers to mutable data unsafe { &static_cross_crate::ZERO } //~^ WARN shared reference of mutable static is discouraged [static_mut_ref] }; -const U8_MUT: &u8 = { - //~^ ERROR undefined behavior to use this value - //~| encountered a reference pointing to a static variable +const U8_MUT: &u8 = { //~ ERROR constant refers to mutable data unsafe { &static_cross_crate::ZERO[0] } }; // Also test indirection that reads from other static. -const U8_MUT2: &u8 = { +const U8_MUT2: &u8 = { //~ ERROR constant refers to mutable data unsafe { &(*static_cross_crate::ZERO_REF)[0] } - //~^ ERROR evaluation of constant value failed - //~| constant accesses static }; const U8_MUT3: &u8 = { unsafe { match static_cross_crate::OPT_ZERO { //~^ ERROR evaluation of constant value failed - //~| constant accesses static + //~| constant accesses mutable global memory Some(ref u) => u, None => panic!(), } diff --git a/tests/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr b/tests/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr index 4793466a98784..59cde74db97b3 100644 --- a/tests/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr +++ b/tests/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr @@ -38,55 +38,50 @@ LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const ╾ALLOC1╼ │ ╾──╼ } -error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references_err.rs:47:1 - | -LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant +error[E0080]: evaluation of constant value failed + --> $DIR/mutable_references_err.rs:48:33 | - = 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. - = note: the raw bytes of the constant (size: 4, align: 4) { - ╾ALLOC2╼ │ ╾──╼ - } +LL | const READS_FROM_MUTABLE: i32 = *POINTS_TO_MUTABLE1; + | ^^^^^^^^^^^^^^^^^^^ constant accesses mutable global memory error[E0080]: evaluation of constant value failed - --> $DIR/mutable_references_err.rs:51:43 + --> $DIR/mutable_references_err.rs:52:43 | LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF }; - | ^^^^^^^^^^^^^ constant accesses static + | ^^^^^^^^^^^^^ constant accesses mutable global memory error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:55:1 + --> $DIR/mutable_references_err.rs:56:1 | LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:57:1 + --> $DIR/mutable_references_err.rs:58:1 | LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:59:1 + --> $DIR/mutable_references_err.rs:60:1 | LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:69:1 + --> $DIR/mutable_references_err.rs:70:1 | LL | const RAW_SYNC: SyncPtr = SyncPtr { x: &AtomicI32::new(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:71:1 + --> $DIR/mutable_references_err.rs:72:1 | LL | const RAW_MUT_CAST: SyncPtr = SyncPtr { x : &mut 42 as *mut _ as *const _ }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:73:1 + --> $DIR/mutable_references_err.rs:74:1 | LL | const RAW_MUT_COERCE: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -103,12 +98,12 @@ help: skipping check that does not even have a feature gate | LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate +help: skipping check for `const_refs_to_static` feature --> $DIR/mutable_references_err.rs:32:40 | LL | const SUBTLE: &mut i32 = unsafe { &mut FOO }; | ^^^ -help: skipping check that does not even have a feature gate +help: skipping check for `const_refs_to_static` feature --> $DIR/mutable_references_err.rs:32:40 | LL | const SUBTLE: &mut i32 = unsafe { &mut FOO }; @@ -133,53 +128,53 @@ help: skipping check for `const_mut_refs` feature | LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate +help: skipping check for `const_refs_to_static` feature --> $DIR/mutable_references_err.rs:47:44 | LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE }; | ^^^^^^^ -help: skipping check that does not even have a feature gate +help: skipping check for `const_refs_to_static` feature --> $DIR/mutable_references_err.rs:47:44 | LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE }; | ^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:51:45 +help: skipping check for `const_refs_to_static` feature + --> $DIR/mutable_references_err.rs:52:45 | LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF }; | ^^^^^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:51:45 +help: skipping check for `const_refs_to_static` feature + --> $DIR/mutable_references_err.rs:52:45 | LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF }; | ^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:55:45 + --> $DIR/mutable_references_err.rs:56:45 | LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:57:46 + --> $DIR/mutable_references_err.rs:58:46 | LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:59:47 + --> $DIR/mutable_references_err.rs:60:47 | LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _; | ^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:69:51 + --> $DIR/mutable_references_err.rs:70:51 | LL | const RAW_SYNC: SyncPtr = SyncPtr { x: &AtomicI32::new(42) }; | ^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:71:50 + --> $DIR/mutable_references_err.rs:72:50 | LL | const RAW_MUT_CAST: SyncPtr = SyncPtr { x : &mut 42 as *mut _ as *const _ }; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:73:51 + --> $DIR/mutable_references_err.rs:74:51 | LL | const RAW_MUT_COERCE: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^ diff --git a/tests/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr b/tests/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr index f5f7b605c9416..ff7678b1555b7 100644 --- a/tests/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr +++ b/tests/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr @@ -38,55 +38,50 @@ LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const ╾ALLOC1╼ │ ╾──────╼ } -error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references_err.rs:47:1 - | -LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant +error[E0080]: evaluation of constant value failed + --> $DIR/mutable_references_err.rs:48:33 | - = 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. - = note: the raw bytes of the constant (size: 8, align: 8) { - ╾ALLOC2╼ │ ╾──────╼ - } +LL | const READS_FROM_MUTABLE: i32 = *POINTS_TO_MUTABLE1; + | ^^^^^^^^^^^^^^^^^^^ constant accesses mutable global memory error[E0080]: evaluation of constant value failed - --> $DIR/mutable_references_err.rs:51:43 + --> $DIR/mutable_references_err.rs:52:43 | LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF }; - | ^^^^^^^^^^^^^ constant accesses static + | ^^^^^^^^^^^^^ constant accesses mutable global memory error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:55:1 + --> $DIR/mutable_references_err.rs:56:1 | LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:57:1 + --> $DIR/mutable_references_err.rs:58:1 | LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:59:1 + --> $DIR/mutable_references_err.rs:60:1 | LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:69:1 + --> $DIR/mutable_references_err.rs:70:1 | LL | const RAW_SYNC: SyncPtr = SyncPtr { x: &AtomicI32::new(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:71:1 + --> $DIR/mutable_references_err.rs:72:1 | LL | const RAW_MUT_CAST: SyncPtr = SyncPtr { x : &mut 42 as *mut _ as *const _ }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:73:1 + --> $DIR/mutable_references_err.rs:74:1 | LL | const RAW_MUT_COERCE: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -103,12 +98,12 @@ help: skipping check that does not even have a feature gate | LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate +help: skipping check for `const_refs_to_static` feature --> $DIR/mutable_references_err.rs:32:40 | LL | const SUBTLE: &mut i32 = unsafe { &mut FOO }; | ^^^ -help: skipping check that does not even have a feature gate +help: skipping check for `const_refs_to_static` feature --> $DIR/mutable_references_err.rs:32:40 | LL | const SUBTLE: &mut i32 = unsafe { &mut FOO }; @@ -133,53 +128,53 @@ help: skipping check for `const_mut_refs` feature | LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate +help: skipping check for `const_refs_to_static` feature --> $DIR/mutable_references_err.rs:47:44 | LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE }; | ^^^^^^^ -help: skipping check that does not even have a feature gate +help: skipping check for `const_refs_to_static` feature --> $DIR/mutable_references_err.rs:47:44 | LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE }; | ^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:51:45 +help: skipping check for `const_refs_to_static` feature + --> $DIR/mutable_references_err.rs:52:45 | LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF }; | ^^^^^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:51:45 +help: skipping check for `const_refs_to_static` feature + --> $DIR/mutable_references_err.rs:52:45 | LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF }; | ^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:55:45 + --> $DIR/mutable_references_err.rs:56:45 | LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:57:46 + --> $DIR/mutable_references_err.rs:58:46 | LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:59:47 + --> $DIR/mutable_references_err.rs:60:47 | LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _; | ^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:69:51 + --> $DIR/mutable_references_err.rs:70:51 | LL | const RAW_SYNC: SyncPtr = SyncPtr { x: &AtomicI32::new(42) }; | ^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:71:50 + --> $DIR/mutable_references_err.rs:72:50 | LL | const RAW_MUT_CAST: SyncPtr = SyncPtr { x : &mut 42 as *mut _ as *const _ }; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:73:51 + --> $DIR/mutable_references_err.rs:74:51 | LL | const RAW_MUT_COERCE: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^ diff --git a/tests/ui/consts/miri_unleashed/mutable_references_err.rs b/tests/ui/consts/miri_unleashed/mutable_references_err.rs index 83a460dadd0ef..d0a79ff7bbc73 100644 --- a/tests/ui/consts/miri_unleashed/mutable_references_err.rs +++ b/tests/ui/consts/miri_unleashed/mutable_references_err.rs @@ -42,15 +42,16 @@ static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as //~| pointing to read-only memory // Check for consts pointing to mutable memory. -// Currently it's not even possible to create such a const. +// These are fine as long as they are not being read. static mut MUTABLE: i32 = 42; const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE }; -//~^ ERROR: undefined behavior to use this value -//~| pointing to a static +const READS_FROM_MUTABLE: i32 = *POINTS_TO_MUTABLE1; +//~^ ERROR: evaluation of constant value failed +//~| accesses mutable global memory static mut MUTABLE_REF: &mut i32 = &mut 42; const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF }; //~^ ERROR: evaluation of constant value failed -//~| accesses static +//~| accesses mutable global memory const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _; //~^ ERROR: mutable pointer in final value diff --git a/tests/ui/error-codes/E0013.rs b/tests/ui/error-codes/E0013.rs deleted file mode 100644 index 9b3982a785b7f..0000000000000 --- a/tests/ui/error-codes/E0013.rs +++ /dev/null @@ -1,4 +0,0 @@ -static X: i32 = 42; -const Y: i32 = X; //~ ERROR constants cannot refer to statics [E0013] - -fn main() {} diff --git a/tests/ui/error-codes/E0013.stderr b/tests/ui/error-codes/E0013.stderr deleted file mode 100644 index b07c8bdb700fe..0000000000000 --- a/tests/ui/error-codes/E0013.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0013]: constants cannot refer to statics - --> $DIR/E0013.rs:2:16 - | -LL | const Y: i32 = X; - | ^ - | - = help: consider extracting the value of the `static` to a `const`, and referring to that - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0013`. diff --git a/tests/ui/feature-gates/feature-gate-const-refs-to-static.rs b/tests/ui/feature-gates/feature-gate-const-refs-to-static.rs new file mode 100644 index 0000000000000..c020bb37a9999 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-const-refs-to-static.rs @@ -0,0 +1,12 @@ +static S: i32 = 0; +static mut S_MUT: i32 = 0; + +const C1: &i32 = &S; //~ERROR: referencing statics in constants is unstable +const C1_READ: () = { + assert!(*C1 == 0); +}; +const C2: *const i32 = unsafe { std::ptr::addr_of!(S_MUT) }; //~ERROR: referencing statics in constants is unstable +//~^ERROR: referencing statics in constants is unstable + +fn main() { +} diff --git a/tests/ui/feature-gates/feature-gate-const-refs-to-static.stderr b/tests/ui/feature-gates/feature-gate-const-refs-to-static.stderr new file mode 100644 index 0000000000000..259e96e71dd58 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-const-refs-to-static.stderr @@ -0,0 +1,37 @@ +error[E0658]: referencing statics in constants is unstable + --> $DIR/feature-gate-const-refs-to-static.rs:4:19 + | +LL | const C1: &i32 = &S; + | ^ + | + = note: see issue #119618 for more information + = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. + = help: to fix this, the value can be extracted to a `const` and then used. + +error[E0658]: referencing statics in constants is unstable + --> $DIR/feature-gate-const-refs-to-static.rs:8:52 + | +LL | const C2: *const i32 = unsafe { std::ptr::addr_of!(S_MUT) }; + | ^^^^^ + | + = note: see issue #119618 for more information + = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. + = help: to fix this, the value can be extracted to a `const` and then used. + +error[E0658]: referencing statics in constants is unstable + --> $DIR/feature-gate-const-refs-to-static.rs:8:52 + | +LL | const C2: *const i32 = unsafe { std::ptr::addr_of!(S_MUT) }; + | ^^^^^ + | + = note: see issue #119618 for more information + = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. + = help: to fix this, the value can be extracted to a `const` and then used. + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/static/issue-18118-2.rs b/tests/ui/static/issue-18118-2.rs index f712a2eedb7e9..6c81eec7d7e4b 100644 --- a/tests/ui/static/issue-18118-2.rs +++ b/tests/ui/static/issue-18118-2.rs @@ -1,6 +1,6 @@ pub fn main() { const z: &'static isize = { static p: isize = 3; - &p //~ ERROR constants cannot refer to statics + &p //~ ERROR referencing statics }; } diff --git a/tests/ui/static/issue-18118-2.stderr b/tests/ui/static/issue-18118-2.stderr index 6231a276f9913..04604709c8a7b 100644 --- a/tests/ui/static/issue-18118-2.stderr +++ b/tests/ui/static/issue-18118-2.stderr @@ -1,11 +1,14 @@ -error[E0013]: constants cannot refer to statics +error[E0658]: referencing statics in constants is unstable --> $DIR/issue-18118-2.rs:4:10 | LL | &p | ^ | - = help: consider extracting the value of the `static` to a `const`, and referring to that + = note: see issue #119618 for more information + = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. + = help: to fix this, the value can be extracted to a `const` and then used. error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0013`. +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/thread-local/thread-local-static.rs b/tests/ui/thread-local/thread-local-static.rs index f5fb098489746..7b69ffed197a1 100644 --- a/tests/ui/thread-local/thread-local-static.rs +++ b/tests/ui/thread-local/thread-local-static.rs @@ -12,7 +12,7 @@ const fn g(x: &mut [u32; 8]) { //~^^ ERROR thread-local statics cannot be accessed //~| ERROR mutable references are not allowed //~| ERROR use of mutable static is unsafe - //~| constant functions cannot refer to statics + //~| referencing statics } fn main() {} diff --git a/tests/ui/thread-local/thread-local-static.stderr b/tests/ui/thread-local/thread-local-static.stderr index 59bd17b39d85e..46b6519c80b3b 100644 --- a/tests/ui/thread-local/thread-local-static.stderr +++ b/tests/ui/thread-local/thread-local-static.stderr @@ -37,13 +37,16 @@ error[E0625]: thread-local statics cannot be accessed at compile-time LL | std::mem::swap(x, &mut STATIC_VAR_2) | ^^^^^^^^^^^^ -error[E0013]: constant functions cannot refer to statics +error[E0658]: referencing statics in constant functions is unstable --> $DIR/thread-local-static.rs:10:28 | LL | std::mem::swap(x, &mut STATIC_VAR_2) | ^^^^^^^^^^^^ | - = help: consider extracting the value of the `static` to a `const`, and referring to that + = note: see issue #119618 for more information + = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. + = help: to fix this, the value can be extracted to a `const` and then used. error[E0658]: mutable references are not allowed in constant functions --> $DIR/thread-local-static.rs:10:23 @@ -57,5 +60,5 @@ LL | std::mem::swap(x, &mut STATIC_VAR_2) error: aborting due to 5 previous errors; 1 warning emitted -Some errors have detailed explanations: E0013, E0133, E0625, E0658. -For more information about an error, try `rustc --explain E0013`. +Some errors have detailed explanations: E0133, E0625, E0658. +For more information about an error, try `rustc --explain E0133`. From 9c0623fe8f2d19c1e29cf452a6ff3ed0e16a310a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 6 Jan 2024 13:48:48 +0100 Subject: [PATCH 2/5] validation: descend from consts into statics --- compiler/rustc_const_eval/messages.ftl | 6 +- .../rustc_const_eval/src/const_eval/mod.rs | 24 +++--- .../src/const_eval/valtrees.rs | 14 +--- compiler/rustc_const_eval/src/errors.rs | 10 +-- .../src/interpret/eval_context.rs | 42 +++++------ .../rustc_const_eval/src/interpret/mod.rs | 2 +- .../src/interpret/validity.rs | 73 ++++++++++--------- .../rustc_middle/src/mir/interpret/error.rs | 1 + .../src/const_prop_lint.rs | 7 +- src/tools/miri/src/diagnostics.rs | 6 +- tests/ui/consts/const_refs_to_static_fail.rs | 8 +- .../consts/const_refs_to_static_fail.stderr | 19 ++++- .../const_refs_to_static_fail_invalid.rs | 17 +++++ .../const_refs_to_static_fail_invalid.stderr | 20 +++++ .../const_refs_to_static_fail_pattern.rs | 5 +- .../const_refs_to_static_fail_pattern.stderr | 14 +++- .../const_refers_to_static.32bit.stderr | 17 ++++- .../const_refers_to_static.64bit.stderr | 17 ++++- .../miri_unleashed/const_refers_to_static.rs | 6 +- ..._refers_to_static_cross_crate.32bit.stderr | 65 ++++++++++------- ..._refers_to_static_cross_crate.64bit.stderr | 65 ++++++++++------- .../const_refers_to_static_cross_crate.rs | 9 ++- .../mutable_references_err.32bit.stderr | 47 +++++++----- .../mutable_references_err.64bit.stderr | 47 +++++++----- .../miri_unleashed/mutable_references_err.rs | 5 +- 25 files changed, 334 insertions(+), 212 deletions(-) create mode 100644 tests/ui/consts/const_refs_to_static_fail_invalid.rs create mode 100644 tests/ui/consts/const_refs_to_static_fail_invalid.stderr diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index d932bf3c2a25d..f8bb122c52c0f 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -215,9 +215,6 @@ const_eval_modified_global = const_eval_mut_deref = mutation through a reference is not allowed in {const_eval_const_context}s -const_eval_mutable_data_in_const = - constant refers to mutable data - const_eval_mutable_ptr_in_final = encountered mutable pointer in final value of {const_eval_intern_kind} const_eval_non_const_fmt_macro_call = @@ -414,6 +411,9 @@ const_eval_upcast_mismatch = ## (We'd love to sort this differently to make that more clear but tidy won't let us...) const_eval_validation_box_to_static = {$front_matter}: encountered a box pointing to a static variable in a constant const_eval_validation_box_to_uninhabited = {$front_matter}: encountered a box pointing to uninhabited type {$ty} + +const_eval_validation_const_ref_to_mutable = {$front_matter}: encountered reference to mutable memory in `const` + const_eval_validation_dangling_box_no_provenance = {$front_matter}: encountered a dangling box ({$pointer} has no provenance) const_eval_validation_dangling_box_out_of_bounds = {$front_matter}: encountered a dangling box (going beyond the bounds of its allocation) const_eval_validation_dangling_box_use_after_free = {$front_matter}: encountered a dangling box (use-after-free) diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 826b4b278ed61..cd50701040e82 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -1,11 +1,12 @@ // Not in interpret to make sure we do not use private implementation details -use crate::interpret::InterpCx; use rustc_middle::mir; -use rustc_middle::mir::interpret::{InterpError, InterpErrorInfo}; +use rustc_middle::mir::interpret::InterpErrorInfo; use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::{self, Ty}; +use crate::interpret::{format_interp_error, InterpCx}; + mod error; mod eval_queries; mod fn_queries; @@ -25,24 +26,17 @@ pub(crate) enum ValTreeCreationError { NodesOverflow, /// Values of this type, or this particular value, are not supported as valtrees. NonSupportedType, - /// The value pointed to non-read-only memory, so we cannot make it a valtree. - NotReadOnly, - Other, } pub(crate) type ValTreeCreationResult<'tcx> = Result, ValTreeCreationError>; impl From> for ValTreeCreationError { fn from(err: InterpErrorInfo<'_>) -> Self { - match err.kind() { - InterpError::MachineStop(err) => { - let err = err.downcast_ref::().unwrap(); - match err { - ConstEvalErrKind::ConstAccessesMutGlobal => ValTreeCreationError::NotReadOnly, - _ => ValTreeCreationError::Other, - } - } - _ => ValTreeCreationError::Other, - } + ty::tls::with(|tcx| { + bug!( + "Unexpected Undefined Behavior error during valtree construction: {}", + format_interp_error(tcx.dcx(), err), + ) + }) } } diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index 31fcdc9a3bd13..514a6a7df7617 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -9,7 +9,7 @@ use super::eval_queries::{mk_eval_cx, op_to_const}; use super::machine::CompileTimeEvalContext; use super::{ValTreeCreationError, ValTreeCreationResult, VALTREE_MAX_NODES}; use crate::const_eval::CanAccessMutGlobal; -use crate::errors::{MaxNumNodesInConstErr, MutableDataInConstErr}; +use crate::errors::MaxNumNodesInConstErr; use crate::interpret::MPlaceTy; use crate::interpret::{ intern_const_alloc_recursive, ImmTy, Immediate, InternKind, MemPlaceMeta, MemoryKind, PlaceTy, @@ -249,18 +249,6 @@ pub(crate) fn eval_to_valtree<'tcx>( tcx.dcx().emit_err(MaxNumNodesInConstErr { span, global_const_id }); Err(handled.into()) } - ValTreeCreationError::NotReadOnly => { - let handled = - tcx.dcx().emit_err(MutableDataInConstErr { span, global_const_id }); - Err(handled.into()) - } - ValTreeCreationError::Other => { - let handled = tcx.dcx().span_delayed_bug( - span.unwrap_or(DUMMY_SP), - "unexpected error during valtree construction", - ); - Err(handled.into()) - } ValTreeCreationError::NonSupportedType => Ok(None), } } diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 296329f5d1e78..fe72941bbabaf 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -117,14 +117,6 @@ pub(crate) struct MaxNumNodesInConstErr { pub global_const_id: String, } -#[derive(Diagnostic)] -#[diag(const_eval_mutable_data_in_const)] -pub(crate) struct MutableDataInConstErr { - #[primary_span] - pub span: Option, - pub global_const_id: String, -} - #[derive(Diagnostic)] #[diag(const_eval_unallowed_fn_pointer_call)] pub(crate) struct UnallowedFnPointerCall { @@ -619,6 +611,7 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { PointerAsInt { .. } => const_eval_validation_pointer_as_int, PartialPointer => const_eval_validation_partial_pointer, + ConstRefToMutable => const_eval_validation_const_ref_to_mutable, MutableRefInConst => const_eval_validation_mutable_ref_in_const, MutableRefToImmutable => const_eval_validation_mutable_ref_to_immutable, NullFnPtr => const_eval_validation_null_fn_ptr, @@ -773,6 +766,7 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { NullPtr { .. } | PtrToStatic { .. } | MutableRefInConst + | ConstRefToMutable | MutableRefToImmutable | NullFnPtr | NeverVal diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index dd989ab80fd3c..dd9dfe3fe7983 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -4,6 +4,7 @@ use std::{fmt, mem}; use either::{Either, Left, Right}; use hir::CRATE_HIR_ID; +use rustc_errors::DiagCtxt; use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData}; use rustc_index::IndexVec; use rustc_middle::mir; @@ -430,6 +431,26 @@ pub(super) fn from_known_layout<'tcx>( } } +/// Turn the given error into a human-readable string. Expects the string to be printed, so if +/// `RUSTC_CTFE_BACKTRACE` is set this will show a backtrace of the rustc internals that +/// triggered the error. +/// +/// This is NOT the preferred way to render an error; use `report` from `const_eval` instead. +/// However, this is useful when error messages appear in ICEs. +pub fn format_interp_error<'tcx>(dcx: &DiagCtxt, e: InterpErrorInfo<'tcx>) -> String { + let (e, backtrace) = e.into_parts(); + backtrace.print_backtrace(); + // FIXME(fee1-dead), HACK: we want to use the error as title therefore we can just extract the + // label and arguments from the InterpError. + #[allow(rustc::untranslatable_diagnostic)] + let mut diag = dcx.struct_allow(""); + let msg = e.diagnostic_message(); + e.add_args(dcx, &mut diag); + let s = dcx.eagerly_translate_to_string(msg, diag.args()); + diag.cancel(); + s +} + impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub fn new( tcx: TyCtxt<'tcx>, @@ -462,27 +483,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { .map_or(CRATE_HIR_ID, |def_id| self.tcx.local_def_id_to_hir_id(def_id)) } - /// Turn the given error into a human-readable string. Expects the string to be printed, so if - /// `RUSTC_CTFE_BACKTRACE` is set this will show a backtrace of the rustc internals that - /// triggered the error. - /// - /// This is NOT the preferred way to render an error; use `report` from `const_eval` instead. - /// However, this is useful when error messages appear in ICEs. - pub fn format_error(&self, e: InterpErrorInfo<'tcx>) -> String { - let (e, backtrace) = e.into_parts(); - backtrace.print_backtrace(); - // FIXME(fee1-dead), HACK: we want to use the error as title therefore we can just extract the - // label and arguments from the InterpError. - let dcx = self.tcx.dcx(); - #[allow(rustc::untranslatable_diagnostic)] - let mut diag = dcx.struct_allow(""); - let msg = e.diagnostic_message(); - e.add_args(dcx, &mut diag); - let s = dcx.eagerly_translate_to_string(msg, diag.args()); - diag.cancel(); - s - } - #[inline(always)] pub(crate) fn stack(&self) -> &[Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>] { M::stack(self) diff --git a/compiler/rustc_const_eval/src/interpret/mod.rs b/compiler/rustc_const_eval/src/interpret/mod.rs index 7d286d103adfe..c1b6ce4eb4e31 100644 --- a/compiler/rustc_const_eval/src/interpret/mod.rs +++ b/compiler/rustc_const_eval/src/interpret/mod.rs @@ -20,7 +20,7 @@ mod visitor; pub use rustc_middle::mir::interpret::*; // have all the `interpret` symbols in one place: here -pub use self::eval_context::{Frame, FrameInfo, InterpCx, StackPopCleanup}; +pub use self::eval_context::{format_interp_error, Frame, FrameInfo, InterpCx, StackPopCleanup}; pub use self::intern::{ intern_const_alloc_for_constprop, intern_const_alloc_recursive, InternKind, }; diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 67665c4aed2cf..90623a1aa9db6 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -27,8 +27,9 @@ use rustc_target::abi::{ use std::hash::Hash; use super::{ - AllocId, CheckInAllocMsg, GlobalAlloc, ImmTy, Immediate, InterpCx, InterpResult, MPlaceTy, - Machine, MemPlaceMeta, OpTy, Pointer, Projectable, Scalar, ValueVisitor, + format_interp_error, AllocId, CheckInAllocMsg, GlobalAlloc, ImmTy, Immediate, InterpCx, + InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy, Pointer, Projectable, Scalar, + ValueVisitor, }; // for the validation errors @@ -460,46 +461,49 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' // Special handling for pointers to statics (irrespective of their type). assert!(!self.ecx.tcx.is_thread_local_static(did)); assert!(self.ecx.tcx.is_static(did)); + let is_mut = + matches!(self.ecx.tcx.def_kind(did), DefKind::Static(Mutability::Mut)) + || !self + .ecx + .tcx + .type_of(did) + .no_bound_vars() + .expect("statics should not have generic parameters") + .is_freeze(*self.ecx.tcx, ty::ParamEnv::reveal_all()); // Mutability check. if ptr_expected_mutbl == Mutability::Mut { - if matches!( - self.ecx.tcx.def_kind(did), - DefKind::Static(Mutability::Not) - ) && self - .ecx - .tcx - .type_of(did) - .no_bound_vars() - .expect("statics should not have generic parameters") - .is_freeze(*self.ecx.tcx, ty::ParamEnv::reveal_all()) - { + if !is_mut { throw_validation_failure!(self.path, MutableRefToImmutable); } } - // We skip recursively 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(()); + match self.ctfe_mode { + Some(CtfeValidationMode::Static { .. }) => { + // We skip recursively 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. + // This could miss some UB, but that's fine. + return Ok(()); + } + Some(CtfeValidationMode::Const { .. }) => { + // For consts on the other hand we have to recursively check; + // pattern matching assumes a valid value. However we better make + // sure this is not mutable. + if is_mut { + throw_validation_failure!(self.path, ConstRefToMutable); + } + } + None => {} + } } GlobalAlloc::Memory(alloc) => { if alloc.inner().mutability == Mutability::Mut && matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { .. })) { - // This is impossible: this can only be some inner allocation of a - // `static mut` (everything else either hits the `GlobalAlloc::Static` - // case or is interned immutably). To get such a pointer we'd have to - // load it from a static, but such loads lead to a CTFE error. - span_bug!( - self.ecx.tcx.span, - "encountered reference to mutable memory inside a `const`" - ); + throw_validation_failure!(self.path, ConstRefToMutable); } if ptr_expected_mutbl == Mutability::Mut && alloc.inner().mutability == Mutability::Not @@ -978,7 +982,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Complain about any other kind of error -- those are bad because we'd like to // report them in a way that shows *where* in the value the issue lies. Err(err) => { - bug!("Unexpected error during validation: {}", self.format_error(err)); + bug!( + "Unexpected error during validation: {}", + format_interp_error(self.tcx.dcx(), err) + ); } } } diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 0f69ab93452f7..9a4ce48ebcee3 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -417,6 +417,7 @@ pub enum ValidationErrorKind<'tcx> { PtrToUninhabited { ptr_kind: PointerKind, ty: Ty<'tcx> }, PtrToStatic { ptr_kind: PointerKind }, MutableRefInConst, + ConstRefToMutable, MutableRefToImmutable, UnsafeCellInImmutable, NullFnPtr, diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index 04d0a4f303f25..f8e6905282c59 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -3,8 +3,9 @@ use std::fmt::Debug; -use rustc_const_eval::interpret::{ImmTy, Projectable}; -use rustc_const_eval::interpret::{InterpCx, InterpResult, Scalar}; +use rustc_const_eval::interpret::{ + format_interp_error, ImmTy, InterpCx, InterpResult, Projectable, Scalar, +}; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def::DefKind; use rustc_hir::HirId; @@ -246,7 +247,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { assert!( !error.kind().formatted_string(), "const-prop encountered formatting error: {}", - self.ecx.format_error(error), + format_interp_error(self.ecx.tcx.dcx(), error), ); None } diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 92c58d48dc757..7f91af59d5622 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -290,7 +290,7 @@ pub fn report_error<'tcx, 'mir>( ) => { ecx.handle_ice(); // print interpreter backtrace - bug!("This validation error should be impossible in Miri: {}", ecx.format_error(e)); + bug!("This validation error should be impossible in Miri: {}", format_interp_error(ecx.tcx.dcx(), e)); } UndefinedBehavior(_) => "Undefined Behavior", ResourceExhaustion(_) => "resource exhaustion", @@ -304,7 +304,7 @@ pub fn report_error<'tcx, 'mir>( ) => "post-monomorphization error", _ => { ecx.handle_ice(); // print interpreter backtrace - bug!("This error should be impossible in Miri: {}", ecx.format_error(e)); + bug!("This error should be impossible in Miri: {}", format_interp_error(ecx.tcx.dcx(), e)); } }; #[rustfmt::skip] @@ -370,7 +370,7 @@ pub fn report_error<'tcx, 'mir>( _ => {} } - msg.insert(0, ecx.format_error(e)); + msg.insert(0, format_interp_error(ecx.tcx.dcx(), e)); report_msg( DiagLevel::Error, diff --git a/tests/ui/consts/const_refs_to_static_fail.rs b/tests/ui/consts/const_refs_to_static_fail.rs index 95ffcce43660f..d5bcccf82d597 100644 --- a/tests/ui/consts/const_refs_to_static_fail.rs +++ b/tests/ui/consts/const_refs_to_static_fail.rs @@ -1,13 +1,15 @@ +// normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +// normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![feature(const_refs_to_static, const_mut_refs, sync_unsafe_cell)] use std::cell::SyncUnsafeCell; static S: SyncUnsafeCell = SyncUnsafeCell::new(0); static mut S_MUT: i32 = 0; -const C1: &SyncUnsafeCell = &S; +const C1: &SyncUnsafeCell = &S; //~ERROR undefined behavior +//~| encountered reference to mutable memory const C1_READ: () = unsafe { - assert!(*C1.get() == 0); //~ERROR evaluation of constant value failed - //~^ constant accesses mutable global memory + assert!(*C1.get() == 0); }; const C2: *const i32 = unsafe { std::ptr::addr_of!(S_MUT) }; const C2_READ: () = unsafe { diff --git a/tests/ui/consts/const_refs_to_static_fail.stderr b/tests/ui/consts/const_refs_to_static_fail.stderr index d27aebc5c1268..cdabd86b183e9 100644 --- a/tests/ui/consts/const_refs_to_static_fail.stderr +++ b/tests/ui/consts/const_refs_to_static_fail.stderr @@ -1,11 +1,22 @@ -error[E0080]: evaluation of constant value failed - --> $DIR/const_refs_to_static_fail.rs:9:13 +error[E0080]: it is undefined behavior to use this value + --> $DIR/const_refs_to_static_fail.rs:9:1 + | +LL | const C1: &SyncUnsafeCell = &S; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` + | + = 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. + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } + +note: erroneous constant encountered + --> $DIR/const_refs_to_static_fail.rs:12:14 | LL | assert!(*C1.get() == 0); - | ^^^^^^^^^ constant accesses mutable global memory + | ^^ error[E0080]: evaluation of constant value failed - --> $DIR/const_refs_to_static_fail.rs:14:13 + --> $DIR/const_refs_to_static_fail.rs:16:13 | LL | assert!(*C2 == 0); | ^^^ constant accesses mutable global memory diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.rs b/tests/ui/consts/const_refs_to_static_fail_invalid.rs new file mode 100644 index 0000000000000..de4ec6b1e2a25 --- /dev/null +++ b/tests/ui/consts/const_refs_to_static_fail_invalid.rs @@ -0,0 +1,17 @@ +// normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +// normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +#![feature(const_refs_to_static)] + +static S: i8 = 10; + +const C: &bool = unsafe { std::mem::transmute(&S) }; +//~^ERROR: undefined behavior +//~| expected a boolean + +fn main() { + // This must be rejected here (or earlier), since it's not a valid `&bool`. + match &true { + C => {}, //~ERROR: could not evaluate constant pattern + _ => {}, + } +} diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr new file mode 100644 index 0000000000000..cf8238063bc5a --- /dev/null +++ b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr @@ -0,0 +1,20 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/const_refs_to_static_fail_invalid.rs:7:1 + | +LL | const C: &bool = unsafe { std::mem::transmute(&S) }; + | ^^^^^^^^^^^^^^ constructing invalid value at .: encountered 0x0a, but expected a boolean + | + = 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. + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } + +error: could not evaluate constant pattern + --> $DIR/const_refs_to_static_fail_invalid.rs:14:9 + | +LL | C => {}, + | ^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const_refs_to_static_fail_pattern.rs b/tests/ui/consts/const_refs_to_static_fail_pattern.rs index 21dc08066a24a..27a77378d0ee2 100644 --- a/tests/ui/consts/const_refs_to_static_fail_pattern.rs +++ b/tests/ui/consts/const_refs_to_static_fail_pattern.rs @@ -1,9 +1,12 @@ +// normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +// normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![feature(const_refs_to_static)] static mut S_MUT: i32 = 0; const C: &i32 = unsafe { &S_MUT }; -//~^ERROR: constant refers to mutable data +//~^ERROR: undefined behavior +//~| encountered reference to mutable memory fn main() { // This *must not build*, the constant we are matching against diff --git a/tests/ui/consts/const_refs_to_static_fail_pattern.stderr b/tests/ui/consts/const_refs_to_static_fail_pattern.stderr index d6697b8782667..a229654a89be1 100644 --- a/tests/ui/consts/const_refs_to_static_fail_pattern.stderr +++ b/tests/ui/consts/const_refs_to_static_fail_pattern.stderr @@ -1,14 +1,20 @@ -error: constant refers to mutable data - --> $DIR/const_refs_to_static_fail_pattern.rs:5:1 +error[E0080]: it is undefined behavior to use this value + --> $DIR/const_refs_to_static_fail_pattern.rs:7:1 | LL | const C: &i32 = unsafe { &S_MUT }; - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` + | + = 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. + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } error: could not evaluate constant pattern - --> $DIR/const_refs_to_static_fail_pattern.rs:12:9 + --> $DIR/const_refs_to_static_fail_pattern.rs:15:9 | LL | C => {}, | ^ error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static.32bit.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static.32bit.stderr index 2e2e97dde0e65..35b9ed6735e80 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static.32bit.stderr +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static.32bit.stderr @@ -16,6 +16,17 @@ error[E0080]: evaluation of constant value failed LL | const READ_MUT: u32 = unsafe { MUTABLE }; | ^^^^^^^ constant accesses mutable global memory +error[E0080]: it is undefined behavior to use this value + --> $DIR/const_refers_to_static.rs:21:1 + | +LL | const REF_INTERIOR_MUT: &usize = { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` + | + = 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. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾ALLOC0╼ │ ╾──╼ + } + warning: skipping const checks | help: skipping check for `const_refs_to_static` feature @@ -44,16 +55,16 @@ help: skipping check for `const_refs_to_static` feature LL | const READ_MUT: u32 = unsafe { MUTABLE }; | ^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static.rs:23:18 + --> $DIR/const_refers_to_static.rs:24:18 | LL | unsafe { &*(&FOO as *const _ as *const usize) } | ^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static.rs:27:25 + --> $DIR/const_refers_to_static.rs:29:25 | LL | const REF_IMMUT: &u8 = &MY_STATIC; | ^^^^^^^^^ -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 4 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static.64bit.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static.64bit.stderr index 2e2e97dde0e65..8511673b684fb 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static.64bit.stderr +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static.64bit.stderr @@ -16,6 +16,17 @@ error[E0080]: evaluation of constant value failed LL | const READ_MUT: u32 = unsafe { MUTABLE }; | ^^^^^^^ constant accesses mutable global memory +error[E0080]: it is undefined behavior to use this value + --> $DIR/const_refers_to_static.rs:21:1 + | +LL | const REF_INTERIOR_MUT: &usize = { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` + | + = 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. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾ALLOC0╼ │ ╾──────╼ + } + warning: skipping const checks | help: skipping check for `const_refs_to_static` feature @@ -44,16 +55,16 @@ help: skipping check for `const_refs_to_static` feature LL | const READ_MUT: u32 = unsafe { MUTABLE }; | ^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static.rs:23:18 + --> $DIR/const_refers_to_static.rs:24:18 | LL | unsafe { &*(&FOO as *const _ as *const usize) } | ^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static.rs:27:25 + --> $DIR/const_refers_to_static.rs:29:25 | LL | const REF_IMMUT: &u8 = &MY_STATIC; | ^^^^^^^^^ -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 4 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static.rs b/tests/ui/consts/miri_unleashed/const_refers_to_static.rs index d426d7eb184f1..f8d956b3dd86e 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static.rs +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static.rs @@ -17,12 +17,14 @@ const READ_INTERIOR_MUT: usize = { static mut MUTABLE: u32 = 0; const READ_MUT: u32 = unsafe { MUTABLE }; //~ERROR evaluation of constant value failed -// Not actually reading from anything mutable, so these are fine. -const REF_INTERIOR_MUT: &usize = { +// Evaluating this does not read anything mutable, but validation does, so this should error. +const REF_INTERIOR_MUT: &usize = { //~ ERROR undefined behavior + //~| encountered reference to mutable memory static FOO: AtomicUsize = AtomicUsize::new(0); unsafe { &*(&FOO as *const _ as *const usize) } }; +// Not actually reading from anything mutable, so these are fine. static MY_STATIC: u8 = 4; const REF_IMMUT: &u8 = &MY_STATIC; const READ_IMMUT: u8 = *REF_IMMUT; diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr index 682b53edf6fa3..a2c9034c831b8 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr @@ -1,5 +1,5 @@ warning: shared reference of mutable static is discouraged - --> $DIR/const_refers_to_static_cross_crate.rs:11:14 + --> $DIR/const_refers_to_static_cross_crate.rs:12:14 | LL | unsafe { &static_cross_crate::ZERO } | ^^^^^^^^^^^^^^^^^^^^^^^^^ shared reference of mutable static @@ -13,50 +13,65 @@ help: shared references are dangerous since if there's any kind of mutation of t LL | unsafe { addr_of!(static_cross_crate::ZERO) } | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -error: constant refers to mutable data +error[E0080]: it is undefined behavior to use this value --> $DIR/const_refers_to_static_cross_crate.rs:10:1 | LL | const SLICE_MUT: &[u8; 1] = { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` + | + = 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. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾ALLOC0╼ │ ╾──╼ + } error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:36:9 + --> $DIR/const_refers_to_static_cross_crate.rs:39:9 | LL | SLICE_MUT => true, | ^^^^^^^^^ -error: constant refers to mutable data - --> $DIR/const_refers_to_static_cross_crate.rs:15:1 +error[E0080]: it is undefined behavior to use this value + --> $DIR/const_refers_to_static_cross_crate.rs:16:1 | LL | const U8_MUT: &u8 = { - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` + | + = 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. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾ALLOC0╼ │ ╾──╼ + } error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:44:9 + --> $DIR/const_refers_to_static_cross_crate.rs:47:9 | LL | U8_MUT => true, | ^^^^^^ -error: constant refers to mutable data - --> $DIR/const_refers_to_static_cross_crate.rs:20:1 +error[E0080]: it is undefined behavior to use this value + --> $DIR/const_refers_to_static_cross_crate.rs:22:1 | LL | const U8_MUT2: &u8 = { - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` + | + = 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. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾ALLOC0╼ │ ╾──╼ + } error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:54:9 + --> $DIR/const_refers_to_static_cross_crate.rs:57:9 | LL | U8_MUT2 => true, | ^^^^^^^ error[E0080]: evaluation of constant value failed - --> $DIR/const_refers_to_static_cross_crate.rs:25:15 + --> $DIR/const_refers_to_static_cross_crate.rs:28:15 | LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses mutable global memory error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:61:9 + --> $DIR/const_refers_to_static_cross_crate.rs:64:9 | LL | U8_MUT3 => true, | ^^^^^^^ @@ -64,57 +79,57 @@ LL | U8_MUT3 => true, warning: skipping const checks | help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:11:15 + --> $DIR/const_refers_to_static_cross_crate.rs:12:15 | LL | unsafe { &static_cross_crate::ZERO } | ^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:11:15 + --> $DIR/const_refers_to_static_cross_crate.rs:12:15 | LL | unsafe { &static_cross_crate::ZERO } | ^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:16:15 + --> $DIR/const_refers_to_static_cross_crate.rs:18:15 | LL | unsafe { &static_cross_crate::ZERO[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:16:15 + --> $DIR/const_refers_to_static_cross_crate.rs:18:15 | LL | unsafe { &static_cross_crate::ZERO[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:16:15 + --> $DIR/const_refers_to_static_cross_crate.rs:18:15 | LL | unsafe { &static_cross_crate::ZERO[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:21:17 + --> $DIR/const_refers_to_static_cross_crate.rs:24:17 | LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:25:15 + --> $DIR/const_refers_to_static_cross_crate.rs:28:15 | LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:25:15 + --> $DIR/const_refers_to_static_cross_crate.rs:28:15 | LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:25:15 + --> $DIR/const_refers_to_static_cross_crate.rs:28:15 | LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:25:15 + --> $DIR/const_refers_to_static_cross_crate.rs:28:15 | LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:25:15 + --> $DIR/const_refers_to_static_cross_crate.rs:28:15 | LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr index 682b53edf6fa3..2b44a8b12fa3f 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr @@ -1,5 +1,5 @@ warning: shared reference of mutable static is discouraged - --> $DIR/const_refers_to_static_cross_crate.rs:11:14 + --> $DIR/const_refers_to_static_cross_crate.rs:12:14 | LL | unsafe { &static_cross_crate::ZERO } | ^^^^^^^^^^^^^^^^^^^^^^^^^ shared reference of mutable static @@ -13,50 +13,65 @@ help: shared references are dangerous since if there's any kind of mutation of t LL | unsafe { addr_of!(static_cross_crate::ZERO) } | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -error: constant refers to mutable data +error[E0080]: it is undefined behavior to use this value --> $DIR/const_refers_to_static_cross_crate.rs:10:1 | LL | const SLICE_MUT: &[u8; 1] = { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` + | + = 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. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾ALLOC0╼ │ ╾──────╼ + } error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:36:9 + --> $DIR/const_refers_to_static_cross_crate.rs:39:9 | LL | SLICE_MUT => true, | ^^^^^^^^^ -error: constant refers to mutable data - --> $DIR/const_refers_to_static_cross_crate.rs:15:1 +error[E0080]: it is undefined behavior to use this value + --> $DIR/const_refers_to_static_cross_crate.rs:16:1 | LL | const U8_MUT: &u8 = { - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` + | + = 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. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾ALLOC0╼ │ ╾──────╼ + } error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:44:9 + --> $DIR/const_refers_to_static_cross_crate.rs:47:9 | LL | U8_MUT => true, | ^^^^^^ -error: constant refers to mutable data - --> $DIR/const_refers_to_static_cross_crate.rs:20:1 +error[E0080]: it is undefined behavior to use this value + --> $DIR/const_refers_to_static_cross_crate.rs:22:1 | LL | const U8_MUT2: &u8 = { - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` + | + = 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. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾ALLOC0╼ │ ╾──────╼ + } error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:54:9 + --> $DIR/const_refers_to_static_cross_crate.rs:57:9 | LL | U8_MUT2 => true, | ^^^^^^^ error[E0080]: evaluation of constant value failed - --> $DIR/const_refers_to_static_cross_crate.rs:25:15 + --> $DIR/const_refers_to_static_cross_crate.rs:28:15 | LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses mutable global memory error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:61:9 + --> $DIR/const_refers_to_static_cross_crate.rs:64:9 | LL | U8_MUT3 => true, | ^^^^^^^ @@ -64,57 +79,57 @@ LL | U8_MUT3 => true, warning: skipping const checks | help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:11:15 + --> $DIR/const_refers_to_static_cross_crate.rs:12:15 | LL | unsafe { &static_cross_crate::ZERO } | ^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:11:15 + --> $DIR/const_refers_to_static_cross_crate.rs:12:15 | LL | unsafe { &static_cross_crate::ZERO } | ^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:16:15 + --> $DIR/const_refers_to_static_cross_crate.rs:18:15 | LL | unsafe { &static_cross_crate::ZERO[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:16:15 + --> $DIR/const_refers_to_static_cross_crate.rs:18:15 | LL | unsafe { &static_cross_crate::ZERO[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:16:15 + --> $DIR/const_refers_to_static_cross_crate.rs:18:15 | LL | unsafe { &static_cross_crate::ZERO[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:21:17 + --> $DIR/const_refers_to_static_cross_crate.rs:24:17 | LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:25:15 + --> $DIR/const_refers_to_static_cross_crate.rs:28:15 | LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:25:15 + --> $DIR/const_refers_to_static_cross_crate.rs:28:15 | LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:25:15 + --> $DIR/const_refers_to_static_cross_crate.rs:28:15 | LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:25:15 + --> $DIR/const_refers_to_static_cross_crate.rs:28:15 | LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/const_refers_to_static_cross_crate.rs:25:15 + --> $DIR/const_refers_to_static_cross_crate.rs:28:15 | LL | match static_cross_crate::OPT_ZERO { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs index 7c10a3fd19c62..cdbfb37c7c738 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs @@ -7,17 +7,20 @@ extern crate static_cross_crate; // Sneaky: reference to a mutable static. // Allowing this would be a disaster for pattern matching, we could violate exhaustiveness checking! -const SLICE_MUT: &[u8; 1] = { //~ ERROR constant refers to mutable data +const SLICE_MUT: &[u8; 1] = { //~ ERROR undefined behavior + //~| encountered reference to mutable memory unsafe { &static_cross_crate::ZERO } //~^ WARN shared reference of mutable static is discouraged [static_mut_ref] }; -const U8_MUT: &u8 = { //~ ERROR constant refers to mutable data +const U8_MUT: &u8 = { //~ ERROR undefined behavior + //~| encountered reference to mutable memory unsafe { &static_cross_crate::ZERO[0] } }; // Also test indirection that reads from other static. -const U8_MUT2: &u8 = { //~ ERROR constant refers to mutable data +const U8_MUT2: &u8 = { //~ ERROR undefined behavior + //~| encountered reference to mutable memory unsafe { &(*static_cross_crate::ZERO_REF)[0] } }; const U8_MUT3: &u8 = { diff --git a/tests/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr b/tests/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr index 59cde74db97b3..b60f9a24f8c7a 100644 --- a/tests/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr +++ b/tests/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr @@ -38,50 +38,61 @@ LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const ╾ALLOC1╼ │ ╾──╼ } -error[E0080]: evaluation of constant value failed - --> $DIR/mutable_references_err.rs:48:33 +error[E0080]: it is undefined behavior to use this value + --> $DIR/mutable_references_err.rs:47:1 + | +LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` + | + = 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. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾ALLOC2╼ │ ╾──╼ + } + +note: erroneous constant encountered + --> $DIR/mutable_references_err.rs:49:34 | LL | const READS_FROM_MUTABLE: i32 = *POINTS_TO_MUTABLE1; - | ^^^^^^^^^^^^^^^^^^^ constant accesses mutable global memory + | ^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed - --> $DIR/mutable_references_err.rs:52:43 + --> $DIR/mutable_references_err.rs:51:43 | LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF }; | ^^^^^^^^^^^^^ constant accesses mutable global memory error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:56:1 + --> $DIR/mutable_references_err.rs:55:1 | LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:58:1 + --> $DIR/mutable_references_err.rs:57:1 | LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:60:1 + --> $DIR/mutable_references_err.rs:59:1 | LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:70:1 + --> $DIR/mutable_references_err.rs:69:1 | LL | const RAW_SYNC: SyncPtr = SyncPtr { x: &AtomicI32::new(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:72:1 + --> $DIR/mutable_references_err.rs:71:1 | LL | const RAW_MUT_CAST: SyncPtr = SyncPtr { x : &mut 42 as *mut _ as *const _ }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:74:1 + --> $DIR/mutable_references_err.rs:73:1 | LL | const RAW_MUT_COERCE: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -139,42 +150,42 @@ help: skipping check for `const_refs_to_static` feature LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE }; | ^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/mutable_references_err.rs:52:45 + --> $DIR/mutable_references_err.rs:51:45 | LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF }; | ^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/mutable_references_err.rs:52:45 + --> $DIR/mutable_references_err.rs:51:45 | LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF }; | ^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:56:45 + --> $DIR/mutable_references_err.rs:55:45 | LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:58:46 + --> $DIR/mutable_references_err.rs:57:46 | LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:60:47 + --> $DIR/mutable_references_err.rs:59:47 | LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _; | ^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:70:51 + --> $DIR/mutable_references_err.rs:69:51 | LL | const RAW_SYNC: SyncPtr = SyncPtr { x: &AtomicI32::new(42) }; | ^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:72:50 + --> $DIR/mutable_references_err.rs:71:50 | LL | const RAW_MUT_CAST: SyncPtr = SyncPtr { x : &mut 42 as *mut _ as *const _ }; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:74:51 + --> $DIR/mutable_references_err.rs:73:51 | LL | const RAW_MUT_COERCE: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^ diff --git a/tests/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr b/tests/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr index ff7678b1555b7..1e5d4bd890b99 100644 --- a/tests/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr +++ b/tests/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr @@ -38,50 +38,61 @@ LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const ╾ALLOC1╼ │ ╾──────╼ } -error[E0080]: evaluation of constant value failed - --> $DIR/mutable_references_err.rs:48:33 +error[E0080]: it is undefined behavior to use this value + --> $DIR/mutable_references_err.rs:47:1 + | +LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` + | + = 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. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾ALLOC2╼ │ ╾──────╼ + } + +note: erroneous constant encountered + --> $DIR/mutable_references_err.rs:49:34 | LL | const READS_FROM_MUTABLE: i32 = *POINTS_TO_MUTABLE1; - | ^^^^^^^^^^^^^^^^^^^ constant accesses mutable global memory + | ^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed - --> $DIR/mutable_references_err.rs:52:43 + --> $DIR/mutable_references_err.rs:51:43 | LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF }; | ^^^^^^^^^^^^^ constant accesses mutable global memory error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:56:1 + --> $DIR/mutable_references_err.rs:55:1 | LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:58:1 + --> $DIR/mutable_references_err.rs:57:1 | LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:60:1 + --> $DIR/mutable_references_err.rs:59:1 | LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:70:1 + --> $DIR/mutable_references_err.rs:69:1 | LL | const RAW_SYNC: SyncPtr = SyncPtr { x: &AtomicI32::new(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:72:1 + --> $DIR/mutable_references_err.rs:71:1 | LL | const RAW_MUT_CAST: SyncPtr = SyncPtr { x : &mut 42 as *mut _ as *const _ }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:74:1 + --> $DIR/mutable_references_err.rs:73:1 | LL | const RAW_MUT_COERCE: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -139,42 +150,42 @@ help: skipping check for `const_refs_to_static` feature LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE }; | ^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/mutable_references_err.rs:52:45 + --> $DIR/mutable_references_err.rs:51:45 | LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF }; | ^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/mutable_references_err.rs:52:45 + --> $DIR/mutable_references_err.rs:51:45 | LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF }; | ^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:56:45 + --> $DIR/mutable_references_err.rs:55:45 | LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:58:46 + --> $DIR/mutable_references_err.rs:57:46 | LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:60:47 + --> $DIR/mutable_references_err.rs:59:47 | LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _; | ^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:70:51 + --> $DIR/mutable_references_err.rs:69:51 | LL | const RAW_SYNC: SyncPtr = SyncPtr { x: &AtomicI32::new(42) }; | ^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:72:50 + --> $DIR/mutable_references_err.rs:71:50 | LL | const RAW_MUT_CAST: SyncPtr = SyncPtr { x : &mut 42 as *mut _ as *const _ }; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:74:51 + --> $DIR/mutable_references_err.rs:73:51 | LL | const RAW_MUT_COERCE: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^ diff --git a/tests/ui/consts/miri_unleashed/mutable_references_err.rs b/tests/ui/consts/miri_unleashed/mutable_references_err.rs index d0a79ff7bbc73..43b65f459a1eb 100644 --- a/tests/ui/consts/miri_unleashed/mutable_references_err.rs +++ b/tests/ui/consts/miri_unleashed/mutable_references_err.rs @@ -44,10 +44,9 @@ static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as // Check for consts pointing to mutable memory. // These are fine as long as they are not being read. static mut MUTABLE: i32 = 42; -const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE }; +const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE }; //~ERROR: undefined behavior +//~| encountered reference to mutable memory const READS_FROM_MUTABLE: i32 = *POINTS_TO_MUTABLE1; -//~^ ERROR: evaluation of constant value failed -//~| accesses mutable global memory static mut MUTABLE_REF: &mut i32 = &mut 42; const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF }; //~^ ERROR: evaluation of constant value failed From 77f8c3caea901df51ef723251a7a58b27f96bb3a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 6 Jan 2024 15:06:22 +0100 Subject: [PATCH 3/5] detect consts that reference extern statics --- compiler/rustc_const_eval/messages.ftl | 1 + .../src/const_eval/eval_queries.rs | 7 ++- compiler/rustc_const_eval/src/errors.rs | 2 + .../src/interpret/validity.rs | 14 +++++- .../rustc_middle/src/mir/interpret/error.rs | 1 + .../const_refs_to_static_fail_invalid.rs | 43 ++++++++++++++++--- .../const_refs_to_static_fail_invalid.stderr | 42 ++++++++++++++++-- .../const_refs_to_static_fail_pattern.rs | 18 -------- .../const_refs_to_static_fail_pattern.stderr | 20 --------- 9 files changed, 97 insertions(+), 51 deletions(-) delete mode 100644 tests/ui/consts/const_refs_to_static_fail_pattern.rs delete mode 100644 tests/ui/consts/const_refs_to_static_fail_pattern.stderr diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index f8bb122c52c0f..546001a25b299 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -412,6 +412,7 @@ const_eval_upcast_mismatch = const_eval_validation_box_to_static = {$front_matter}: encountered a box pointing to a static variable in a constant const_eval_validation_box_to_uninhabited = {$front_matter}: encountered a box pointing to uninhabited type {$ty} +const_eval_validation_const_ref_to_extern = {$front_matter}: encountered reference to `extern` static in `const` const_eval_validation_const_ref_to_mutable = {$front_matter}: encountered reference to mutable memory in `const` const_eval_validation_dangling_box_no_provenance = {$front_matter}: encountered a dangling box ({$pointer} has no provenance) diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 52060a8693f1b..0844cdbe99b88 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -360,7 +360,7 @@ pub fn const_validate_mplace<'mir, 'tcx>( // Promoteds in statics are consts that re allowed to point to statics. CtfeValidationMode::Const { allow_immutable_unsafe_cell: false, - allow_static_ptrs: true, + allow_extern_static_ptrs: true, } } Some(mutbl) => CtfeValidationMode::Static { mutbl }, // a `static` @@ -368,7 +368,10 @@ pub fn const_validate_mplace<'mir, 'tcx>( // In normal `const` (not promoted), the outermost allocation is always only copied, // so having `UnsafeCell` in there is okay despite them being in immutable memory. let allow_immutable_unsafe_cell = cid.promoted.is_none() && !inner; - CtfeValidationMode::Const { allow_immutable_unsafe_cell, allow_static_ptrs: false } + CtfeValidationMode::Const { + allow_immutable_unsafe_cell, + allow_extern_static_ptrs: false, + } } }; ecx.const_validate_operand(&mplace.into(), path, &mut ref_tracking, mode)?; diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index fe72941bbabaf..fb89b49faded5 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -612,6 +612,7 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { PointerAsInt { .. } => const_eval_validation_pointer_as_int, PartialPointer => const_eval_validation_partial_pointer, ConstRefToMutable => const_eval_validation_const_ref_to_mutable, + ConstRefToExtern => const_eval_validation_const_ref_to_extern, MutableRefInConst => const_eval_validation_mutable_ref_in_const, MutableRefToImmutable => const_eval_validation_mutable_ref_to_immutable, NullFnPtr => const_eval_validation_null_fn_ptr, @@ -767,6 +768,7 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { | PtrToStatic { .. } | MutableRefInConst | ConstRefToMutable + | ConstRefToExtern | MutableRefToImmutable | NullFnPtr | NeverVal diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 90623a1aa9db6..38aeace02ba4b 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -133,7 +133,7 @@ pub enum CtfeValidationMode { /// `allow_immutable_unsafe_cell` says whether we allow `UnsafeCell` in immutable memory (which is the /// case for the top-level allocation of a `const`, where this is fine because the allocation will be /// copied at each use site). - Const { allow_immutable_unsafe_cell: bool, allow_static_ptrs: bool }, + Const { allow_immutable_unsafe_cell: bool, allow_extern_static_ptrs: bool }, } impl CtfeValidationMode { @@ -488,13 +488,23 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' // This could miss some UB, but that's fine. return Ok(()); } - Some(CtfeValidationMode::Const { .. }) => { + Some(CtfeValidationMode::Const { + allow_extern_static_ptrs, .. + }) => { // For consts on the other hand we have to recursively check; // pattern matching assumes a valid value. However we better make // sure this is not mutable. if is_mut { throw_validation_failure!(self.path, ConstRefToMutable); } + if self.ecx.tcx.is_foreign_item(did) { + if !allow_extern_static_ptrs { + throw_validation_failure!(self.path, ConstRefToExtern); + } else { + // We can't validate this... + return Ok(()); + } + } } None => {} } diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 9a4ce48ebcee3..66f448a451ee5 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -418,6 +418,7 @@ pub enum ValidationErrorKind<'tcx> { PtrToStatic { ptr_kind: PointerKind }, MutableRefInConst, ConstRefToMutable, + ConstRefToExtern, MutableRefToImmutable, UnsafeCellInImmutable, NullFnPtr, diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.rs b/tests/ui/consts/const_refs_to_static_fail_invalid.rs index de4ec6b1e2a25..ee20db6c6c09f 100644 --- a/tests/ui/consts/const_refs_to_static_fail_invalid.rs +++ b/tests/ui/consts/const_refs_to_static_fail_invalid.rs @@ -2,16 +2,49 @@ // normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![feature(const_refs_to_static)] -static S: i8 = 10; +fn invalid() { + static S: i8 = 10; -const C: &bool = unsafe { std::mem::transmute(&S) }; -//~^ERROR: undefined behavior -//~| expected a boolean + const C: &bool = unsafe { std::mem::transmute(&S) }; + //~^ERROR: undefined behavior + //~| expected a boolean -fn main() { // This must be rejected here (or earlier), since it's not a valid `&bool`. match &true { + C => {} //~ERROR: could not evaluate constant pattern + _ => {} + } +} + +fn extern_() { + extern "C" { + static S: i8; + } + + const C: &i8 = unsafe { &S }; + //~^ERROR: undefined behavior + //~| `extern` static + + // This must be rejected here (or earlier), since the pattern cannot be read. + match &0 { + C => {} //~ERROR: could not evaluate constant pattern + _ => {} + } +} + +fn mutable() { + static mut S_MUT: i32 = 0; + + const C: &i32 = unsafe { &S_MUT }; + //~^ERROR: undefined behavior + //~| encountered reference to mutable memory + + // This *must not build*, the constant we are matching against + // could change its value! + match &42 { C => {}, //~ERROR: could not evaluate constant pattern _ => {}, } } + +fn main() {} diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr index cf8238063bc5a..56006f7ae250a 100644 --- a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr +++ b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr @@ -1,8 +1,8 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refs_to_static_fail_invalid.rs:7:1 + --> $DIR/const_refs_to_static_fail_invalid.rs:8:5 | -LL | const C: &bool = unsafe { std::mem::transmute(&S) }; - | ^^^^^^^^^^^^^^ constructing invalid value at .: encountered 0x0a, but expected a boolean +LL | const C: &bool = unsafe { std::mem::transmute(&S) }; + | ^^^^^^^^^^^^^^ constructing invalid value at .: encountered 0x0a, but expected a boolean | = 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. = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { @@ -12,9 +12,43 @@ LL | const C: &bool = unsafe { std::mem::transmute(&S) }; error: could not evaluate constant pattern --> $DIR/const_refs_to_static_fail_invalid.rs:14:9 | +LL | C => {} + | ^ + +error[E0080]: it is undefined behavior to use this value + --> $DIR/const_refs_to_static_fail_invalid.rs:24:5 + | +LL | const C: &i8 = unsafe { &S }; + | ^^^^^^^^^^^^ constructing invalid value: encountered reference to `extern` static in `const` + | + = 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. + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } + +error: could not evaluate constant pattern + --> $DIR/const_refs_to_static_fail_invalid.rs:30:9 + | +LL | C => {} + | ^ + +error[E0080]: it is undefined behavior to use this value + --> $DIR/const_refs_to_static_fail_invalid.rs:38:5 + | +LL | const C: &i32 = unsafe { &S_MUT }; + | ^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` + | + = 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. + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } + +error: could not evaluate constant pattern + --> $DIR/const_refs_to_static_fail_invalid.rs:45:9 + | LL | C => {}, | ^ -error: aborting due to 2 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const_refs_to_static_fail_pattern.rs b/tests/ui/consts/const_refs_to_static_fail_pattern.rs deleted file mode 100644 index 27a77378d0ee2..0000000000000 --- a/tests/ui/consts/const_refs_to_static_fail_pattern.rs +++ /dev/null @@ -1,18 +0,0 @@ -// normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -// normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" -#![feature(const_refs_to_static)] - -static mut S_MUT: i32 = 0; - -const C: &i32 = unsafe { &S_MUT }; -//~^ERROR: undefined behavior -//~| encountered reference to mutable memory - -fn main() { - // This *must not build*, the constant we are matching against - // could change its value! - match &42 { - C => {}, //~ERROR: could not evaluate constant pattern - _ => {}, - } -} diff --git a/tests/ui/consts/const_refs_to_static_fail_pattern.stderr b/tests/ui/consts/const_refs_to_static_fail_pattern.stderr deleted file mode 100644 index a229654a89be1..0000000000000 --- a/tests/ui/consts/const_refs_to_static_fail_pattern.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refs_to_static_fail_pattern.rs:7:1 - | -LL | const C: &i32 = unsafe { &S_MUT }; - | ^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` - | - = 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. - = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { - HEX_DUMP - } - -error: could not evaluate constant pattern - --> $DIR/const_refs_to_static_fail_pattern.rs:15:9 - | -LL | C => {}, - | ^ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0080`. From 04bc624ea0af4757e4464695193ba952e3c0951d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 5 Feb 2024 21:24:32 +0100 Subject: [PATCH 4/5] rebless after rebase --- tests/ui/asm/x86_64/type-check-4.stderr | 3 +++ .../consts/const-fn-not-safe-for-const.stderr | 2 ++ .../const_refs_to_static_fail_invalid.rs | 1 + .../const_refs_to_static_fail_invalid.stderr | 19 +++++++++++++++++-- .../issue-17718-const-bad-values.stderr | 2 ++ tests/ui/consts/issue-17718-references.stderr | 3 +++ tests/ui/consts/issue-52060.stderr | 1 + .../consts/min_const_fn/min_const_fn.stderr | 2 ++ .../feature-gate-const-refs-to-static.stderr | 3 +++ tests/ui/static/issue-18118-2.stderr | 1 + .../thread-local/thread-local-static.stderr | 1 + 11 files changed, 36 insertions(+), 2 deletions(-) diff --git a/tests/ui/asm/x86_64/type-check-4.stderr b/tests/ui/asm/x86_64/type-check-4.stderr index fbca868c0838b..cbdc051b3436b 100644 --- a/tests/ui/asm/x86_64/type-check-4.stderr +++ b/tests/ui/asm/x86_64/type-check-4.stderr @@ -6,6 +6,7 @@ LL | global_asm!("{}", const S); | = note: see issue #119618 for more information = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. = help: to fix this, the value can be extracted to a `const` and then used. @@ -17,6 +18,7 @@ LL | global_asm!("{}", const const_foo(S)); | = note: see issue #119618 for more information = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. = help: to fix this, the value can be extracted to a `const` and then used. @@ -28,6 +30,7 @@ LL | global_asm!("{}", const const_bar(S)); | = note: see issue #119618 for more information = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. = help: to fix this, the value can be extracted to a `const` and then used. diff --git a/tests/ui/consts/const-fn-not-safe-for-const.stderr b/tests/ui/consts/const-fn-not-safe-for-const.stderr index 1793c7342806f..7d7e94da86f7a 100644 --- a/tests/ui/consts/const-fn-not-safe-for-const.stderr +++ b/tests/ui/consts/const-fn-not-safe-for-const.stderr @@ -14,6 +14,7 @@ LL | Y | = note: see issue #119618 for more information = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. = help: to fix this, the value can be extracted to a `const` and then used. @@ -25,6 +26,7 @@ LL | &Y | = note: see issue #119618 for more information = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. = help: to fix this, the value can be extracted to a `const` and then used. diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.rs b/tests/ui/consts/const_refs_to_static_fail_invalid.rs index ee20db6c6c09f..bf52f884209c3 100644 --- a/tests/ui/consts/const_refs_to_static_fail_invalid.rs +++ b/tests/ui/consts/const_refs_to_static_fail_invalid.rs @@ -38,6 +38,7 @@ fn mutable() { const C: &i32 = unsafe { &S_MUT }; //~^ERROR: undefined behavior //~| encountered reference to mutable memory + //~| WARN shared reference of mutable static is discouraged // This *must not build*, the constant we are matching against // could change its value! diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr index 56006f7ae250a..35051557b614d 100644 --- a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr +++ b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr @@ -1,3 +1,18 @@ +warning: shared reference of mutable static is discouraged + --> $DIR/const_refs_to_static_fail_invalid.rs:38:30 + | +LL | const C: &i32 = unsafe { &S_MUT }; + | ^^^^^^ shared reference of mutable static + | + = note: for more information, see issue #114447 + = note: reference of mutable static is a hard error from 2024 edition + = note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior + = note: `#[warn(static_mut_ref)]` on by default +help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer + | +LL | const C: &i32 = unsafe { addr_of!(S_MUT) }; + | ~~~~~~~~~~~~~~~ + error[E0080]: it is undefined behavior to use this value --> $DIR/const_refs_to_static_fail_invalid.rs:8:5 | @@ -44,11 +59,11 @@ LL | const C: &i32 = unsafe { &S_MUT }; } error: could not evaluate constant pattern - --> $DIR/const_refs_to_static_fail_invalid.rs:45:9 + --> $DIR/const_refs_to_static_fail_invalid.rs:46:9 | LL | C => {}, | ^ -error: aborting due to 6 previous errors +error: aborting due to 6 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/issue-17718-const-bad-values.stderr b/tests/ui/consts/issue-17718-const-bad-values.stderr index 248cd999bb620..cda94490155c0 100644 --- a/tests/ui/consts/issue-17718-const-bad-values.stderr +++ b/tests/ui/consts/issue-17718-const-bad-values.stderr @@ -27,6 +27,7 @@ LL | const C2: &'static mut usize = unsafe { &mut S }; | = note: see issue #119618 for more information = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. = help: to fix this, the value can be extracted to a `const` and then used. @@ -38,6 +39,7 @@ LL | const C2: &'static mut usize = unsafe { &mut S }; | = note: see issue #119618 for more information = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. = help: to fix this, the value can be extracted to a `const` and then used. = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/consts/issue-17718-references.stderr b/tests/ui/consts/issue-17718-references.stderr index 4e5a44f6b6efd..8b57220378123 100644 --- a/tests/ui/consts/issue-17718-references.stderr +++ b/tests/ui/consts/issue-17718-references.stderr @@ -6,6 +6,7 @@ LL | const T2: &'static usize = &S; | = note: see issue #119618 for more information = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. = help: to fix this, the value can be extracted to a `const` and then used. @@ -17,6 +18,7 @@ LL | const T6: usize = S; | = note: see issue #119618 for more information = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. = help: to fix this, the value can be extracted to a `const` and then used. @@ -28,6 +30,7 @@ LL | const T10: Struct = Struct { a: S }; | = note: see issue #119618 for more information = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. = help: to fix this, the value can be extracted to a `const` and then used. diff --git a/tests/ui/consts/issue-52060.stderr b/tests/ui/consts/issue-52060.stderr index 9d5dff1ef2276..644a5314622d9 100644 --- a/tests/ui/consts/issue-52060.stderr +++ b/tests/ui/consts/issue-52060.stderr @@ -6,6 +6,7 @@ LL | static B: [u32; 1] = [0; A.len()]; | = note: see issue #119618 for more information = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. = help: to fix this, the value can be extracted to a `const` and then used. diff --git a/tests/ui/consts/min_const_fn/min_const_fn.stderr b/tests/ui/consts/min_const_fn/min_const_fn.stderr index 64b13e941a527..daa0ab2614fb1 100644 --- a/tests/ui/consts/min_const_fn/min_const_fn.stderr +++ b/tests/ui/consts/min_const_fn/min_const_fn.stderr @@ -150,6 +150,7 @@ LL | const fn foo25() -> u32 { BAR } | = note: see issue #119618 for more information = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. = help: to fix this, the value can be extracted to a `const` and then used. @@ -161,6 +162,7 @@ LL | const fn foo26() -> &'static u32 { &BAR } | = note: see issue #119618 for more information = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. = help: to fix this, the value can be extracted to a `const` and then used. diff --git a/tests/ui/feature-gates/feature-gate-const-refs-to-static.stderr b/tests/ui/feature-gates/feature-gate-const-refs-to-static.stderr index 259e96e71dd58..f94cff5b55047 100644 --- a/tests/ui/feature-gates/feature-gate-const-refs-to-static.stderr +++ b/tests/ui/feature-gates/feature-gate-const-refs-to-static.stderr @@ -6,6 +6,7 @@ LL | const C1: &i32 = &S; | = note: see issue #119618 for more information = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. = help: to fix this, the value can be extracted to a `const` and then used. @@ -17,6 +18,7 @@ LL | const C2: *const i32 = unsafe { std::ptr::addr_of!(S_MUT) }; | = note: see issue #119618 for more information = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. = help: to fix this, the value can be extracted to a `const` and then used. @@ -28,6 +30,7 @@ LL | const C2: *const i32 = unsafe { std::ptr::addr_of!(S_MUT) }; | = note: see issue #119618 for more information = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. = help: to fix this, the value can be extracted to a `const` and then used. = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/static/issue-18118-2.stderr b/tests/ui/static/issue-18118-2.stderr index 04604709c8a7b..f084f2b9fdfc4 100644 --- a/tests/ui/static/issue-18118-2.stderr +++ b/tests/ui/static/issue-18118-2.stderr @@ -6,6 +6,7 @@ LL | &p | = note: see issue #119618 for more information = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. = help: to fix this, the value can be extracted to a `const` and then used. diff --git a/tests/ui/thread-local/thread-local-static.stderr b/tests/ui/thread-local/thread-local-static.stderr index 46b6519c80b3b..d91742686c691 100644 --- a/tests/ui/thread-local/thread-local-static.stderr +++ b/tests/ui/thread-local/thread-local-static.stderr @@ -45,6 +45,7 @@ LL | std::mem::swap(x, &mut STATIC_VAR_2) | = note: see issue #119618 for more information = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. = help: to fix this, the value can be extracted to a `const` and then used. From 4def37386c181e9afb0dfc7f6c137f3730e5fca1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 10 Feb 2024 11:07:07 +0100 Subject: [PATCH 5/5] manually bless an aarch64 test --- tests/ui/asm/aarch64/type-check-4.rs | 6 +++--- tests/ui/asm/aarch64/type-check-4.stderr | 26 +++++++++++++++++------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/tests/ui/asm/aarch64/type-check-4.rs b/tests/ui/asm/aarch64/type-check-4.rs index 5dec60a2138d9..a14010481fc1d 100644 --- a/tests/ui/asm/aarch64/type-check-4.rs +++ b/tests/ui/asm/aarch64/type-check-4.rs @@ -23,10 +23,10 @@ const fn const_bar(x: T) -> T { x } global_asm!("{}", const S); -//~^ ERROR constants cannot refer to statics +//~^ ERROR referencing statics global_asm!("{}", const const_foo(0)); global_asm!("{}", const const_foo(S)); -//~^ ERROR constants cannot refer to statics +//~^ ERROR referencing statics global_asm!("{}", const const_bar(0)); global_asm!("{}", const const_bar(S)); -//~^ ERROR constants cannot refer to statics +//~^ ERROR referencing statics diff --git a/tests/ui/asm/aarch64/type-check-4.stderr b/tests/ui/asm/aarch64/type-check-4.stderr index 4837e647beae1..3e675f69e842b 100644 --- a/tests/ui/asm/aarch64/type-check-4.stderr +++ b/tests/ui/asm/aarch64/type-check-4.stderr @@ -1,27 +1,39 @@ -error[E0013]: constants cannot refer to statics +error[E0658]: referencing statics in constants is unstable --> $DIR/type-check-4.rs:25:25 | LL | global_asm!("{}", const S); | ^ | - = help: consider extracting the value of the `static` to a `const`, and referring to that + = note: see issue #119618 for more information + = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. + = help: to fix this, the value can be extracted to a `const` and then used. -error[E0013]: constants cannot refer to statics +error[E0658]: referencing statics in constants is unstable --> $DIR/type-check-4.rs:28:35 | LL | global_asm!("{}", const const_foo(S)); | ^ | - = help: consider extracting the value of the `static` to a `const`, and referring to that + = note: see issue #119618 for more information + = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. + = help: to fix this, the value can be extracted to a `const` and then used. -error[E0013]: constants cannot refer to statics +error[E0658]: referencing statics in constants is unstable --> $DIR/type-check-4.rs:31:35 | LL | global_asm!("{}", const const_bar(S)); | ^ | - = help: consider extracting the value of the `static` to a `const`, and referring to that + = note: see issue #119618 for more information + = help: add `#![feature(const_refs_to_static)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable. + = help: to fix this, the value can be extracted to a `const` and then used. error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0013`. +For more information about this error, try `rustc --explain E0658`.