mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-16 17:03:35 +00:00
unstably allow constants to refer to statics and read from immutable statics
This commit is contained in:
parent
5f40394baa
commit
4e77e368eb
@ -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
|
||||
|
||||
|
@ -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<ConstInt>),
|
||||
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<Self>, 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());
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -51,13 +51,10 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> {
|
||||
/// The virtual call stack.
|
||||
pub(super) stack: Vec<Frame<'mir, 'tcx>>,
|
||||
|
||||
/// 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<bool> for CanAccessStatics {
|
||||
impl From<bool> for CanAccessMutGlobal {
|
||||
fn from(value: bool) -> Self {
|
||||
if value { Self::Yes } else { Self::No }
|
||||
}
|
||||
@ -86,13 +83,13 @@ impl From<bool> 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<DefId>,
|
||||
_static_def_id: Option<DefId>,
|
||||
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(())
|
||||
}
|
||||
|
@ -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<ty::ValTree<'tcx>, 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<InterpErrorInfo<'_>> for ValTreeCreationError {
|
||||
fn from(err: InterpErrorInfo<'_>) -> Self {
|
||||
match err.kind() {
|
||||
InterpError::MachineStop(err) => {
|
||||
let err = err.downcast_ref::<ConstEvalErrKind>().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<mir::DestructuredConstant<'tcx>> {
|
||||
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.
|
||||
|
@ -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);
|
||||
|
@ -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<Span>,
|
||||
pub global_const_id: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(const_eval_unallowed_fn_pointer_call)]
|
||||
pub(crate) struct UnallowedFnPointerCall {
|
||||
|
@ -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!(
|
||||
|
@ -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 })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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<bool, &'tcx LayoutError<'tcx>> {
|
||||
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);
|
||||
|
||||
|
@ -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;
|
||||
```
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -19,10 +19,10 @@ const fn const_bar<T>(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
|
||||
|
@ -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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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`.
|
||||
|
@ -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() {
|
||||
}
|
@ -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`.
|
@ -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 {
|
||||
|
@ -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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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`.
|
||||
|
19
tests/ui/consts/const_refs_to_static.rs
Normal file
19
tests/ui/consts/const_refs_to_static.rs
Normal file
@ -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));
|
||||
}
|
19
tests/ui/consts/const_refs_to_static_fail.rs
Normal file
19
tests/ui/consts/const_refs_to_static_fail.rs
Normal file
@ -0,0 +1,19 @@
|
||||
#![feature(const_refs_to_static, const_mut_refs, sync_unsafe_cell)]
|
||||
use std::cell::SyncUnsafeCell;
|
||||
|
||||
static S: SyncUnsafeCell<i32> = SyncUnsafeCell::new(0);
|
||||
static mut S_MUT: i32 = 0;
|
||||
|
||||
const C1: &SyncUnsafeCell<i32> = &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() {
|
||||
}
|
15
tests/ui/consts/const_refs_to_static_fail.stderr
Normal file
15
tests/ui/consts/const_refs_to_static_fail.stderr
Normal file
@ -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`.
|
15
tests/ui/consts/const_refs_to_static_fail_pattern.rs
Normal file
15
tests/ui/consts/const_refs_to_static_fail_pattern.rs
Normal file
@ -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
|
||||
_ => {},
|
||||
}
|
||||
}
|
14
tests/ui/consts/const_refs_to_static_fail_pattern.stderr
Normal file
14
tests/ui/consts/const_refs_to_static_fail_pattern.stderr
Normal file
@ -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
|
||||
|
@ -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() {}
|
||||
|
@ -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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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`.
|
||||
|
@ -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 };
|
||||
|
||||
|
@ -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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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`.
|
||||
|
@ -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() {}
|
||||
|
@ -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 <https://github.com/rust-lang/rust/issues/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`.
|
||||
|
@ -86,8 +86,8 @@ const fn foo11_2<T: Send>(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 } }
|
||||
|
@ -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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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`.
|
||||
|
@ -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<imm>╼ │ ╾──╼
|
||||
}
|
||||
|
||||
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<imm>╼ │ ╾──╼
|
||||
}
|
||||
|
||||
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<imm>╼ │ ╾──╼
|
||||
}
|
||||
| ^^^^^^^ 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`.
|
||||
|
@ -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<imm>╼ │ ╾──────╼
|
||||
}
|
||||
|
||||
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<imm>╼ │ ╾──────╼
|
||||
}
|
||||
|
||||
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<imm>╼ │ ╾──────╼
|
||||
}
|
||||
| ^^^^^^^ 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`.
|
||||
|
@ -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() {}
|
||||
|
@ -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<imm>╼ │ ╾──╼
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
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<imm>╼ │ ╾──╼
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
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 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -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<imm>╼ │ ╾──────╼
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
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<imm>╼ │ ╾──────╼
|
||||
}
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
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 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -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!(),
|
||||
}
|
||||
|
@ -38,55 +38,50 @@ LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const
|
||||
╾ALLOC1<imm>╼ │ ╾──╼
|
||||
}
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/mutable_references_err.rs:47:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/mutable_references_err.rs:48:33
|
||||
|
|
||||
LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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<imm>╼ │ ╾──╼
|
||||
}
|
||||
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<AtomicI32> = 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<i32> = 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<i32> = 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 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
|
||||
|
|
||||
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<AtomicI32> = 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<i32> = 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<i32> = SyncPtr { x: &mut 0 };
|
||||
| ^^^^^^
|
||||
|
@ -38,55 +38,50 @@ LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const
|
||||
╾ALLOC1<imm>╼ │ ╾──────╼
|
||||
}
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/mutable_references_err.rs:47:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/mutable_references_err.rs:48:33
|
||||
|
|
||||
LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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<imm>╼ │ ╾──────╼
|
||||
}
|
||||
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<AtomicI32> = 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<i32> = 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<i32> = 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 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
|
||||
|
|
||||
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<AtomicI32> = 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<i32> = 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<i32> = SyncPtr { x: &mut 0 };
|
||||
| ^^^^^^
|
||||
|
@ -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
|
||||
|
@ -1,4 +0,0 @@
|
||||
static X: i32 = 42;
|
||||
const Y: i32 = X; //~ ERROR constants cannot refer to statics [E0013]
|
||||
|
||||
fn main() {}
|
@ -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`.
|
12
tests/ui/feature-gates/feature-gate-const-refs-to-static.rs
Normal file
12
tests/ui/feature-gates/feature-gate-const-refs-to-static.rs
Normal file
@ -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() {
|
||||
}
|
@ -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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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`.
|
@ -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
|
||||
};
|
||||
}
|
||||
|
@ -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 <https://github.com/rust-lang/rust/issues/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`.
|
||||
|
@ -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() {}
|
||||
|
@ -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 <https://github.com/rust-lang/rust/issues/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`.
|
||||
|
Loading…
Reference in New Issue
Block a user