const-eval interning: accpt interior mutable pointers in final value (but keep rejecting mutable references)
This commit is contained in:
parent
304b7f801b
commit
f76f128dc9
21 changed files with 177 additions and 563 deletions
|
@ -538,8 +538,9 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
// final value.
|
// final value.
|
||||||
// Note: This is only sound if every local that has a `StorageDead` has a
|
// Note: This is only sound if every local that has a `StorageDead` has a
|
||||||
// `StorageDead` in every control flow path leading to a `return` terminator.
|
// `StorageDead` in every control flow path leading to a `return` terminator.
|
||||||
// The good news is that interning will detect if any unexpected mutable
|
// If anything slips through, there's no safety net -- safe code can create
|
||||||
// pointer slips through.
|
// references to variants of `!Freeze` enums as long as that variant is `Freeze`,
|
||||||
|
// so interning can't protect us here.
|
||||||
if self.local_is_transient(place.local) {
|
if self.local_is_transient(place.local) {
|
||||||
self.check_op(ops::TransientCellBorrow);
|
self.check_op(ops::TransientCellBorrow);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -10,7 +10,6 @@ use rustc_middle::traits::Reveal;
|
||||||
use rustc_middle::ty::layout::LayoutOf;
|
use rustc_middle::ty::layout::LayoutOf;
|
||||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_session::lint;
|
|
||||||
use rustc_span::def_id::LocalDefId;
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
use rustc_target::abi::{self, Abi};
|
use rustc_target::abi::{self, Abi};
|
||||||
|
@ -18,13 +17,12 @@ use tracing::{debug, instrument, trace};
|
||||||
|
|
||||||
use super::{CanAccessMutGlobal, CompileTimeInterpCx, CompileTimeMachine};
|
use super::{CanAccessMutGlobal, CompileTimeInterpCx, CompileTimeMachine};
|
||||||
use crate::const_eval::CheckAlignment;
|
use crate::const_eval::CheckAlignment;
|
||||||
use crate::errors::{self, ConstEvalError, DanglingPtrInFinal};
|
|
||||||
use crate::interpret::{
|
use crate::interpret::{
|
||||||
create_static_alloc, eval_nullary_intrinsic, intern_const_alloc_recursive, throw_exhaust,
|
create_static_alloc, eval_nullary_intrinsic, intern_const_alloc_recursive, throw_exhaust,
|
||||||
CtfeValidationMode, GlobalId, Immediate, InternKind, InternResult, InterpCx, InterpError,
|
CtfeValidationMode, GlobalId, Immediate, InternKind, InternResult, InterpCx, InterpError,
|
||||||
InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, StackPopCleanup,
|
InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, StackPopCleanup,
|
||||||
};
|
};
|
||||||
use crate::CTRL_C_RECEIVED;
|
use crate::{errors, CTRL_C_RECEIVED};
|
||||||
|
|
||||||
// Returns a pointer to where the result lives
|
// Returns a pointer to where the result lives
|
||||||
#[instrument(level = "trace", skip(ecx, body))]
|
#[instrument(level = "trace", skip(ecx, body))]
|
||||||
|
@ -105,18 +103,15 @@ fn eval_body_using_ecx<'tcx, R: InterpretationResult<'tcx>>(
|
||||||
return Err(ecx
|
return Err(ecx
|
||||||
.tcx
|
.tcx
|
||||||
.dcx()
|
.dcx()
|
||||||
.emit_err(DanglingPtrInFinal { span: ecx.tcx.span, kind: intern_kind })
|
.emit_err(errors::DanglingPtrInFinal { span: ecx.tcx.span, kind: intern_kind })
|
||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
Err(InternResult::FoundBadMutablePointer) => {
|
Err(InternResult::FoundBadMutablePointer) => {
|
||||||
// only report mutable pointers if there were no dangling pointers
|
return Err(ecx
|
||||||
let err_diag = errors::MutablePtrInFinal { span: ecx.tcx.span, kind: intern_kind };
|
.tcx
|
||||||
ecx.tcx.emit_node_span_lint(
|
.dcx()
|
||||||
lint::builtin::CONST_EVAL_MUTABLE_PTR_IN_FINAL_VALUE,
|
.emit_err(errors::MutablePtrInFinal { span: ecx.tcx.span, kind: intern_kind })
|
||||||
ecx.machine.best_lint_scope(*ecx.tcx),
|
.into());
|
||||||
err_diag.span,
|
|
||||||
err_diag,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -448,7 +443,12 @@ fn report_eval_error<'tcx>(
|
||||||
error,
|
error,
|
||||||
DUMMY_SP,
|
DUMMY_SP,
|
||||||
|| super::get_span_and_frames(ecx.tcx, ecx.stack()),
|
|| super::get_span_and_frames(ecx.tcx, ecx.stack()),
|
||||||
|span, frames| ConstEvalError { span, error_kind: kind, instance, frame_notes: frames },
|
|span, frames| errors::ConstEvalError {
|
||||||
|
span,
|
||||||
|
error_kind: kind,
|
||||||
|
instance,
|
||||||
|
frame_notes: frames,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -718,16 +718,29 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
|
||||||
_kind: mir::RetagKind,
|
_kind: mir::RetagKind,
|
||||||
val: &ImmTy<'tcx, CtfeProvenance>,
|
val: &ImmTy<'tcx, CtfeProvenance>,
|
||||||
) -> InterpResult<'tcx, ImmTy<'tcx, CtfeProvenance>> {
|
) -> InterpResult<'tcx, ImmTy<'tcx, CtfeProvenance>> {
|
||||||
// If it's a frozen shared reference that's not already immutable, make it immutable.
|
// If it's a frozen shared reference that's not already immutable, potentially make it immutable.
|
||||||
// (Do nothing on `None` provenance, that cannot store immutability anyway.)
|
// (Do nothing on `None` provenance, that cannot store immutability anyway.)
|
||||||
if let ty::Ref(_, ty, mutbl) = val.layout.ty.kind()
|
if let ty::Ref(_, ty, mutbl) = val.layout.ty.kind()
|
||||||
&& *mutbl == Mutability::Not
|
&& *mutbl == Mutability::Not
|
||||||
&& val.to_scalar_and_meta().0.to_pointer(ecx)?.provenance.is_some_and(|p| !p.immutable())
|
&& val
|
||||||
// That next check is expensive, that's why we have all the guards above.
|
.to_scalar_and_meta()
|
||||||
&& ty.is_freeze(*ecx.tcx, ecx.param_env)
|
.0
|
||||||
|
.to_pointer(ecx)?
|
||||||
|
.provenance
|
||||||
|
.is_some_and(|p| !p.immutable())
|
||||||
{
|
{
|
||||||
|
// That next check is expensive, that's why we have all the guards above.
|
||||||
|
let is_immutable = ty.is_freeze(*ecx.tcx, ecx.param_env);
|
||||||
let place = ecx.ref_to_mplace(val)?;
|
let place = ecx.ref_to_mplace(val)?;
|
||||||
let new_place = place.map_provenance(CtfeProvenance::as_immutable);
|
let new_place = if is_immutable {
|
||||||
|
place.map_provenance(CtfeProvenance::as_immutable)
|
||||||
|
} else {
|
||||||
|
// Even if it is not immutable, remember that it is a shared reference.
|
||||||
|
// This allows it to become part of the final value of the constant.
|
||||||
|
// (See <https://github.com/rust-lang/rust/pull/128543> for why we allow this
|
||||||
|
// even when there is interior mutability.)
|
||||||
|
place.map_provenance(CtfeProvenance::as_shared_ref)
|
||||||
|
};
|
||||||
Ok(ImmTy::from_immediate(new_place.to_ref(ecx), val.layout))
|
Ok(ImmTy::from_immediate(new_place.to_ref(ecx), val.layout))
|
||||||
} else {
|
} else {
|
||||||
Ok(val.clone())
|
Ok(val.clone())
|
||||||
|
|
|
@ -35,13 +35,10 @@ pub(crate) struct NestedStaticInThreadLocal {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(LintDiagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(const_eval_mutable_ptr_in_final)]
|
#[diag(const_eval_mutable_ptr_in_final)]
|
||||||
pub(crate) struct MutablePtrInFinal {
|
pub(crate) struct MutablePtrInFinal {
|
||||||
// rust-lang/rust#122153: This was marked as `#[primary_span]` under
|
#[primary_span]
|
||||||
// `derive(Diagnostic)`. Since we expect we may hard-error in future, we are
|
|
||||||
// keeping the field (and skipping it under `derive(LintDiagnostic)`).
|
|
||||||
#[skip_arg]
|
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub kind: InternKind,
|
pub kind: InternKind,
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,16 +223,20 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx, const_eval
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crucially, we check this *before* checking whether the `alloc_id`
|
// Ensure that this is is derived from a shared reference. Crucially, we check this *before*
|
||||||
// has already been interned. The point of this check is to ensure that when
|
// checking whether the `alloc_id` has already been interned. The point of this check is to
|
||||||
// there are multiple pointers to the same allocation, they are *all* immutable.
|
// ensure that when there are multiple pointers to the same allocation, they are *all*
|
||||||
// Therefore it would be bad if we only checked the first pointer to any given
|
// derived from a shared reference. Therefore it would be bad if we only checked the first
|
||||||
// allocation.
|
// pointer to any given allocation.
|
||||||
// (It is likely not possible to actually have multiple pointers to the same allocation,
|
// (It is likely not possible to actually have multiple pointers to the same allocation,
|
||||||
// so alternatively we could also check that and ICE if there are multiple such pointers.)
|
// so alternatively we could also check that and ICE if there are multiple such pointers.)
|
||||||
|
// See <https://github.com/rust-lang/rust/pull/128543> for why we are checking for
|
||||||
|
// "shared reference" and not "immutable", i.e., for why we are allowed interior-mutable
|
||||||
|
// shared references: they can actually be created in safe code while pointing to apparently
|
||||||
|
// "immutable" values, via promotion of `&None::<Cell<T>>`.
|
||||||
if intern_kind != InternKind::Promoted
|
if intern_kind != InternKind::Promoted
|
||||||
&& inner_mutability == Mutability::Not
|
&& inner_mutability == Mutability::Not
|
||||||
&& !prov.immutable()
|
&& !prov.shared_ref()
|
||||||
{
|
{
|
||||||
if ecx.tcx.try_get_global_alloc(alloc_id).is_some()
|
if ecx.tcx.try_get_global_alloc(alloc_id).is_some()
|
||||||
&& !just_interned.contains(&alloc_id)
|
&& !just_interned.contains(&alloc_id)
|
||||||
|
@ -245,7 +249,7 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx, const_eval
|
||||||
// this to the todo list, since after all it is already interned.
|
// this to the todo list, since after all it is already interned.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Found a mutable pointer inside a const where inner allocations should be
|
// Found a mutable reference inside a const where inner allocations should be
|
||||||
// immutable. We exclude promoteds from this, since things like `&mut []` and
|
// immutable. We exclude promoteds from this, since things like `&mut []` and
|
||||||
// `&None::<Cell<i32>>` lead to promotion that can produce mutable pointers. We rely
|
// `&None::<Cell<i32>>` lead to promotion that can produce mutable pointers. We rely
|
||||||
// on the promotion analysis not screwing up to ensure that it is sound to intern
|
// on the promotion analysis not screwing up to ensure that it is sound to intern
|
||||||
|
|
|
@ -576,6 +576,10 @@ fn register_builtins(store: &mut LintStore) {
|
||||||
<https://github.com/rust-lang/rust/issues/107457> for more information",
|
<https://github.com/rust-lang/rust/issues/107457> for more information",
|
||||||
);
|
);
|
||||||
store.register_removed("writes_through_immutable_pointer", "converted into hard error");
|
store.register_removed("writes_through_immutable_pointer", "converted into hard error");
|
||||||
|
store.register_removed(
|
||||||
|
"const_eval_mutable_ptr_in_final_value",
|
||||||
|
"partially allowed now, otherwise turned into a hard error",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_internals(store: &mut LintStore) {
|
fn register_internals(store: &mut LintStore) {
|
||||||
|
|
|
@ -29,7 +29,6 @@ declare_lint_pass! {
|
||||||
CENUM_IMPL_DROP_CAST,
|
CENUM_IMPL_DROP_CAST,
|
||||||
COHERENCE_LEAK_CHECK,
|
COHERENCE_LEAK_CHECK,
|
||||||
CONFLICTING_REPR_HINTS,
|
CONFLICTING_REPR_HINTS,
|
||||||
CONST_EVAL_MUTABLE_PTR_IN_FINAL_VALUE,
|
|
||||||
CONST_EVALUATABLE_UNCHECKED,
|
CONST_EVALUATABLE_UNCHECKED,
|
||||||
CONST_ITEM_MUTATION,
|
CONST_ITEM_MUTATION,
|
||||||
DEAD_CODE,
|
DEAD_CODE,
|
||||||
|
@ -2804,51 +2803,6 @@ declare_lint! {
|
||||||
@feature_gate = strict_provenance;
|
@feature_gate = strict_provenance;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
|
||||||
/// The `const_eval_mutable_ptr_in_final_value` lint detects if a mutable pointer
|
|
||||||
/// has leaked into the final value of a const expression.
|
|
||||||
///
|
|
||||||
/// ### Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// pub enum JsValue {
|
|
||||||
/// Undefined,
|
|
||||||
/// Object(std::cell::Cell<bool>),
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// impl ::std::ops::Drop for JsValue {
|
|
||||||
/// fn drop(&mut self) {}
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// const UNDEFINED: &JsValue = &JsValue::Undefined;
|
|
||||||
///
|
|
||||||
/// fn main() {
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// {{produces}}
|
|
||||||
///
|
|
||||||
/// ### Explanation
|
|
||||||
///
|
|
||||||
/// In the 1.77 release, the const evaluation machinery adopted some
|
|
||||||
/// stricter rules to reject expressions with values that could
|
|
||||||
/// end up holding mutable references to state stored in static memory
|
|
||||||
/// (which is inherently immutable).
|
|
||||||
///
|
|
||||||
/// This is a [future-incompatible] lint to ease the transition to an error.
|
|
||||||
/// See [issue #122153] for more details.
|
|
||||||
///
|
|
||||||
/// [issue #122153]: https://github.com/rust-lang/rust/issues/122153
|
|
||||||
/// [future-incompatible]: ../index.md#future-incompatible-lints
|
|
||||||
pub CONST_EVAL_MUTABLE_PTR_IN_FINAL_VALUE,
|
|
||||||
Warn,
|
|
||||||
"detects a mutable pointer that has leaked into final value of a const expression",
|
|
||||||
@future_incompatible = FutureIncompatibleInfo {
|
|
||||||
reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
|
|
||||||
reference: "issue #122153 <https://github.com/rust-lang/rust/issues/122153>",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// The `const_evaluatable_unchecked` lint detects a generic constant used
|
/// The `const_evaluatable_unchecked` lint detects a generic constant used
|
||||||
/// in a type.
|
/// in a type.
|
||||||
|
|
|
@ -80,14 +80,23 @@ pub trait Provenance: Copy + fmt::Debug + 'static {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The type of provenance in the compile-time interpreter.
|
/// The type of provenance in the compile-time interpreter.
|
||||||
/// This is a packed representation of an `AllocId` and an `immutable: bool`.
|
/// This is a packed representation of:
|
||||||
|
/// - an `AllocId` (non-zero)
|
||||||
|
/// - an `immutable: bool`
|
||||||
|
/// - a `shared_ref: bool`
|
||||||
|
///
|
||||||
|
/// with the extra invariant that if `immutable` is `true`, then so
|
||||||
|
/// is `shared_ref`.
|
||||||
#[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
#[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||||
pub struct CtfeProvenance(NonZero<u64>);
|
pub struct CtfeProvenance(NonZero<u64>);
|
||||||
|
|
||||||
impl From<AllocId> for CtfeProvenance {
|
impl From<AllocId> for CtfeProvenance {
|
||||||
fn from(value: AllocId) -> Self {
|
fn from(value: AllocId) -> Self {
|
||||||
let prov = CtfeProvenance(value.0);
|
let prov = CtfeProvenance(value.0);
|
||||||
assert!(!prov.immutable(), "`AllocId` with the highest bit set cannot be used in CTFE");
|
assert!(
|
||||||
|
prov.alloc_id() == value,
|
||||||
|
"`AllocId` with the highest bits set cannot be used in CTFE"
|
||||||
|
);
|
||||||
prov
|
prov
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,12 +112,14 @@ impl fmt::Debug for CtfeProvenance {
|
||||||
}
|
}
|
||||||
|
|
||||||
const IMMUTABLE_MASK: u64 = 1 << 63; // the highest bit
|
const IMMUTABLE_MASK: u64 = 1 << 63; // the highest bit
|
||||||
|
const SHARED_REF_MASK: u64 = 1 << 62;
|
||||||
|
const ALLOC_ID_MASK: u64 = u64::MAX & !IMMUTABLE_MASK & !SHARED_REF_MASK;
|
||||||
|
|
||||||
impl CtfeProvenance {
|
impl CtfeProvenance {
|
||||||
/// Returns the `AllocId` of this provenance.
|
/// Returns the `AllocId` of this provenance.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn alloc_id(self) -> AllocId {
|
pub fn alloc_id(self) -> AllocId {
|
||||||
AllocId(NonZero::new(self.0.get() & !IMMUTABLE_MASK).unwrap())
|
AllocId(NonZero::new(self.0.get() & ALLOC_ID_MASK).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether this provenance is immutable.
|
/// Returns whether this provenance is immutable.
|
||||||
|
@ -117,10 +128,38 @@ impl CtfeProvenance {
|
||||||
self.0.get() & IMMUTABLE_MASK != 0
|
self.0.get() & IMMUTABLE_MASK != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether this provenance is derived from a shared reference.
|
||||||
|
#[inline]
|
||||||
|
pub fn shared_ref(self) -> bool {
|
||||||
|
self.0.get() & SHARED_REF_MASK != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_parts(self) -> (AllocId, bool, bool) {
|
||||||
|
(self.alloc_id(), self.immutable(), self.shared_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_parts((alloc_id, immutable, shared_ref): (AllocId, bool, bool)) -> Self {
|
||||||
|
let prov = CtfeProvenance::from(alloc_id);
|
||||||
|
if immutable {
|
||||||
|
// This sets both flags, so we don't even have to check `shared_ref`.
|
||||||
|
prov.as_immutable()
|
||||||
|
} else if shared_ref {
|
||||||
|
prov.as_shared_ref()
|
||||||
|
} else {
|
||||||
|
prov
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns an immutable version of this provenance.
|
/// Returns an immutable version of this provenance.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_immutable(self) -> Self {
|
pub fn as_immutable(self) -> Self {
|
||||||
CtfeProvenance(self.0 | IMMUTABLE_MASK)
|
CtfeProvenance(self.0 | IMMUTABLE_MASK | SHARED_REF_MASK)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a "shared reference" (but not necessarily immutable!) version of this provenance.
|
||||||
|
#[inline]
|
||||||
|
pub fn as_shared_ref(self) -> Self {
|
||||||
|
CtfeProvenance(self.0 | SHARED_REF_MASK)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -165,8 +165,7 @@ impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for AllocId {
|
||||||
|
|
||||||
impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for CtfeProvenance {
|
impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for CtfeProvenance {
|
||||||
fn encode(&self, e: &mut E) {
|
fn encode(&self, e: &mut E) {
|
||||||
self.alloc_id().encode(e);
|
self.into_parts().encode(e);
|
||||||
self.immutable().encode(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,10 +294,8 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for AllocId {
|
||||||
|
|
||||||
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for CtfeProvenance {
|
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for CtfeProvenance {
|
||||||
fn decode(decoder: &mut D) -> Self {
|
fn decode(decoder: &mut D) -> Self {
|
||||||
let alloc_id: AllocId = Decodable::decode(decoder);
|
let parts = Decodable::decode(decoder);
|
||||||
let prov = CtfeProvenance::from(alloc_id);
|
CtfeProvenance::from_parts(parts)
|
||||||
let immutable: bool = Decodable::decode(decoder);
|
|
||||||
if immutable { prov.as_immutable() } else { prov }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,11 +75,9 @@ impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CtfeProvenance is an AllocId and a bool.
|
|
||||||
impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::CtfeProvenance {
|
impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::CtfeProvenance {
|
||||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
||||||
self.alloc_id().hash_stable(hcx, hasher);
|
self.into_parts().hash_stable(hcx, hasher);
|
||||||
self.immutable().hash_stable(hcx, hasher);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
#![feature(const_heap)]
|
#![feature(const_heap)]
|
||||||
#![feature(const_mut_refs)]
|
#![feature(const_mut_refs)]
|
||||||
#![deny(const_eval_mutable_ptr_in_final_value)]
|
|
||||||
use std::intrinsics;
|
use std::intrinsics;
|
||||||
|
|
||||||
const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32 };
|
const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32 };
|
||||||
//~^ error: mutable pointer in final value of constant
|
//~^ error: mutable pointer in final value of constant
|
||||||
//~| WARNING this was previously accepted by the compiler
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,31 +1,8 @@
|
||||||
error: encountered mutable pointer in final value of constant
|
error: encountered mutable pointer in final value of constant
|
||||||
--> $DIR/alloc_intrinsic_untyped.rs:7:1
|
--> $DIR/alloc_intrinsic_untyped.rs:6:1
|
||||||
|
|
|
|
||||||
LL | const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32 };
|
LL | const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/alloc_intrinsic_untyped.rs:4:9
|
|
||||||
|
|
|
||||||
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
Future incompatibility report: Future breakage diagnostic:
|
|
||||||
error: encountered mutable pointer in final value of constant
|
|
||||||
--> $DIR/alloc_intrinsic_untyped.rs:7:1
|
|
||||||
|
|
|
||||||
LL | const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32 };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/alloc_intrinsic_untyped.rs:4:9
|
|
||||||
|
|
|
||||||
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
//@ check-pass
|
|
||||||
use std::cell::Cell;
|
|
||||||
|
|
||||||
pub enum JsValue {
|
|
||||||
Undefined,
|
|
||||||
Object(Cell<bool>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::std::ops::Drop for JsValue {
|
|
||||||
fn drop(&mut self) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
const UNDEFINED: &JsValue = &JsValue::Undefined;
|
|
||||||
//~^ WARN encountered mutable pointer in final value of constant
|
|
||||||
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
warning: encountered mutable pointer in final value of constant
|
|
||||||
--> $DIR/future-incompat-mutable-in-final-value-issue-121610.rs:13:1
|
|
||||||
|
|
|
||||||
LL | const UNDEFINED: &JsValue = &JsValue::Undefined;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
= note: `#[warn(const_eval_mutable_ptr_in_final_value)]` on by default
|
|
||||||
|
|
||||||
warning: 1 warning emitted
|
|
||||||
|
|
||||||
Future incompatibility report: Future breakage diagnostic:
|
|
||||||
warning: encountered mutable pointer in final value of constant
|
|
||||||
--> $DIR/future-incompat-mutable-in-final-value-issue-121610.rs:13:1
|
|
||||||
|
|
|
||||||
LL | const UNDEFINED: &JsValue = &JsValue::Undefined;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
= note: `#[warn(const_eval_mutable_ptr_in_final_value)]` on by default
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP"
|
//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP"
|
||||||
|
|
||||||
#![allow(static_mut_refs)]
|
#![allow(static_mut_refs)]
|
||||||
#![deny(const_eval_mutable_ptr_in_final_value)]
|
|
||||||
use std::cell::UnsafeCell;
|
use std::cell::UnsafeCell;
|
||||||
use std::sync::atomic::*;
|
use std::sync::atomic::*;
|
||||||
|
|
||||||
|
@ -18,13 +17,11 @@ static OH_YES: &mut i32 = &mut 42;
|
||||||
//~| pointing to read-only memory
|
//~| pointing to read-only memory
|
||||||
static BAR: &mut () = &mut ();
|
static BAR: &mut () = &mut ();
|
||||||
//~^ ERROR encountered mutable pointer in final value of static
|
//~^ ERROR encountered mutable pointer in final value of static
|
||||||
//~| WARNING this was previously accepted by the compiler
|
|
||||||
|
|
||||||
struct Foo<T>(T);
|
struct Foo<T>(T);
|
||||||
|
|
||||||
static BOO: &mut Foo<()> = &mut Foo(());
|
static BOO: &mut Foo<()> = &mut Foo(());
|
||||||
//~^ ERROR encountered mutable pointer in final value of static
|
//~^ ERROR encountered mutable pointer in final value of static
|
||||||
//~| WARNING this was previously accepted by the compiler
|
|
||||||
|
|
||||||
const BLUNT: &mut i32 = &mut 42;
|
const BLUNT: &mut i32 = &mut 42;
|
||||||
//~^ ERROR: it is undefined behavior to use this value
|
//~^ ERROR: it is undefined behavior to use this value
|
||||||
|
@ -81,36 +78,32 @@ const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
|
||||||
|
|
||||||
const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _;
|
const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _;
|
||||||
//~^ ERROR: mutable pointer in final value
|
//~^ ERROR: mutable pointer in final value
|
||||||
//~| WARNING this was previously accepted by the compiler
|
|
||||||
|
|
||||||
const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _;
|
const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _;
|
||||||
//~^ ERROR: mutable pointer in final value
|
//~^ ERROR: mutable pointer in final value
|
||||||
//~| WARNING this was previously accepted by the compiler
|
|
||||||
|
|
||||||
|
// This does *not* error since it uses a shared reference, and we have to ignore
|
||||||
|
// those. See <https://github.com/rust-lang/rust/pull/128543>.
|
||||||
const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
|
const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
|
||||||
//~^ ERROR: mutable pointer in final value
|
|
||||||
//~| WARNING this was previously accepted by the compiler
|
|
||||||
|
|
||||||
struct SyncPtr<T> {
|
struct SyncPtr<T> {
|
||||||
x: *const T,
|
x: *const T,
|
||||||
}
|
}
|
||||||
unsafe impl<T> Sync for SyncPtr<T> {}
|
unsafe impl<T> Sync for SyncPtr<T> {}
|
||||||
|
|
||||||
// These pass the lifetime checks because of the "tail expression" / "outer scope" rule.
|
// These pass the lifetime checks because of the "tail expression" / "outer scope" rule. (This
|
||||||
// (This relies on `SyncPtr` being a curly brace struct.)
|
// relies on `SyncPtr` being a curly brace struct.) However, we intern the inner memory as
|
||||||
// However, we intern the inner memory as read-only, so this must be rejected.
|
// read-only, so ideally this should be rejected. Unfortunately, as explained in
|
||||||
|
// <https://github.com/rust-lang/rust/pull/128543>, we have to accept it.
|
||||||
// (Also see `static-no-inner-mut` for similar tests on `static`.)
|
// (Also see `static-no-inner-mut` for similar tests on `static`.)
|
||||||
const RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
|
const RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
|
||||||
//~^ ERROR mutable pointer in final value
|
|
||||||
//~| WARNING this was previously accepted by the compiler
|
|
||||||
|
|
||||||
|
// With mutable references at least, we can detect this and error.
|
||||||
const RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x: &mut 42 as *mut _ as *const _ };
|
const RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x: &mut 42 as *mut _ as *const _ };
|
||||||
//~^ ERROR mutable pointer in final value
|
//~^ ERROR mutable pointer in final value
|
||||||
//~| WARNING this was previously accepted by the compiler
|
|
||||||
|
|
||||||
const RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
|
const RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
|
||||||
//~^ ERROR mutable pointer in final value
|
//~^ ERROR mutable pointer in final value
|
||||||
//~| WARNING this was previously accepted by the compiler
|
|
||||||
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0080]: it is undefined behavior to use this value
|
error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/mutable_references.rs:13:1
|
--> $DIR/mutable_references.rs:12:1
|
||||||
|
|
|
|
||||||
LL | static FOO: &&mut u32 = &&mut 42;
|
LL | static FOO: &&mut u32 = &&mut 42;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered mutable reference or box pointing to read-only memory
|
| ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered mutable reference or box pointing to read-only memory
|
||||||
|
@ -10,7 +10,7 @@ LL | static FOO: &&mut u32 = &&mut 42;
|
||||||
}
|
}
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/mutable_references.rs:16:1
|
--> $DIR/mutable_references.rs:15:1
|
||||||
|
|
|
|
||||||
LL | static OH_YES: &mut i32 = &mut 42;
|
LL | static OH_YES: &mut i32 = &mut 42;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory
|
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory
|
||||||
|
@ -21,30 +21,19 @@ LL | static OH_YES: &mut i32 = &mut 42;
|
||||||
}
|
}
|
||||||
|
|
||||||
error: encountered mutable pointer in final value of static
|
error: encountered mutable pointer in final value of static
|
||||||
--> $DIR/mutable_references.rs:19:1
|
--> $DIR/mutable_references.rs:18:1
|
||||||
|
|
|
|
||||||
LL | static BAR: &mut () = &mut ();
|
LL | static BAR: &mut () = &mut ();
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/mutable_references.rs:6:9
|
|
||||||
|
|
|
||||||
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: encountered mutable pointer in final value of static
|
error: encountered mutable pointer in final value of static
|
||||||
--> $DIR/mutable_references.rs:25:1
|
--> $DIR/mutable_references.rs:23:1
|
||||||
|
|
|
|
||||||
LL | static BOO: &mut Foo<()> = &mut Foo(());
|
LL | static BOO: &mut Foo<()> = &mut Foo(());
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/mutable_references.rs:29:1
|
--> $DIR/mutable_references.rs:26:1
|
||||||
|
|
|
|
||||||
LL | const BLUNT: &mut i32 = &mut 42;
|
LL | const BLUNT: &mut i32 = &mut 42;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory
|
| ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory
|
||||||
|
@ -55,7 +44,7 @@ LL | const BLUNT: &mut i32 = &mut 42;
|
||||||
}
|
}
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/mutable_references.rs:33:1
|
--> $DIR/mutable_references.rs:30:1
|
||||||
|
|
|
|
||||||
LL | const SUBTLE: &mut i32 = unsafe { static mut STATIC: i32 = 0; &mut STATIC };
|
LL | const SUBTLE: &mut i32 = unsafe { static mut STATIC: i32 = 0; &mut STATIC };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const`
|
| ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const`
|
||||||
|
@ -66,7 +55,7 @@ LL | const SUBTLE: &mut i32 = unsafe { static mut STATIC: i32 = 0; &mut STATIC }
|
||||||
}
|
}
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/mutable_references.rs:43:1
|
--> $DIR/mutable_references.rs:40:1
|
||||||
|
|
|
|
||||||
LL | static MEH: Meh = Meh { x: &UnsafeCell::new(42) };
|
LL | static MEH: Meh = Meh { x: &UnsafeCell::new(42) };
|
||||||
| ^^^^^^^^^^^^^^^ constructing invalid value at .x.<deref>: encountered `UnsafeCell` in read-only memory
|
| ^^^^^^^^^^^^^^^ constructing invalid value at .x.<deref>: encountered `UnsafeCell` in read-only memory
|
||||||
|
@ -77,7 +66,7 @@ LL | static MEH: Meh = Meh { x: &UnsafeCell::new(42) };
|
||||||
}
|
}
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/mutable_references.rs:49:1
|
--> $DIR/mutable_references.rs:46:1
|
||||||
|
|
|
|
||||||
LL | const MUH: Meh = Meh {
|
LL | const MUH: Meh = Meh {
|
||||||
| ^^^^^^^^^^^^^^ constructing invalid value at .x.<deref>: encountered `UnsafeCell` in read-only memory
|
| ^^^^^^^^^^^^^^ constructing invalid value at .x.<deref>: encountered `UnsafeCell` in read-only memory
|
||||||
|
@ -88,7 +77,7 @@ LL | const MUH: Meh = Meh {
|
||||||
}
|
}
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/mutable_references.rs:61:1
|
--> $DIR/mutable_references.rs:58:1
|
||||||
|
|
|
|
||||||
LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) };
|
LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.<dyn-downcast>.x: encountered `UnsafeCell` in read-only memory
|
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.<dyn-downcast>.x: encountered `UnsafeCell` in read-only memory
|
||||||
|
@ -99,7 +88,7 @@ LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) };
|
||||||
}
|
}
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/mutable_references.rs:68:1
|
--> $DIR/mutable_references.rs:65:1
|
||||||
|
|
|
|
||||||
LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
|
LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory
|
||||||
|
@ -110,7 +99,7 @@ LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const
|
||||||
}
|
}
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/mutable_references.rs:75:1
|
--> $DIR/mutable_references.rs:72:1
|
||||||
|
|
|
|
||||||
LL | const POINTS_TO_MUTABLE: &i32 = unsafe { &MUTABLE };
|
LL | const POINTS_TO_MUTABLE: &i32 = unsafe { &MUTABLE };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const`
|
||||||
|
@ -121,67 +110,37 @@ LL | const POINTS_TO_MUTABLE: &i32 = unsafe { &MUTABLE };
|
||||||
}
|
}
|
||||||
|
|
||||||
error[E0080]: evaluation of constant value failed
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/mutable_references.rs:78:43
|
--> $DIR/mutable_references.rs:75:43
|
||||||
|
|
|
|
||||||
LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
|
LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
|
||||||
| ^^^^^^^^^^^^^ constant accesses mutable global memory
|
| ^^^^^^^^^^^^^ constant accesses mutable global memory
|
||||||
|
|
||||||
error: encountered mutable pointer in final value of constant
|
error: encountered mutable pointer in final value of constant
|
||||||
--> $DIR/mutable_references.rs:82:1
|
--> $DIR/mutable_references.rs:79:1
|
||||||
|
|
|
|
||||||
LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _;
|
LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
|
|
||||||
error: encountered mutable pointer in final value of constant
|
error: encountered mutable pointer in final value of constant
|
||||||
--> $DIR/mutable_references.rs:86:1
|
--> $DIR/mutable_references.rs:82:1
|
||||||
|
|
|
|
||||||
LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _;
|
LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
|
|
||||||
error: encountered mutable pointer in final value of constant
|
error: encountered mutable pointer in final value of constant
|
||||||
--> $DIR/mutable_references.rs:90:1
|
--> $DIR/mutable_references.rs:102:1
|
||||||
|
|
|
||||||
LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
|
|
||||||
error: encountered mutable pointer in final value of constant
|
|
||||||
--> $DIR/mutable_references.rs:103:1
|
|
||||||
|
|
|
||||||
LL | const RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
|
|
||||||
error: encountered mutable pointer in final value of constant
|
|
||||||
--> $DIR/mutable_references.rs:107:1
|
|
||||||
|
|
|
|
||||||
LL | const RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x: &mut 42 as *mut _ as *const _ };
|
LL | const RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x: &mut 42 as *mut _ as *const _ };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
|
|
||||||
error: encountered mutable pointer in final value of constant
|
error: encountered mutable pointer in final value of constant
|
||||||
--> $DIR/mutable_references.rs:111:1
|
--> $DIR/mutable_references.rs:105:1
|
||||||
|
|
|
|
||||||
LL | const RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
|
LL | const RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
|
|
||||||
error[E0594]: cannot assign to `*OH_YES`, as `OH_YES` is an immutable static item
|
error[E0594]: cannot assign to `*OH_YES`, as `OH_YES` is an immutable static item
|
||||||
--> $DIR/mutable_references.rs:120:5
|
--> $DIR/mutable_references.rs:113:5
|
||||||
|
|
|
|
||||||
LL | *OH_YES = 99;
|
LL | *OH_YES = 99;
|
||||||
| ^^^^^^^^^^^^ cannot assign
|
| ^^^^^^^^^^^^ cannot assign
|
||||||
|
@ -189,227 +148,107 @@ LL | *OH_YES = 99;
|
||||||
warning: skipping const checks
|
warning: skipping const checks
|
||||||
|
|
|
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/mutable_references.rs:13:26
|
--> $DIR/mutable_references.rs:12:26
|
||||||
|
|
|
|
||||||
LL | static FOO: &&mut u32 = &&mut 42;
|
LL | static FOO: &&mut u32 = &&mut 42;
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/mutable_references.rs:16:27
|
--> $DIR/mutable_references.rs:15:27
|
||||||
|
|
|
|
||||||
LL | static OH_YES: &mut i32 = &mut 42;
|
LL | static OH_YES: &mut i32 = &mut 42;
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/mutable_references.rs:19:23
|
--> $DIR/mutable_references.rs:18:23
|
||||||
|
|
|
|
||||||
LL | static BAR: &mut () = &mut ();
|
LL | static BAR: &mut () = &mut ();
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/mutable_references.rs:25:28
|
--> $DIR/mutable_references.rs:23:28
|
||||||
|
|
|
|
||||||
LL | static BOO: &mut Foo<()> = &mut Foo(());
|
LL | static BOO: &mut Foo<()> = &mut Foo(());
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/mutable_references.rs:29:25
|
--> $DIR/mutable_references.rs:26:25
|
||||||
|
|
|
|
||||||
LL | const BLUNT: &mut i32 = &mut 42;
|
LL | const BLUNT: &mut i32 = &mut 42;
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
help: skipping check for `const_refs_to_static` feature
|
help: skipping check for `const_refs_to_static` feature
|
||||||
--> $DIR/mutable_references.rs:33:68
|
--> $DIR/mutable_references.rs:30:68
|
||||||
|
|
|
|
||||||
LL | const SUBTLE: &mut i32 = unsafe { static mut STATIC: i32 = 0; &mut STATIC };
|
LL | const SUBTLE: &mut i32 = unsafe { static mut STATIC: i32 = 0; &mut STATIC };
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
help: skipping check for `const_mut_refs` feature
|
help: skipping check for `const_mut_refs` feature
|
||||||
--> $DIR/mutable_references.rs:33:63
|
--> $DIR/mutable_references.rs:30:63
|
||||||
|
|
|
|
||||||
LL | const SUBTLE: &mut i32 = unsafe { static mut STATIC: i32 = 0; &mut STATIC };
|
LL | const SUBTLE: &mut i32 = unsafe { static mut STATIC: i32 = 0; &mut STATIC };
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/mutable_references.rs:43:28
|
--> $DIR/mutable_references.rs:40:28
|
||||||
|
|
|
|
||||||
LL | static MEH: Meh = Meh { x: &UnsafeCell::new(42) };
|
LL | static MEH: Meh = Meh { x: &UnsafeCell::new(42) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/mutable_references.rs:52:8
|
--> $DIR/mutable_references.rs:49:8
|
||||||
|
|
|
|
||||||
LL | x: &UnsafeCell::new(42),
|
LL | x: &UnsafeCell::new(42),
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/mutable_references.rs:61:27
|
--> $DIR/mutable_references.rs:58:27
|
||||||
|
|
|
|
||||||
LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) };
|
LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
help: skipping check for `const_mut_refs` feature
|
help: skipping check for `const_mut_refs` feature
|
||||||
--> $DIR/mutable_references.rs:68:49
|
--> $DIR/mutable_references.rs:65:49
|
||||||
|
|
|
|
||||||
LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
|
LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
help: skipping check for `const_mut_refs` feature
|
help: skipping check for `const_mut_refs` feature
|
||||||
--> $DIR/mutable_references.rs:68:49
|
--> $DIR/mutable_references.rs:65:49
|
||||||
|
|
|
|
||||||
LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
|
LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
help: skipping check for `const_refs_to_static` feature
|
help: skipping check for `const_refs_to_static` feature
|
||||||
--> $DIR/mutable_references.rs:75:43
|
--> $DIR/mutable_references.rs:72:43
|
||||||
|
|
|
|
||||||
LL | const POINTS_TO_MUTABLE: &i32 = unsafe { &MUTABLE };
|
LL | const POINTS_TO_MUTABLE: &i32 = unsafe { &MUTABLE };
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
help: skipping check for `const_refs_to_static` feature
|
help: skipping check for `const_refs_to_static` feature
|
||||||
--> $DIR/mutable_references.rs:78:45
|
--> $DIR/mutable_references.rs:75:45
|
||||||
|
|
|
|
||||||
LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
|
LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/mutable_references.rs:82:45
|
--> $DIR/mutable_references.rs:79:45
|
||||||
|
|
|
|
||||||
LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _;
|
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
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/mutable_references.rs:86:46
|
--> $DIR/mutable_references.rs:82:46
|
||||||
|
|
|
|
||||||
LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _;
|
LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _;
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/mutable_references.rs:90:47
|
--> $DIR/mutable_references.rs:87:47
|
||||||
|
|
|
|
||||||
LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
|
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
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/mutable_references.rs:103:51
|
--> $DIR/mutable_references.rs:99:51
|
||||||
|
|
|
|
||||||
LL | const RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
|
LL | const RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/mutable_references.rs:107:49
|
--> $DIR/mutable_references.rs:102:49
|
||||||
|
|
|
|
||||||
LL | const RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x: &mut 42 as *mut _ as *const _ };
|
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
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/mutable_references.rs:111:51
|
--> $DIR/mutable_references.rs:105:51
|
||||||
|
|
|
|
||||||
LL | const RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
|
LL | const RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
error: aborting due to 19 previous errors; 1 warning emitted
|
error: aborting due to 17 previous errors; 1 warning emitted
|
||||||
|
|
||||||
Some errors have detailed explanations: E0080, E0594.
|
Some errors have detailed explanations: E0080, E0594.
|
||||||
For more information about an error, try `rustc --explain E0080`.
|
For more information about an error, try `rustc --explain E0080`.
|
||||||
Future incompatibility report: Future breakage diagnostic:
|
|
||||||
error: encountered mutable pointer in final value of static
|
|
||||||
--> $DIR/mutable_references.rs:19:1
|
|
||||||
|
|
|
||||||
LL | static BAR: &mut () = &mut ();
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/mutable_references.rs:6:9
|
|
||||||
|
|
|
||||||
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Future breakage diagnostic:
|
|
||||||
error: encountered mutable pointer in final value of static
|
|
||||||
--> $DIR/mutable_references.rs:25:1
|
|
||||||
|
|
|
||||||
LL | static BOO: &mut Foo<()> = &mut Foo(());
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/mutable_references.rs:6:9
|
|
||||||
|
|
|
||||||
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Future breakage diagnostic:
|
|
||||||
error: encountered mutable pointer in final value of constant
|
|
||||||
--> $DIR/mutable_references.rs:82:1
|
|
||||||
|
|
|
||||||
LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/mutable_references.rs:6:9
|
|
||||||
|
|
|
||||||
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Future breakage diagnostic:
|
|
||||||
error: encountered mutable pointer in final value of constant
|
|
||||||
--> $DIR/mutable_references.rs:86:1
|
|
||||||
|
|
|
||||||
LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/mutable_references.rs:6:9
|
|
||||||
|
|
|
||||||
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Future breakage diagnostic:
|
|
||||||
error: encountered mutable pointer in final value of constant
|
|
||||||
--> $DIR/mutable_references.rs:90:1
|
|
||||||
|
|
|
||||||
LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/mutable_references.rs:6:9
|
|
||||||
|
|
|
||||||
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Future breakage diagnostic:
|
|
||||||
error: encountered mutable pointer in final value of constant
|
|
||||||
--> $DIR/mutable_references.rs:103:1
|
|
||||||
|
|
|
||||||
LL | const RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/mutable_references.rs:6:9
|
|
||||||
|
|
|
||||||
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Future breakage diagnostic:
|
|
||||||
error: encountered mutable pointer in final value of constant
|
|
||||||
--> $DIR/mutable_references.rs:107:1
|
|
||||||
|
|
|
||||||
LL | const RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x: &mut 42 as *mut _ as *const _ };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/mutable_references.rs:6:9
|
|
||||||
|
|
|
||||||
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Future breakage diagnostic:
|
|
||||||
error: encountered mutable pointer in final value of constant
|
|
||||||
--> $DIR/mutable_references.rs:111:1
|
|
||||||
|
|
|
||||||
LL | const RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/mutable_references.rs:6:9
|
|
||||||
|
|
|
||||||
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0080]: it is undefined behavior to use this value
|
error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/static-no-inner-mut.rs:9:1
|
--> $DIR/static-no-inner-mut.rs:8:1
|
||||||
|
|
|
|
||||||
LL | static REF: &AtomicI32 = &AtomicI32::new(42);
|
LL | static REF: &AtomicI32 = &AtomicI32::new(42);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.v: encountered `UnsafeCell` in read-only memory
|
| ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.v: encountered `UnsafeCell` in read-only memory
|
||||||
|
@ -10,7 +10,7 @@ LL | static REF: &AtomicI32 = &AtomicI32::new(42);
|
||||||
}
|
}
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/static-no-inner-mut.rs:12:1
|
--> $DIR/static-no-inner-mut.rs:11:1
|
||||||
|
|
|
|
||||||
LL | static REFMUT: &mut i32 = &mut 0;
|
LL | static REFMUT: &mut i32 = &mut 0;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory
|
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory
|
||||||
|
@ -21,7 +21,7 @@ LL | static REFMUT: &mut i32 = &mut 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/static-no-inner-mut.rs:16:1
|
--> $DIR/static-no-inner-mut.rs:15:1
|
||||||
|
|
|
|
||||||
LL | static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}};
|
LL | static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}};
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.v: encountered `UnsafeCell` in read-only memory
|
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.v: encountered `UnsafeCell` in read-only memory
|
||||||
|
@ -32,7 +32,7 @@ LL | static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}};
|
||||||
}
|
}
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/static-no-inner-mut.rs:18:1
|
--> $DIR/static-no-inner-mut.rs:17:1
|
||||||
|
|
|
|
||||||
LL | static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}};
|
LL | static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}};
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory
|
||||||
|
@ -45,118 +45,53 @@ LL | static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}};
|
||||||
error: encountered mutable pointer in final value of static
|
error: encountered mutable pointer in final value of static
|
||||||
--> $DIR/static-no-inner-mut.rs:34:1
|
--> $DIR/static-no-inner-mut.rs:34:1
|
||||||
|
|
|
|
||||||
LL | static RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/static-no-inner-mut.rs:6:9
|
|
||||||
|
|
|
||||||
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: encountered mutable pointer in final value of static
|
|
||||||
--> $DIR/static-no-inner-mut.rs:38:1
|
|
||||||
|
|
|
||||||
LL | static RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
|
LL | static RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
|
|
||||||
error: encountered mutable pointer in final value of static
|
error: encountered mutable pointer in final value of static
|
||||||
--> $DIR/static-no-inner-mut.rs:42:1
|
--> $DIR/static-no-inner-mut.rs:37:1
|
||||||
|
|
|
|
||||||
LL | static RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
|
LL | static RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
|
|
||||||
warning: skipping const checks
|
warning: skipping const checks
|
||||||
|
|
|
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/static-no-inner-mut.rs:9:26
|
--> $DIR/static-no-inner-mut.rs:8:26
|
||||||
|
|
|
|
||||||
LL | static REF: &AtomicI32 = &AtomicI32::new(42);
|
LL | static REF: &AtomicI32 = &AtomicI32::new(42);
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/static-no-inner-mut.rs:12:27
|
--> $DIR/static-no-inner-mut.rs:11:27
|
||||||
|
|
|
|
||||||
LL | static REFMUT: &mut i32 = &mut 0;
|
LL | static REFMUT: &mut i32 = &mut 0;
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/static-no-inner-mut.rs:16:56
|
--> $DIR/static-no-inner-mut.rs:15:56
|
||||||
|
|
|
|
||||||
LL | static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}};
|
LL | static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}};
|
||||||
| ^^^^
|
| ^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/static-no-inner-mut.rs:18:44
|
--> $DIR/static-no-inner-mut.rs:17:44
|
||||||
|
|
|
|
||||||
LL | static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}};
|
LL | static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}};
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/static-no-inner-mut.rs:34:52
|
--> $DIR/static-no-inner-mut.rs:31:52
|
||||||
|
|
|
|
||||||
LL | static RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
|
LL | static RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/static-no-inner-mut.rs:38:51
|
--> $DIR/static-no-inner-mut.rs:34:51
|
||||||
|
|
|
|
||||||
LL | static RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
|
LL | static RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/static-no-inner-mut.rs:42:52
|
--> $DIR/static-no-inner-mut.rs:37:52
|
||||||
|
|
|
|
||||||
LL | static RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
|
LL | static RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
error: aborting due to 7 previous errors; 1 warning emitted
|
error: aborting due to 6 previous errors; 1 warning emitted
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0080`.
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
Future incompatibility report: Future breakage diagnostic:
|
|
||||||
error: encountered mutable pointer in final value of static
|
|
||||||
--> $DIR/static-no-inner-mut.rs:34:1
|
|
||||||
|
|
|
||||||
LL | static RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/static-no-inner-mut.rs:6:9
|
|
||||||
|
|
|
||||||
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Future breakage diagnostic:
|
|
||||||
error: encountered mutable pointer in final value of static
|
|
||||||
--> $DIR/static-no-inner-mut.rs:38:1
|
|
||||||
|
|
|
||||||
LL | static RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/static-no-inner-mut.rs:6:9
|
|
||||||
|
|
|
||||||
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Future breakage diagnostic:
|
|
||||||
error: encountered mutable pointer in final value of static
|
|
||||||
--> $DIR/static-no-inner-mut.rs:42:1
|
|
||||||
|
|
|
||||||
LL | static RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/static-no-inner-mut.rs:6:9
|
|
||||||
|
|
|
||||||
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0080]: it is undefined behavior to use this value
|
error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/static-no-inner-mut.rs:9:1
|
--> $DIR/static-no-inner-mut.rs:8:1
|
||||||
|
|
|
|
||||||
LL | static REF: &AtomicI32 = &AtomicI32::new(42);
|
LL | static REF: &AtomicI32 = &AtomicI32::new(42);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.v: encountered `UnsafeCell` in read-only memory
|
| ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.v: encountered `UnsafeCell` in read-only memory
|
||||||
|
@ -10,7 +10,7 @@ LL | static REF: &AtomicI32 = &AtomicI32::new(42);
|
||||||
}
|
}
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/static-no-inner-mut.rs:12:1
|
--> $DIR/static-no-inner-mut.rs:11:1
|
||||||
|
|
|
|
||||||
LL | static REFMUT: &mut i32 = &mut 0;
|
LL | static REFMUT: &mut i32 = &mut 0;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory
|
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory
|
||||||
|
@ -21,7 +21,7 @@ LL | static REFMUT: &mut i32 = &mut 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/static-no-inner-mut.rs:16:1
|
--> $DIR/static-no-inner-mut.rs:15:1
|
||||||
|
|
|
|
||||||
LL | static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}};
|
LL | static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}};
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.v: encountered `UnsafeCell` in read-only memory
|
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.v: encountered `UnsafeCell` in read-only memory
|
||||||
|
@ -32,7 +32,7 @@ LL | static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}};
|
||||||
}
|
}
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/static-no-inner-mut.rs:18:1
|
--> $DIR/static-no-inner-mut.rs:17:1
|
||||||
|
|
|
|
||||||
LL | static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}};
|
LL | static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}};
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory
|
||||||
|
@ -45,118 +45,53 @@ LL | static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}};
|
||||||
error: encountered mutable pointer in final value of static
|
error: encountered mutable pointer in final value of static
|
||||||
--> $DIR/static-no-inner-mut.rs:34:1
|
--> $DIR/static-no-inner-mut.rs:34:1
|
||||||
|
|
|
|
||||||
LL | static RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/static-no-inner-mut.rs:6:9
|
|
||||||
|
|
|
||||||
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: encountered mutable pointer in final value of static
|
|
||||||
--> $DIR/static-no-inner-mut.rs:38:1
|
|
||||||
|
|
|
||||||
LL | static RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
|
LL | static RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
|
|
||||||
error: encountered mutable pointer in final value of static
|
error: encountered mutable pointer in final value of static
|
||||||
--> $DIR/static-no-inner-mut.rs:42:1
|
--> $DIR/static-no-inner-mut.rs:37:1
|
||||||
|
|
|
|
||||||
LL | static RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
|
LL | static RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
|
|
||||||
warning: skipping const checks
|
warning: skipping const checks
|
||||||
|
|
|
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/static-no-inner-mut.rs:9:26
|
--> $DIR/static-no-inner-mut.rs:8:26
|
||||||
|
|
|
|
||||||
LL | static REF: &AtomicI32 = &AtomicI32::new(42);
|
LL | static REF: &AtomicI32 = &AtomicI32::new(42);
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/static-no-inner-mut.rs:12:27
|
--> $DIR/static-no-inner-mut.rs:11:27
|
||||||
|
|
|
|
||||||
LL | static REFMUT: &mut i32 = &mut 0;
|
LL | static REFMUT: &mut i32 = &mut 0;
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/static-no-inner-mut.rs:16:56
|
--> $DIR/static-no-inner-mut.rs:15:56
|
||||||
|
|
|
|
||||||
LL | static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}};
|
LL | static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}};
|
||||||
| ^^^^
|
| ^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/static-no-inner-mut.rs:18:44
|
--> $DIR/static-no-inner-mut.rs:17:44
|
||||||
|
|
|
|
||||||
LL | static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}};
|
LL | static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}};
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/static-no-inner-mut.rs:34:52
|
--> $DIR/static-no-inner-mut.rs:31:52
|
||||||
|
|
|
|
||||||
LL | static RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
|
LL | static RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/static-no-inner-mut.rs:38:51
|
--> $DIR/static-no-inner-mut.rs:34:51
|
||||||
|
|
|
|
||||||
LL | static RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
|
LL | static RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/static-no-inner-mut.rs:42:52
|
--> $DIR/static-no-inner-mut.rs:37:52
|
||||||
|
|
|
|
||||||
LL | static RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
|
LL | static RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
error: aborting due to 7 previous errors; 1 warning emitted
|
error: aborting due to 6 previous errors; 1 warning emitted
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0080`.
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
Future incompatibility report: Future breakage diagnostic:
|
|
||||||
error: encountered mutable pointer in final value of static
|
|
||||||
--> $DIR/static-no-inner-mut.rs:34:1
|
|
||||||
|
|
|
||||||
LL | static RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/static-no-inner-mut.rs:6:9
|
|
||||||
|
|
|
||||||
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Future breakage diagnostic:
|
|
||||||
error: encountered mutable pointer in final value of static
|
|
||||||
--> $DIR/static-no-inner-mut.rs:38:1
|
|
||||||
|
|
|
||||||
LL | static RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/static-no-inner-mut.rs:6:9
|
|
||||||
|
|
|
||||||
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Future breakage diagnostic:
|
|
||||||
error: encountered mutable pointer in final value of static
|
|
||||||
--> $DIR/static-no-inner-mut.rs:42:1
|
|
||||||
|
|
|
||||||
LL | static RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/static-no-inner-mut.rs:6:9
|
|
||||||
|
|
|
||||||
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#![feature(const_refs_to_cell, const_mut_refs)]
|
#![feature(const_refs_to_cell, const_mut_refs)]
|
||||||
// All "inner" allocations that come with a `static` are interned immutably. This means it is
|
// All "inner" allocations that come with a `static` are interned immutably. This means it is
|
||||||
// crucial that we do not accept any form of (interior) mutability there.
|
// crucial that we do not accept any form of (interior) mutability there.
|
||||||
#![deny(const_eval_mutable_ptr_in_final_value)]
|
|
||||||
use std::sync::atomic::*;
|
use std::sync::atomic::*;
|
||||||
|
|
||||||
static REF: &AtomicI32 = &AtomicI32::new(42);
|
static REF: &AtomicI32 = &AtomicI32::new(42);
|
||||||
|
@ -27,20 +26,15 @@ unsafe impl<T> Sync for SyncPtr<T> {}
|
||||||
|
|
||||||
// All of these pass the lifetime checks because of the "tail expression" / "outer scope" rule.
|
// All of these pass the lifetime checks because of the "tail expression" / "outer scope" rule.
|
||||||
// (This relies on `SyncPtr` being a curly brace struct.)
|
// (This relies on `SyncPtr` being a curly brace struct.)
|
||||||
// Then they get interned immutably, which is not great.
|
// Then they get interned immutably, which is not great. See
|
||||||
// `mut_ref_in_final.rs` and `std/cell.rs` ensure that we don't accept this even with the feature
|
// <https://github.com/rust-lang/rust/pull/128543> for why we accept such code.
|
||||||
// fate, but for unleashed Miri there's not really any way we can reject them: it's just
|
|
||||||
// non-dangling raw pointers.
|
|
||||||
static RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
|
static RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
|
||||||
//~^ ERROR mutable pointer in final value
|
|
||||||
//~| WARNING this was previously accepted by the compiler
|
|
||||||
|
|
||||||
|
// With mutable references at least, we can detect this and error.
|
||||||
static RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
|
static RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
|
||||||
//~^ ERROR mutable pointer in final value
|
//~^ ERROR mutable pointer in final value
|
||||||
//~| WARNING this was previously accepted by the compiler
|
|
||||||
|
|
||||||
static RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
|
static RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
|
||||||
//~^ ERROR mutable pointer in final value
|
//~^ ERROR mutable pointer in final value
|
||||||
//~| WARNING this was previously accepted by the compiler
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -18,8 +18,8 @@ const RAW_SYNC_C: SyncPtr<Cell<i32>> = SyncPtr { x: &Cell::new(42) };
|
||||||
// This one does not get promoted because of `Drop`, and then enters interesting codepaths because
|
// This one does not get promoted because of `Drop`, and then enters interesting codepaths because
|
||||||
// as a value it has no interior mutability, but as a type it does. See
|
// as a value it has no interior mutability, but as a type it does. See
|
||||||
// <https://github.com/rust-lang/rust/issues/121610>. Value-based reasoning for interior mutability
|
// <https://github.com/rust-lang/rust/issues/121610>. Value-based reasoning for interior mutability
|
||||||
// is questionable (https://github.com/rust-lang/unsafe-code-guidelines/issues/493) so for now we
|
// is questionable (https://github.com/rust-lang/unsafe-code-guidelines/issues/493) but we've
|
||||||
// reject this, though not with a great error message.
|
// done it since Rust 1.0 so we can't stop now.
|
||||||
pub enum JsValue {
|
pub enum JsValue {
|
||||||
Undefined,
|
Undefined,
|
||||||
Object(Cell<bool>),
|
Object(Cell<bool>),
|
||||||
|
@ -28,10 +28,8 @@ impl Drop for JsValue {
|
||||||
fn drop(&mut self) {}
|
fn drop(&mut self) {}
|
||||||
}
|
}
|
||||||
const UNDEFINED: &JsValue = &JsValue::Undefined;
|
const UNDEFINED: &JsValue = &JsValue::Undefined;
|
||||||
//~^ WARNING: mutable pointer in final value of constant
|
|
||||||
//~| WARNING: this was previously accepted by the compiler but is being phased out
|
|
||||||
|
|
||||||
// In contrast, this one works since it is being promoted.
|
// Here's a variant of the above that uses promotion instead of the "outer scope" rule.
|
||||||
const NONE: &'static Option<Cell<i32>> = &None;
|
const NONE: &'static Option<Cell<i32>> = &None;
|
||||||
// Making it clear that this is promotion, not "outer scope".
|
// Making it clear that this is promotion, not "outer scope".
|
||||||
const NONE_EXPLICIT_PROMOTED: &'static Option<Cell<i32>> = {
|
const NONE_EXPLICIT_PROMOTED: &'static Option<Cell<i32>> = {
|
||||||
|
|
|
@ -12,27 +12,6 @@ error[E0492]: constants cannot refer to interior mutable data
|
||||||
LL | const RAW_SYNC_C: SyncPtr<Cell<i32>> = SyncPtr { x: &Cell::new(42) };
|
LL | const RAW_SYNC_C: SyncPtr<Cell<i32>> = SyncPtr { x: &Cell::new(42) };
|
||||||
| ^^^^^^^^^^^^^^ this borrow of an interior mutable value may end up in the final value
|
| ^^^^^^^^^^^^^^ this borrow of an interior mutable value may end up in the final value
|
||||||
|
|
||||||
warning: encountered mutable pointer in final value of constant
|
error: aborting due to 2 previous errors
|
||||||
--> $DIR/refs-to-cell-in-final.rs:30:1
|
|
||||||
|
|
|
||||||
LL | const UNDEFINED: &JsValue = &JsValue::Undefined;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
= note: `#[warn(const_eval_mutable_ptr_in_final_value)]` on by default
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors; 1 warning emitted
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0492`.
|
For more information about this error, try `rustc --explain E0492`.
|
||||||
Future incompatibility report: Future breakage diagnostic:
|
|
||||||
warning: encountered mutable pointer in final value of constant
|
|
||||||
--> $DIR/refs-to-cell-in-final.rs:30:1
|
|
||||||
|
|
|
||||||
LL | const UNDEFINED: &JsValue = &JsValue::Undefined;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
|
|
||||||
= note: `#[warn(const_eval_mutable_ptr_in_final_value)]` on by default
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue