diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index 0046190d20cc7..221ba7b5c7c3a 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -49,7 +49,6 @@ const_eval_dangling_int_pointer = const_eval_dangling_null_pointer = {$bad_pointer_message}: null pointer is a dangling pointer (it has no provenance) -const_eval_dangling_ptr_in_final = encountered dangling pointer in final value of {const_eval_intern_kind} const_eval_dead_local = accessing a dead local variable const_eval_dealloc_immutable = diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 5a1c7cc4209ad..d14b176ddb7c8 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -16,12 +16,12 @@ use super::{CanAccessMutGlobal, CompileTimeEvalContext, CompileTimeInterpreter}; use crate::const_eval::CheckAlignment; use crate::errors; use crate::errors::ConstEvalError; -use crate::interpret::eval_nullary_intrinsic; use crate::interpret::{ create_static_alloc, intern_const_alloc_recursive, CtfeValidationMode, GlobalId, Immediate, InternKind, InterpCx, InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, StackPopCleanup, }; +use crate::interpret::{eval_nullary_intrinsic, patch_mutability_of_allocs}; // Returns a pointer to where the result lives #[instrument(level = "trace", skip(ecx, body))] @@ -81,11 +81,13 @@ fn eval_body_using_ecx<'mir, 'tcx, R: InterpretationResult<'tcx>>( // The main interpreter loop. while ecx.step()? {} - // Intern the result - intern_const_alloc_recursive(ecx, intern_kind, &ret)?; + patch_mutability_of_allocs(ecx, intern_kind, &ret)?; // Since evaluation had no errors, validate the resulting constant. - const_validate_mplace(&ecx, &ret, cid)?; + const_validate_mplace(ecx, &ret, cid)?; + + // Intern the result + intern_const_alloc_recursive(ecx, intern_kind, &ret)?; Ok(R::make_result(ret, ecx)) } @@ -401,7 +403,7 @@ fn const_validate_mplace<'mir, 'tcx>( CtfeValidationMode::Const { allow_immutable_unsafe_cell: !inner } } }; - ecx.const_validate_operand(&mplace.into(), path, &mut ref_tracking, mode) + ecx.const_validate_operand(mplace, path, &mut ref_tracking, mode) // Instead of just reporting the `InterpError` via the usual machinery, we give a more targetted // error about the validation failure. .map_err(|error| report_validation_error(&ecx, error, alloc_id))?; diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index d3428d27d52fd..671f101e7af98 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -10,11 +10,11 @@ use super::machine::CompileTimeEvalContext; use super::{ValTreeCreationError, ValTreeCreationResult, VALTREE_MAX_NODES}; use crate::const_eval::CanAccessMutGlobal; use crate::errors::MaxNumNodesInConstErr; -use crate::interpret::MPlaceTy; use crate::interpret::{ intern_const_alloc_recursive, ImmTy, Immediate, InternKind, MemPlaceMeta, MemoryKind, PlaceTy, Projectable, Scalar, }; +use crate::interpret::{patch_mutability_of_allocs, MPlaceTy}; #[instrument(skip(ecx), level = "debug")] fn branches<'tcx>( @@ -323,6 +323,7 @@ pub fn valtree_to_const_value<'tcx>( valtree_into_mplace(&mut ecx, &place, valtree); dump_place(&ecx, &place); + patch_mutability_of_allocs(&mut ecx, InternKind::Constant, &place).unwrap(); intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &place).unwrap(); op_to_const(&ecx, &place.into(), /* for diagnostics */ false) @@ -359,6 +360,7 @@ fn valtree_to_ref<'tcx>( valtree_into_mplace(ecx, &pointee_place, valtree); dump_place(ecx, &pointee_place); + patch_mutability_of_allocs(ecx, InternKind::Constant, &pointee_place).unwrap(); intern_const_alloc_recursive(ecx, InternKind::Constant, &pointee_place).unwrap(); pointee_place.to_ref(&ecx.tcx) diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index cc32640408b7e..8c04be2a427ef 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -17,14 +17,6 @@ use rustc_target::abi::{Size, WrappingRange}; use crate::interpret::InternKind; -#[derive(Diagnostic)] -#[diag(const_eval_dangling_ptr_in_final)] -pub(crate) struct DanglingPtrInFinal { - #[primary_span] - pub span: Span, - pub kind: InternKind, -} - #[derive(LintDiagnostic)] #[diag(const_eval_mutable_ptr_in_final)] pub(crate) struct MutablePtrInFinal { diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index 17bb59aae8f17..82dad3717795d 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -27,7 +27,7 @@ use rustc_span::sym; use super::{AllocId, Allocation, InterpCx, MPlaceTy, Machine, MemoryKind, PlaceTy}; use crate::const_eval; -use crate::errors::{DanglingPtrInFinal, MutablePtrInFinal}; +use crate::errors::MutablePtrInFinal; pub trait CompileTimeMachine<'mir, 'tcx: 'mir, T> = Machine< 'mir, @@ -62,26 +62,13 @@ impl HasStaticRootDefId for const_eval::CompileTimeInterpreter<'_, '_> { fn intern_shallow<'rt, 'mir, 'tcx, T, M: CompileTimeMachine<'mir, 'tcx, T>>( ecx: &'rt mut InterpCx<'mir, 'tcx, M>, alloc_id: AllocId, - mutability: Mutability, ) -> Result + 'tcx, ()> { trace!("intern_shallow {:?}", alloc_id); // remove allocation // FIXME(#120456) - is `swap_remove` correct? - let Some((_kind, mut alloc)) = ecx.memory.alloc_map.swap_remove(&alloc_id) else { + let Some((_kind, alloc)) = ecx.memory.alloc_map.swap_remove(&alloc_id) else { return Err(()); }; - // Set allocation mutability as appropriate. This is used by LLVM to put things into - // read-only memory, and also by Miri when evaluating other globals that - // access this one. - match mutability { - Mutability::Not => { - alloc.mutability = Mutability::Not; - } - Mutability::Mut => { - // This must be already mutable, we won't "un-freeze" allocations ever. - assert_eq!(alloc.mutability, Mutability::Mut); - } - } // link the alloc id to the actual allocation let alloc = ecx.tcx.mk_const_alloc(alloc); if let Some(static_id) = ecx.machine.static_def_id() { @@ -123,14 +110,9 @@ pub enum InternKind { Promoted, } -/// Intern `ret` and everything it references. -/// -/// This *cannot raise an interpreter error*. Doing so is left to validation, which -/// tracks where in the value we are and thus can show much better error messages. -/// -/// For `InternKind::Static` the root allocation will not be interned, but must be handled by the caller. -#[instrument(level = "debug", skip(ecx))] -pub fn intern_const_alloc_recursive< +/// Now that evaluation is finished, and we are not going to modify allocations anymore, +/// recursively mark all allocations as immutable if the item kind calls for it (const/promoted/immut static). +pub fn patch_mutability_of_allocs< 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx, const_eval::MemoryKind>, @@ -141,12 +123,12 @@ pub fn intern_const_alloc_recursive< ) -> Result<(), ErrorGuaranteed> { // We are interning recursively, and for mutability we are distinguishing the "root" allocation // that we are starting in, and all other allocations that we are encountering recursively. - let (base_mutability, inner_mutability, is_static) = match intern_kind { + let (base_mutability, inner_mutability) = match intern_kind { InternKind::Constant | InternKind::Promoted => { // Completely immutable. Interning anything mutably here can only lead to unsoundness, // since all consts are conceptually independent values but share the same underlying // memory. - (Mutability::Not, Mutability::Not, false) + (Mutability::Not, Mutability::Not) } InternKind::Static(Mutability::Not) => { ( @@ -159,30 +141,79 @@ pub fn intern_const_alloc_recursive< // Inner allocations are never mutable. They can only arise via the "tail // expression" / "outer scope" rule, and we treat them consistently with `const`. Mutability::Not, - true, ) } InternKind::Static(Mutability::Mut) => { // Just make everything mutable. We accept code like // `static mut X = &mut [42]`, so even inner allocations need to be mutable. - (Mutability::Mut, Mutability::Mut, true) + (Mutability::Mut, Mutability::Mut) } }; + let base_alloc_id = ret.ptr().provenance.unwrap().alloc_id(); + let mut todo: Vec<_> = { + let base_alloc = &mut ecx.memory.alloc_map.get_mut(&base_alloc_id).unwrap().1; + base_alloc.mutability = base_mutability; + base_alloc.provenance().ptrs().iter().copied().collect() + }; + let mut seen = FxHashSet::default(); + seen.insert(base_alloc_id); + while let Some((_, prov)) = todo.pop() { + if !seen.insert(prov.alloc_id()) { + // Already processed + continue; + } + let Some((_, alloc)) = &mut ecx.memory.alloc_map.get_mut(&prov.alloc_id()) else { + continue; + }; + // We always intern with `inner_mutability`, and furthermore we ensured above that if + // that is "immutable", then there are *no* mutable pointers anywhere in the newly + // interned memory -- justifying that we can indeed intern immutably. However this also + // means we can *not* easily intern immutably here if `prov.immutable()` is true and + // `inner_mutability` is `Mut`: there might be other pointers to that allocation, and + // we'd have to somehow check that they are *all* immutable before deciding that this + // allocation can be made immutable. In the future we could consider analyzing all + // pointers before deciding which allocations can be made immutable; but for now we are + // okay with losing some potential for immutability here. This can anyway only affect + // `static mut`. + alloc.mutability = inner_mutability; + todo.extend(alloc.provenance().ptrs().iter().copied()); + } + Ok(()) +} + +/// Intern `ret` and everything it references. +/// +/// This *cannot raise an interpreter error*. Doing so is left to validation, which +/// tracks where in the value we are and thus can show much better error messages. +/// +/// For `InternKind::Static` the root allocation will not be interned, but must be handled by the caller. +#[instrument(level = "debug", skip(ecx))] +pub fn intern_const_alloc_recursive< + 'mir, + 'tcx: 'mir, + M: CompileTimeMachine<'mir, 'tcx, const_eval::MemoryKind>, +>( + ecx: &mut InterpCx<'mir, 'tcx, M>, + intern_kind: InternKind, + ret: &MPlaceTy<'tcx>, +) -> Result<(), ErrorGuaranteed> { + let (inner_mutability, is_static) = match intern_kind { + InternKind::Constant | InternKind::Promoted => (Mutability::Not, false), + InternKind::Static(mutability) => (mutability, true), + }; // Intern the base allocation, and initialize todo list for recursive interning. let base_alloc_id = ret.ptr().provenance.unwrap().alloc_id(); - trace!(?base_alloc_id, ?base_mutability); + trace!(?base_alloc_id); // First we intern the base allocation, as it requires a different mutability. // This gives us the initial set of nested allocations, which will then all be processed // recursively in the loop below. let mut todo: Vec<_> = if is_static { // Do not steal the root allocation, we need it later to create the return value of `eval_static_initializer`. - // But still change its mutability to match the requested one. - let alloc = ecx.memory.alloc_map.get_mut(&base_alloc_id).unwrap(); - alloc.1.mutability = base_mutability; + let alloc = ecx.memory.alloc_map.get(&base_alloc_id).unwrap(); alloc.1.provenance().ptrs().iter().map(|&(_, prov)| prov).collect() } else { - intern_shallow(ecx, base_alloc_id, base_mutability).unwrap().collect() + intern_shallow(ecx, base_alloc_id).unwrap().collect() }; // We need to distinguish "has just been interned" from "was already in `tcx`", // so we track this in a separate set. @@ -248,19 +279,7 @@ pub fn intern_const_alloc_recursive< continue; } just_interned.insert(alloc_id); - // We always intern with `inner_mutability`, and furthermore we ensured above that if - // that is "immutable", then there are *no* mutable pointers anywhere in the newly - // interned memory -- justifying that we can indeed intern immutably. However this also - // means we can *not* easily intern immutably here if `prov.immutable()` is true and - // `inner_mutability` is `Mut`: there might be other pointers to that allocation, and - // we'd have to somehow check that they are *all* immutable before deciding that this - // allocation can be made immutable. In the future we could consider analyzing all - // pointers before deciding which allocations can be made immutable; but for now we are - // okay with losing some potential for immutability here. This can anyway only affect - // `static mut`. - todo.extend(intern_shallow(ecx, alloc_id, inner_mutability).map_err(|()| { - ecx.tcx.dcx().emit_err(DanglingPtrInFinal { span: ecx.tcx.span, kind: intern_kind }) - })?); + todo.extend(intern_shallow(ecx, alloc_id).unwrap()); } if found_bad_mutable_pointer { let err_diag = MutablePtrInFinal { span: ecx.tcx.span, kind: intern_kind }; @@ -291,7 +310,8 @@ pub fn intern_const_alloc_for_constprop< return Ok(()); } // Move allocation to `tcx`. - for _ in intern_shallow(ecx, alloc_id, Mutability::Not).map_err(|()| err_ub!(DeadLocal))? { + ecx.memory.alloc_map.get_mut(&alloc_id).unwrap().1.mutability = Mutability::Not; + for _ in intern_shallow(ecx, alloc_id).map_err(|()| err_ub!(DeadLocal))? { // We are not doing recursive interning, so we don't currently support provenance. // (If this assertion ever triggers, we should just implement a // proper recursive interning loop -- or just call `intern_const_alloc_recursive`. @@ -318,7 +338,8 @@ impl<'mir, 'tcx: 'mir, M: super::intern::CompileTimeMachine<'mir, 'tcx, !>> let dest = self.allocate(layout, MemoryKind::Stack)?; f(self, &dest.clone().into())?; let alloc_id = dest.ptr().provenance.unwrap().alloc_id(); // this was just allocated, it must have provenance - for prov in intern_shallow(self, alloc_id, Mutability::Not).unwrap() { + self.memory.alloc_map.get_mut(&alloc_id).unwrap().1.mutability = Mutability::Not; + for prov in intern_shallow(self, alloc_id).unwrap() { // We are not doing recursive interning, so we don't currently support provenance. // (If this assertion ever triggers, we should just implement a // proper recursive interning loop -- or just call `intern_const_alloc_recursive`. diff --git a/compiler/rustc_const_eval/src/interpret/mod.rs b/compiler/rustc_const_eval/src/interpret/mod.rs index 474d35b2aa3a2..8e4a88de73706 100644 --- a/compiler/rustc_const_eval/src/interpret/mod.rs +++ b/compiler/rustc_const_eval/src/interpret/mod.rs @@ -22,7 +22,8 @@ pub use rustc_middle::mir::interpret::*; // have all the `interpret` symbols in pub use self::eval_context::{format_interp_error, Frame, FrameInfo, InterpCx, StackPopCleanup}; pub use self::intern::{ - intern_const_alloc_for_constprop, intern_const_alloc_recursive, HasStaticRootDefId, InternKind, + intern_const_alloc_for_constprop, intern_const_alloc_recursive, patch_mutability_of_allocs, + HasStaticRootDefId, InternKind, }; pub use self::machine::{compile_time_machine, AllocMap, Machine, MayLeak, StackPopJump}; pub use self::memory::{AllocKind, AllocRef, AllocRefMut, FnVal, Memory, MemoryKind}; diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index d18600ce7d755..d0ce89962daf2 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -26,10 +26,12 @@ use rustc_target::abi::{ use std::hash::Hash; +use crate::interpret::AllocKind; + use super::{ - format_interp_error, machine::AllocMap, AllocId, CheckInAllocMsg, GlobalAlloc, ImmTy, - Immediate, InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy, Pointer, Projectable, - Scalar, ValueVisitor, + format_interp_error, AllocId, CheckInAllocMsg, GlobalAlloc, ImmTy, Immediate, InterpCx, + InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy, Pointer, Projectable, Scalar, + ValueVisitor, }; // for the validation errors @@ -450,10 +452,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' if let Ok((alloc_id, _offset, _prov)) = self.ecx.ptr_try_get_alloc_id(place.ptr()) { let mut skip_recursive_check = false; // Let's see what kind of memory this points to. - // `unwrap` since dangling pointers have already been handled. - let alloc_kind = self.ecx.tcx.try_get_global_alloc(alloc_id).unwrap(); - let alloc_actual_mutbl = match alloc_kind { - GlobalAlloc::Static(did) => { + let alloc_actual_mutbl = match self.ecx.tcx.try_get_global_alloc(alloc_id) { + Some(GlobalAlloc::Static(did)) => { // 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)); @@ -483,32 +483,39 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' } // Return alloc mutability. For "root" statics we look at the type to account for interior // mutability; for nested statics we have no type and directly use the annotated mutability. - let DefKind::Static { mutability, nested } = self.ecx.tcx.def_kind(did) + let DefKind::Static { mut mutability, nested } = self.ecx.tcx.def_kind(did) else { bug!() }; - match (mutability, nested) { - (Mutability::Mut, _) => Mutability::Mut, - (Mutability::Not, true) => Mutability::Not, - (Mutability::Not, false) - if !self - .ecx - .tcx - .type_of(did) - .no_bound_vars() - .expect("statics should not have generic parameters") - .is_freeze(*self.ecx.tcx, ty::ParamEnv::reveal_all()) => + if let Mutability::Not = mutability + && !nested + { + if !self + .ecx + .tcx + .type_of(did) + .no_bound_vars() + .expect("statics should not have generic parameters") + .is_freeze(*self.ecx.tcx, ty::ParamEnv::reveal_all()) { - Mutability::Mut + mutability = Mutability::Mut; } - (Mutability::Not, false) => Mutability::Not, } + mutability } - GlobalAlloc::Memory(alloc) => alloc.inner().mutability, - GlobalAlloc::Function(..) | GlobalAlloc::VTable(..) => { + Some(GlobalAlloc::Memory(alloc)) => alloc.inner().mutability, + Some(GlobalAlloc::Function(..) | GlobalAlloc::VTable(..)) => { // These are immutable, we better don't allow mutable pointers here. Mutability::Not } + None => match self.ecx.get_alloc_info(alloc_id).2 { + AllocKind::LiveData => self.ecx.get_alloc_mutability(alloc_id).unwrap(), + AllocKind::Function | AllocKind::VTable => Mutability::Not, + AllocKind::Dead => throw_validation_failure!( + self.path, + DanglingPtrUseAfterFree { ptr_kind } + ), + }, }; // Mutability check. // If this allocation has size zero, there is no actual mutability here. @@ -599,6 +606,15 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' if place.layout.is_unsized() { self.check_wide_ptr_meta(place.meta(), place.layout)?; } + if self.ref_tracking.is_some() + && let Some(alloc_id) = place.ptr().provenance.and_then(|p| p.get_alloc_id()) + && let AllocKind::Dead = self.ecx.get_alloc_info(alloc_id).2 + { + throw_validation_failure!( + self.path, + DanglingPtrUseAfterFree { ptr_kind: PointerKind::Ref(Mutability::Not) } + ) + } Ok(true) } ty::Ref(_, _ty, mutbl) => { @@ -707,13 +723,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' fn in_mutable_memory(&self, op: &OpTy<'tcx, M::Provenance>) -> bool { if let Some(mplace) = op.as_mplace_or_imm().left() { if let Some(alloc_id) = mplace.ptr().provenance.and_then(|p| p.get_alloc_id()) { - let mutability = match self.ecx.tcx.global_alloc(alloc_id) { - GlobalAlloc::Static(_) => { - self.ecx.memory.alloc_map.get(alloc_id).unwrap().1.mutability - } - GlobalAlloc::Memory(alloc) => alloc.inner().mutability, - _ => span_bug!(self.ecx.tcx.span, "not a memory allocation"), - }; + let mutability = self.ecx.get_alloc_mutability(alloc_id).unwrap(); return mutability == Mutability::Mut; } } @@ -975,7 +985,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { path: Vec, ref_tracking: Option<&mut RefTracking, Vec>>, ctfe_mode: Option, - ) -> InterpResult<'tcx> { + ) -> InterpResult<'tcx, Vec> { trace!("validate_operand_internal: {:?}, {:?}", *op, op.layout.ty); // Construct a visitor @@ -983,7 +993,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Run it. match self.run_for_validation(|| visitor.visit_value(op)) { - Ok(()) => Ok(()), + Ok(()) => Ok(visitor.path), // Pass through validation failures and "invalid program" issues. Err(err) if matches!( @@ -1003,7 +1013,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } } +} +impl<'mir, 'tcx> InterpCx<'mir, 'tcx, crate::const_eval::CompileTimeInterpreter<'mir, 'tcx>> { /// This function checks the data at `op` to be const-valid. /// `op` is assumed to cover valid memory if it is an indirect operand. /// It will error if the bits at the destination do not match the ones described by the layout. @@ -1017,14 +1029,38 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { #[inline(always)] pub(crate) fn const_validate_operand( &self, - op: &OpTy<'tcx, M::Provenance>, + mplace: MPlaceTy<'tcx>, path: Vec, - ref_tracking: &mut RefTracking, Vec>, + ref_tracking: &mut RefTracking, Vec>, ctfe_mode: CtfeValidationMode, ) -> InterpResult<'tcx> { - self.validate_operand_internal(op, path, Some(ref_tracking), Some(ctfe_mode)) + let prov = mplace.ptr().provenance; + let path = self.validate_operand_internal( + &mplace.into(), + path, + Some(ref_tracking), + Some(ctfe_mode), + )?; + + // There was no error, so let's check the rest of the relocations in the pointed-to allocation for + // dangling pointers. + if let Some(prov) = prov + && let Some((_, alloc)) = self.memory.alloc_map().get(&prov.alloc_id()) + { + for (_, prov) in alloc.provenance().ptrs().iter() { + if let AllocKind::Dead = self.get_alloc_info(prov.alloc_id()).2 { + throw_validation_failure!( + path, + DanglingPtrUseAfterFree { ptr_kind: PointerKind::Ref(Mutability::Not) } + ) + } + } + } + Ok(()) } +} +impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// This function checks the data at `op` to be runtime-valid. /// `op` is assumed to cover valid memory if it is an indirect operand. /// It will error if the bits at the destination do not match the ones described by the layout. @@ -1034,6 +1070,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // still correct to not use `ctfe_mode`: that mode is for validation of the final constant // value, it rules out things like `UnsafeCell` in awkward places. It also can make checking // recurse through references which, for now, we don't want here, either. - self.validate_operand_internal(op, vec![], None, None) + self.validate_operand_internal(op, vec![], None, None).map(drop) } } diff --git a/compiler/rustc_const_eval/src/util/caller_location.rs b/compiler/rustc_const_eval/src/util/caller_location.rs index af9a4a4271d74..6a2cbc6333df5 100644 --- a/compiler/rustc_const_eval/src/util/caller_location.rs +++ b/compiler/rustc_const_eval/src/util/caller_location.rs @@ -64,8 +64,7 @@ pub(crate) fn const_caller_location_provider( ); let loc_place = alloc_caller_location(&mut ecx, file, line, col); - if intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &loc_place).is_err() { - bug!("intern_const_alloc_recursive should not error in this case") - } + patch_mutability_of_allocs(&mut ecx, InternKind::Constant, &loc_place).unwrap(); + intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &loc_place).unwrap(); mir::ConstValue::Scalar(Scalar::from_maybe_pointer(loc_place.ptr(), &tcx)) } diff --git a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs index 6ede6f5339ca4..0f70862b5d9cc 100644 --- a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs +++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs @@ -2,10 +2,15 @@ #![feature(const_heap)] #![feature(const_mut_refs)] +// Strip out raw byte dumps to make comparison platform-independent: +//@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr-test "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" + use std::intrinsics; const _X: &'static u8 = unsafe { - //~^ error: dangling pointer in final value of constant + //~^ error: it is undefined behavior to use this value let ptr = intrinsics::const_allocate(4, 4); intrinsics::const_deallocate(ptr, 4, 4); &*ptr diff --git a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr index 59f5f79a95f38..a42c26c0a8dee 100644 --- a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr +++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr @@ -1,14 +1,19 @@ -error: encountered dangling pointer in final value of constant - --> $DIR/dealloc_intrinsic_dangling.rs:7:1 +error[E0080]: it is undefined behavior to use this value + --> $DIR/dealloc_intrinsic_dangling.rs:12:1 | LL | const _X: &'static u8 = unsafe { - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (use-after-free) + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } error[E0080]: evaluation of constant value failed - --> $DIR/dealloc_intrinsic_dangling.rs:18:5 + --> $DIR/dealloc_intrinsic_dangling.rs:23:5 | LL | *reference - | ^^^^^^^^^^ memory access failed: ALLOC0 has been freed, so this pointer is dangling + | ^^^^^^^^^^ memory access failed: ALLOC1 has been freed, so this pointer is dangling error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs index f3f0e1446fccb..b86846af98813 100644 --- a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs @@ -33,8 +33,8 @@ const fn helper_dangling() -> Option<&'static mut i32> { unsafe { // Undefined behaviour (dangling pointer), who doesn't love tests like this. Some(&mut *(&mut 42 as *mut i32)) } } -const DANGLING: Option<&mut i32> = helper_dangling(); //~ ERROR encountered dangling pointer -static DANGLING_STATIC: Option<&mut i32> = helper_dangling(); //~ ERROR encountered dangling pointer +const DANGLING: Option<&mut i32> = helper_dangling(); //~ ERROR it is undefined behavior to use this value +static DANGLING_STATIC: Option<&mut i32> = helper_dangling(); //~ ERROR it is undefined behavior to use this value // These are fine! Just statics pointing to mutable statics, nothing fundamentally wrong with this. static MUT_STATIC: Option<&mut i32> = helper(); diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr index 5923683a1c96e..dd952fe7ebef8 100644 --- a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr @@ -31,17 +31,27 @@ LL | static INT2PTR_STATIC: Option<&mut i32> = helper_int2ptr(); HEX_DUMP } -error: encountered dangling pointer in final value of constant +error[E0080]: it is undefined behavior to use this value --> $DIR/mut_ref_in_final_dynamic_check.rs:36:1 | LL | const DANGLING: Option<&mut i32> = helper_dangling(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered a dangling reference (use-after-free) + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } -error: encountered dangling pointer in final value of static +error[E0080]: it is undefined behavior to use this value --> $DIR/mut_ref_in_final_dynamic_check.rs:37:1 | LL | static DANGLING_STATIC: Option<&mut i32> = helper_dangling(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered a dangling reference (use-after-free) + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } error: aborting due to 5 previous errors diff --git a/tests/ui/consts/dangling-alloc-id-ice.rs b/tests/ui/consts/dangling-alloc-id-ice.rs index d9f458f3770a8..76d6f33baf34b 100644 --- a/tests/ui/consts/dangling-alloc-id-ice.rs +++ b/tests/ui/consts/dangling-alloc-id-ice.rs @@ -1,4 +1,8 @@ // https://github.com/rust-lang/rust/issues/55223 +// Strip out raw byte dumps to make comparison platform-independent: +//@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr-test "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" union Foo<'a> { y: &'a (), @@ -6,7 +10,7 @@ union Foo<'a> { } const FOO: &() = { -//~^ ERROR encountered dangling pointer in final value of constant + //~^ ERROR it is undefined behavior to use this value let y = (); unsafe { Foo { y: &y }.long_live_the_unit } }; diff --git a/tests/ui/consts/dangling-alloc-id-ice.stderr b/tests/ui/consts/dangling-alloc-id-ice.stderr index 8322b18d692dc..881c0b162edca 100644 --- a/tests/ui/consts/dangling-alloc-id-ice.stderr +++ b/tests/ui/consts/dangling-alloc-id-ice.stderr @@ -1,8 +1,14 @@ -error: encountered dangling pointer in final value of constant - --> $DIR/dangling-alloc-id-ice.rs:8:1 +error[E0080]: it is undefined behavior to use this value + --> $DIR/dangling-alloc-id-ice.rs:12:1 | LL | const FOO: &() = { - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (use-after-free) + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/dangling_raw_ptr.rs b/tests/ui/consts/dangling_raw_ptr.rs index 0ab3643f1216b..a27bbb806dfda 100644 --- a/tests/ui/consts/dangling_raw_ptr.rs +++ b/tests/ui/consts/dangling_raw_ptr.rs @@ -1,8 +1,18 @@ -const FOO: *const u32 = { //~ ERROR encountered dangling pointer in final value of constant +const FOO: *const u32 = { //~ ERROR it is undefined behavior let x = 42; &x }; +union Union { + ptr: *const u32 +} + +const BAR: Union = { //~ ERROR it is undefined behavior + let x = 42; + Union { ptr: &x } +}; + fn main() { let x = FOO; + let x = BAR; } diff --git a/tests/ui/consts/dangling_raw_ptr.stderr b/tests/ui/consts/dangling_raw_ptr.stderr index 28a58ae7be292..d454d888da775 100644 --- a/tests/ui/consts/dangling_raw_ptr.stderr +++ b/tests/ui/consts/dangling_raw_ptr.stderr @@ -1,8 +1,25 @@ -error: encountered dangling pointer in final value of constant +error[E0080]: it is undefined behavior to use this value --> $DIR/dangling_raw_ptr.rs:1:1 | LL | const FOO: *const u32 = { - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (use-after-free) + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾ALLOC0╼ │ ╾──────╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/dangling_raw_ptr.rs:10:1 + | +LL | const BAR: Union = { + | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (use-after-free) + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾ALLOC1╼ │ ╾──────╼ + } -error: aborting due to 1 previous error +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/miri_unleashed/mutable_references.rs b/tests/ui/consts/miri_unleashed/mutable_references.rs index 8878e8eccf12b..8d6c6586d9555 100644 --- a/tests/ui/consts/miri_unleashed/mutable_references.rs +++ b/tests/ui/consts/miri_unleashed/mutable_references.rs @@ -8,8 +8,7 @@ use std::cell::UnsafeCell; // a test demonstrating what things we could allow with a smarter const qualification static FOO: &&mut u32 = &&mut 42; -//~^ ERROR encountered mutable pointer in final value of static -//~| WARNING this was previously accepted by the compiler +//~^ ERROR it is undefined behavior to use this value static BAR: &mut () = &mut (); //~^ ERROR encountered mutable pointer in final value of static @@ -26,13 +25,10 @@ struct Meh { } unsafe impl Sync for Meh {} static MEH: Meh = Meh { x: &UnsafeCell::new(42) }; -//~^ ERROR encountered mutable pointer in final value of static -//~| WARNING this was previously accepted by the compiler +//~^ ERROR it is undefined behavior to use this value static OH_YES: &mut i32 = &mut 42; -//~^ ERROR encountered mutable pointer in final value of static -//~| WARNING this was previously accepted by the compiler -//~| ERROR it is undefined behavior to use this value +//~^ ERROR it is undefined behavior to use this value fn main() { unsafe { diff --git a/tests/ui/consts/miri_unleashed/mutable_references.stderr b/tests/ui/consts/miri_unleashed/mutable_references.stderr index 7122eb609f153..9694aef24c5e6 100644 --- a/tests/ui/consts/miri_unleashed/mutable_references.stderr +++ b/tests/ui/consts/miri_unleashed/mutable_references.stderr @@ -1,28 +1,30 @@ -error: encountered mutable pointer in final value of static +error[E0080]: it is undefined behavior to use this value --> $DIR/mutable_references.rs:10:1 | LL | static FOO: &&mut u32 = &&mut 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 -note: the lint level is defined here - --> $DIR/mutable_references.rs:5:9 + | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered mutable reference or box pointing to read-only memory | -LL | #![deny(const_eval_mutable_ptr_in_final_value)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } error: encountered mutable pointer in final value of static - --> $DIR/mutable_references.rs:14:1 + --> $DIR/mutable_references.rs:13: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 +note: the lint level is defined here + --> $DIR/mutable_references.rs:5:9 + | +LL | #![deny(const_eval_mutable_ptr_in_final_value)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of static - --> $DIR/mutable_references.rs:20:1 + --> $DIR/mutable_references.rs:19:1 | LL | static BOO: &mut Foo<()> = &mut Foo(()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -30,26 +32,19 @@ 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 -error: encountered mutable pointer in final value of static - --> $DIR/mutable_references.rs:28:1 +error[E0080]: it is undefined behavior to use this value + --> $DIR/mutable_references.rs:27:1 | LL | static MEH: Meh = Meh { x: &UnsafeCell::new(42) }; - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ constructing invalid value at .x.: encountered `UnsafeCell` in read-only memory | - = 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 - -error: encountered mutable pointer in final value of static - --> $DIR/mutable_references.rs:32:1 - | -LL | static OH_YES: &mut i32 = &mut 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 + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references.rs:32:1 + --> $DIR/mutable_references.rs:30:1 | LL | static OH_YES: &mut i32 = &mut 42; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory @@ -60,7 +55,7 @@ LL | static OH_YES: &mut i32 = &mut 42; } error[E0594]: cannot assign to `*OH_YES`, as `OH_YES` is an immutable static item - --> $DIR/mutable_references.rs:41:5 + --> $DIR/mutable_references.rs:37:5 | LL | *OH_YES = 99; | ^^^^^^^^^^^^ cannot assign @@ -73,48 +68,33 @@ help: skipping check that does not even have a feature gate LL | static FOO: &&mut u32 = &&mut 42; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:14:23 + --> $DIR/mutable_references.rs:13:23 | LL | static BAR: &mut () = &mut (); | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:20:28 + --> $DIR/mutable_references.rs:19:28 | LL | static BOO: &mut Foo<()> = &mut Foo(()); | ^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:28:28 + --> $DIR/mutable_references.rs:27:28 | LL | static MEH: Meh = Meh { x: &UnsafeCell::new(42) }; | ^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references.rs:32:27 + --> $DIR/mutable_references.rs:30:27 | LL | static OH_YES: &mut i32 = &mut 42; | ^^^^^^^ -error: aborting due to 7 previous errors; 1 warning emitted +error: aborting due to 6 previous errors; 1 warning emitted Some errors have detailed explanations: E0080, E0594. 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:10:1 - | -LL | static FOO: &&mut u32 = &&mut 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 -note: the lint level is defined here - --> $DIR/mutable_references.rs:5: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:14:1 + --> $DIR/mutable_references.rs:13:1 | LL | static BAR: &mut () = &mut (); | ^^^^^^^^^^^^^^^^^^^ @@ -129,7 +109,7 @@ 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:20:1 + --> $DIR/mutable_references.rs:19:1 | LL | static BOO: &mut Foo<()> = &mut Foo(()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -142,33 +122,3 @@ note: the lint level is defined here 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:28:1 - | -LL | static MEH: Meh = Meh { x: &UnsafeCell::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 -note: the lint level is defined here - --> $DIR/mutable_references.rs:5: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:32:1 - | -LL | static OH_YES: &mut i32 = &mut 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 -note: the lint level is defined here - --> $DIR/mutable_references.rs:5:9 - | -LL | #![deny(const_eval_mutable_ptr_in_final_value)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - diff --git a/tests/ui/consts/miri_unleashed/mutable_references_err.rs b/tests/ui/consts/miri_unleashed/mutable_references_err.rs index 97b8a71cafa34..a3da545846e9d 100644 --- a/tests/ui/consts/miri_unleashed/mutable_references_err.rs +++ b/tests/ui/consts/miri_unleashed/mutable_references_err.rs @@ -16,9 +16,7 @@ unsafe impl Sync for Meh {} // the following will never be ok! no interior mut behind consts, because // all allocs interned here will be marked immutable. const MUH: Meh = Meh { - //~^ ERROR encountered mutable pointer in final value of constant - //~| WARNING this was previously accepted by the compiler - //~| ERROR: it is undefined behavior to use this value + //~^ ERROR it is undefined behavior to use this value x: &UnsafeCell::new(42), }; @@ -29,9 +27,7 @@ unsafe impl Sync for Synced {} // Make sure we also catch this behind a type-erased `dyn Trait` reference. const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) }; -//~^ ERROR: mutable pointer in final value -//~| WARNING this was previously accepted by the compiler -//~| ERROR it is undefined behavior to use this value +//~^ ERROR: it is undefined behavior to use this value // Make sure we also catch mutable references in values that shouldn't have them. static mut FOO: i32 = 0; @@ -40,9 +36,7 @@ const SUBTLE: &mut i32 = unsafe { &mut FOO }; //~| static const BLUNT: &mut i32 = &mut 42; -//~^ ERROR: mutable pointer in final value -//~| WARNING this was previously accepted by the compiler -//~| ERROR it is undefined behavior to use this value +//~^ ERROR: it is undefined behavior to use this value // Check for mutable references to read-only memory. static READONLY: i32 = 0; diff --git a/tests/ui/consts/miri_unleashed/mutable_references_err.stderr b/tests/ui/consts/miri_unleashed/mutable_references_err.stderr index 45615f523a6f5..d385b45a3df91 100644 --- a/tests/ui/consts/miri_unleashed/mutable_references_err.stderr +++ b/tests/ui/consts/miri_unleashed/mutable_references_err.stderr @@ -1,17 +1,3 @@ -error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:18:1 - | -LL | const MUH: Meh = Meh { - | ^^^^^^^^^^^^^^ - | - = 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 -note: the lint level is defined here - --> $DIR/mutable_references_err.rs:5:9 - | -LL | #![deny(const_eval_mutable_ptr_in_final_value)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0080]: it is undefined behavior to use this value --> $DIR/mutable_references_err.rs:18:1 | @@ -23,17 +9,8 @@ LL | const MUH: Meh = Meh { HEX_DUMP } -error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:31:1 - | -LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::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 - error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references_err.rs:31:1 + --> $DIR/mutable_references_err.rs:29:1 | LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ...x: encountered `UnsafeCell` in read-only memory @@ -44,7 +21,7 @@ LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references_err.rs:38:1 + --> $DIR/mutable_references_err.rs:34:1 | LL | const SUBTLE: &mut i32 = unsafe { &mut FOO }; | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` @@ -54,17 +31,8 @@ LL | const SUBTLE: &mut i32 = unsafe { &mut FOO }; HEX_DUMP } -error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:42:1 - | -LL | const BLUNT: &mut i32 = &mut 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 - error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references_err.rs:42:1 + --> $DIR/mutable_references_err.rs:38:1 | LL | const BLUNT: &mut i32 = &mut 42; | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory @@ -75,7 +43,7 @@ LL | const BLUNT: &mut i32 = &mut 42; } error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references_err.rs:49:1 + --> $DIR/mutable_references_err.rs:43:1 | 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 @@ -86,7 +54,7 @@ LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const } error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references_err.rs:56:1 + --> $DIR/mutable_references_err.rs:50:1 | LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` @@ -97,28 +65,33 @@ LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE }; } note: erroneous constant encountered - --> $DIR/mutable_references_err.rs:58:34 + --> $DIR/mutable_references_err.rs:52:34 | LL | const READS_FROM_MUTABLE: i32 = *POINTS_TO_MUTABLE1; | ^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed - --> $DIR/mutable_references_err.rs:60:43 + --> $DIR/mutable_references_err.rs:54:43 | LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF }; | ^^^^^^^^^^^^^ constant accesses mutable global memory error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:64:1 + --> $DIR/mutable_references_err.rs:58: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 +note: the lint level is defined here + --> $DIR/mutable_references_err.rs:5:9 + | +LL | #![deny(const_eval_mutable_ptr_in_final_value)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:68:1 + --> $DIR/mutable_references_err.rs:62:1 | LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -127,7 +100,7 @@ LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _; = note: for more information, see issue #122153 error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:72:1 + --> $DIR/mutable_references_err.rs:66:1 | LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -136,7 +109,7 @@ LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *cons = note: for more information, see issue #122153 error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:85:1 + --> $DIR/mutable_references_err.rs:79:1 | LL | const RAW_SYNC: SyncPtr = SyncPtr { x: &AtomicI32::new(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -145,7 +118,7 @@ LL | const RAW_SYNC: SyncPtr = SyncPtr { x: &AtomicI32::new(42) }; = note: for more information, see issue #122153 error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:89:1 + --> $DIR/mutable_references_err.rs:83:1 | LL | const RAW_MUT_CAST: SyncPtr = SyncPtr { x: &mut 42 as *mut _ as *const _ }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -154,7 +127,7 @@ LL | const RAW_MUT_CAST: SyncPtr = SyncPtr { x: &mut 42 as *mut _ as *const = note: for more information, see issue #122153 error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:93:1 + --> $DIR/mutable_references_err.rs:87:1 | LL | const RAW_MUT_COERCE: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -165,132 +138,87 @@ LL | const RAW_MUT_COERCE: SyncPtr = SyncPtr { x: &mut 0 }; warning: skipping const checks | help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:22:8 + --> $DIR/mutable_references_err.rs:20:8 | LL | x: &UnsafeCell::new(42), | ^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:31:27 + --> $DIR/mutable_references_err.rs:29:27 | LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/mutable_references_err.rs:38:40 + --> $DIR/mutable_references_err.rs:34:40 | LL | const SUBTLE: &mut i32 = unsafe { &mut FOO }; | ^^^ help: skipping check for `const_mut_refs` feature - --> $DIR/mutable_references_err.rs:38:35 + --> $DIR/mutable_references_err.rs:34:35 | LL | const SUBTLE: &mut i32 = unsafe { &mut FOO }; | ^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:42:25 + --> $DIR/mutable_references_err.rs:38:25 | LL | const BLUNT: &mut i32 = &mut 42; | ^^^^^^^ help: skipping check for `const_mut_refs` feature - --> $DIR/mutable_references_err.rs:49:49 + --> $DIR/mutable_references_err.rs:43:49 | LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_mut_refs` feature - --> $DIR/mutable_references_err.rs:49:49 + --> $DIR/mutable_references_err.rs:43:49 | LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/mutable_references_err.rs:56:44 + --> $DIR/mutable_references_err.rs:50:44 | LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE }; | ^^^^^^^ help: skipping check for `const_refs_to_static` feature - --> $DIR/mutable_references_err.rs:60:45 + --> $DIR/mutable_references_err.rs:54: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:64:45 + --> $DIR/mutable_references_err.rs:58: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:68:46 + --> $DIR/mutable_references_err.rs:62: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:72:47 + --> $DIR/mutable_references_err.rs:66: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:85:51 + --> $DIR/mutable_references_err.rs:79:51 | LL | const RAW_SYNC: SyncPtr = SyncPtr { x: &AtomicI32::new(42) }; | ^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:89:49 + --> $DIR/mutable_references_err.rs:83:49 | LL | const RAW_MUT_CAST: SyncPtr = SyncPtr { x: &mut 42 as *mut _ as *const _ }; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:93:51 + --> $DIR/mutable_references_err.rs:87:51 | LL | const RAW_MUT_COERCE: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^ -error: aborting due to 16 previous errors; 1 warning emitted +error: aborting due to 13 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0080`. Future incompatibility report: Future breakage diagnostic: error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:18:1 - | -LL | const MUH: Meh = Meh { - | ^^^^^^^^^^^^^^ - | - = 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 -note: the lint level is defined here - --> $DIR/mutable_references_err.rs:5: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_err.rs:31:1 - | -LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::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 -note: the lint level is defined here - --> $DIR/mutable_references_err.rs:5: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_err.rs:42:1 - | -LL | const BLUNT: &mut i32 = &mut 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 -note: the lint level is defined here - --> $DIR/mutable_references_err.rs:5: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_err.rs:64:1 + --> $DIR/mutable_references_err.rs:58:1 | LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -305,7 +233,7 @@ LL | #![deny(const_eval_mutable_ptr_in_final_value)] Future breakage diagnostic: error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:68:1 + --> $DIR/mutable_references_err.rs:62:1 | LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -320,7 +248,7 @@ LL | #![deny(const_eval_mutable_ptr_in_final_value)] Future breakage diagnostic: error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:72:1 + --> $DIR/mutable_references_err.rs:66:1 | LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -335,7 +263,7 @@ LL | #![deny(const_eval_mutable_ptr_in_final_value)] Future breakage diagnostic: error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:85:1 + --> $DIR/mutable_references_err.rs:79:1 | LL | const RAW_SYNC: SyncPtr = SyncPtr { x: &AtomicI32::new(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -350,7 +278,7 @@ LL | #![deny(const_eval_mutable_ptr_in_final_value)] Future breakage diagnostic: error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:89:1 + --> $DIR/mutable_references_err.rs:83:1 | LL | const RAW_MUT_CAST: SyncPtr = SyncPtr { x: &mut 42 as *mut _ as *const _ }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -365,7 +293,7 @@ LL | #![deny(const_eval_mutable_ptr_in_final_value)] Future breakage diagnostic: error: encountered mutable pointer in final value of constant - --> $DIR/mutable_references_err.rs:93:1 + --> $DIR/mutable_references_err.rs:87:1 | LL | const RAW_MUT_COERCE: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/consts/miri_unleashed/static-no-inner-mut.32bit.stderr b/tests/ui/consts/miri_unleashed/static-no-inner-mut.32bit.stderr index 85ed6cbd5383d..3ee34746b8816 100644 --- a/tests/ui/consts/miri_unleashed/static-no-inner-mut.32bit.stderr +++ b/tests/ui/consts/miri_unleashed/static-no-inner-mut.32bit.stderr @@ -1,77 +1,63 @@ -error: encountered mutable pointer in final value of static +error[E0080]: it is undefined behavior to use this value --> $DIR/static-no-inner-mut.rs:9:1 | LL | static REF: &AtomicI32 = &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 -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:13:1 + | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..v: encountered `UnsafeCell` in read-only memory | -LL | static REFMUT: &mut i32 = &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 + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾ALLOC0╼ │ ╾──╼ + } error[E0080]: it is undefined behavior to use this value - --> $DIR/static-no-inner-mut.rs:13:1 + --> $DIR/static-no-inner-mut.rs:12:1 | LL | static REFMUT: &mut i32 = &mut 0; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory | = 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╼ │ ╾──╼ + ╾ALLOC1╼ │ ╾──╼ } -error: encountered mutable pointer in final value of static - --> $DIR/static-no-inner-mut.rs:19:1 +error[E0080]: it is undefined behavior to use this value + --> $DIR/static-no-inner-mut.rs:16:1 | LL | static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}}; - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..v: encountered `UnsafeCell` in read-only memory | - = 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 - -error: encountered mutable pointer in final value of static - --> $DIR/static-no-inner-mut.rs:23:1 - | -LL | static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}}; - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = 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 + = 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╼ │ ╾──╼ + } error[E0080]: it is undefined behavior to use this value - --> $DIR/static-no-inner-mut.rs:23:1 + --> $DIR/static-no-inner-mut.rs:17:1 | LL | static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}}; | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory | = 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╼ │ ╾──╼ + ╾ALLOC3╼ │ ╾──╼ } error: encountered mutable pointer in final value of static - --> $DIR/static-no-inner-mut.rs:41:1 + --> $DIR/static-no-inner-mut.rs:32:1 | LL | static RAW_SYNC: SyncPtr = 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 +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:45:1 + --> $DIR/static-no-inner-mut.rs:36:1 | LL | static RAW_MUT_CAST: SyncPtr = SyncPtr { x : &mut 42 as *mut _ as *const _ }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -80,7 +66,7 @@ LL | static RAW_MUT_CAST: SyncPtr = SyncPtr { x : &mut 42 as *mut _ as *con = note: for more information, see issue #122153 error: encountered mutable pointer in final value of static - --> $DIR/static-no-inner-mut.rs:49:1 + --> $DIR/static-no-inner-mut.rs:40:1 | LL | static RAW_MUT_COERCE: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -96,102 +82,42 @@ help: skipping check that does not even have a feature gate LL | static REF: &AtomicI32 = &AtomicI32::new(42); | ^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/static-no-inner-mut.rs:13:27 + --> $DIR/static-no-inner-mut.rs:12:27 | LL | static REFMUT: &mut i32 = &mut 0; | ^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/static-no-inner-mut.rs:19:56 + --> $DIR/static-no-inner-mut.rs:16:56 | LL | static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}}; | ^^^^ help: skipping check that does not even have a feature gate - --> $DIR/static-no-inner-mut.rs:23:44 + --> $DIR/static-no-inner-mut.rs:17:44 | LL | static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}}; | ^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/static-no-inner-mut.rs:41:52 + --> $DIR/static-no-inner-mut.rs:32:52 | LL | static RAW_SYNC: SyncPtr = SyncPtr { x: &AtomicI32::new(42) }; | ^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/static-no-inner-mut.rs:45:51 + --> $DIR/static-no-inner-mut.rs:36:51 | LL | static RAW_MUT_CAST: SyncPtr = SyncPtr { x : &mut 42 as *mut _ as *const _ }; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/static-no-inner-mut.rs:49:52 + --> $DIR/static-no-inner-mut.rs:40:52 | LL | static RAW_MUT_COERCE: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^ -error: aborting due to 9 previous errors; 1 warning emitted +error: aborting due to 7 previous errors; 1 warning emitted 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:9:1 - | -LL | static REF: &AtomicI32 = &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 -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:13:1 - | -LL | static REFMUT: &mut i32 = &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 -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:19:1 - | -LL | static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}}; - | ^^^^^^^^^^^^^^^^^^^^^^^ - | - = 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 -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:23:1 - | -LL | static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}}; - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = 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 -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:41:1 + --> $DIR/static-no-inner-mut.rs:32:1 | LL | static RAW_SYNC: SyncPtr = SyncPtr { x: &AtomicI32::new(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -206,7 +132,7 @@ 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:45:1 + --> $DIR/static-no-inner-mut.rs:36:1 | LL | static RAW_MUT_CAST: SyncPtr = SyncPtr { x : &mut 42 as *mut _ as *const _ }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -221,7 +147,7 @@ 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:49:1 + --> $DIR/static-no-inner-mut.rs:40:1 | LL | static RAW_MUT_COERCE: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/consts/miri_unleashed/static-no-inner-mut.64bit.stderr b/tests/ui/consts/miri_unleashed/static-no-inner-mut.64bit.stderr index 5aa1cd0b15fc0..d0a2a4eaf67b7 100644 --- a/tests/ui/consts/miri_unleashed/static-no-inner-mut.64bit.stderr +++ b/tests/ui/consts/miri_unleashed/static-no-inner-mut.64bit.stderr @@ -1,77 +1,63 @@ -error: encountered mutable pointer in final value of static +error[E0080]: it is undefined behavior to use this value --> $DIR/static-no-inner-mut.rs:9:1 | LL | static REF: &AtomicI32 = &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 -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:13:1 + | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..v: encountered `UnsafeCell` in read-only memory | -LL | static REFMUT: &mut i32 = &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 + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾ALLOC0╼ │ ╾──────╼ + } error[E0080]: it is undefined behavior to use this value - --> $DIR/static-no-inner-mut.rs:13:1 + --> $DIR/static-no-inner-mut.rs:12:1 | LL | static REFMUT: &mut i32 = &mut 0; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory | = 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╼ │ ╾──────╼ + ╾ALLOC1╼ │ ╾──────╼ } -error: encountered mutable pointer in final value of static - --> $DIR/static-no-inner-mut.rs:19:1 +error[E0080]: it is undefined behavior to use this value + --> $DIR/static-no-inner-mut.rs:16:1 | LL | static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}}; - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..v: encountered `UnsafeCell` in read-only memory | - = 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 - -error: encountered mutable pointer in final value of static - --> $DIR/static-no-inner-mut.rs:23:1 - | -LL | static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}}; - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = 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 + = 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╼ │ ╾──────╼ + } error[E0080]: it is undefined behavior to use this value - --> $DIR/static-no-inner-mut.rs:23:1 + --> $DIR/static-no-inner-mut.rs:17:1 | LL | static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}}; | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory | = 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╼ │ ╾──────╼ + ╾ALLOC3╼ │ ╾──────╼ } error: encountered mutable pointer in final value of static - --> $DIR/static-no-inner-mut.rs:41:1 + --> $DIR/static-no-inner-mut.rs:32:1 | LL | static RAW_SYNC: SyncPtr = 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 +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:45:1 + --> $DIR/static-no-inner-mut.rs:36:1 | LL | static RAW_MUT_CAST: SyncPtr = SyncPtr { x : &mut 42 as *mut _ as *const _ }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -80,7 +66,7 @@ LL | static RAW_MUT_CAST: SyncPtr = SyncPtr { x : &mut 42 as *mut _ as *con = note: for more information, see issue #122153 error: encountered mutable pointer in final value of static - --> $DIR/static-no-inner-mut.rs:49:1 + --> $DIR/static-no-inner-mut.rs:40:1 | LL | static RAW_MUT_COERCE: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -96,102 +82,42 @@ help: skipping check that does not even have a feature gate LL | static REF: &AtomicI32 = &AtomicI32::new(42); | ^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/static-no-inner-mut.rs:13:27 + --> $DIR/static-no-inner-mut.rs:12:27 | LL | static REFMUT: &mut i32 = &mut 0; | ^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/static-no-inner-mut.rs:19:56 + --> $DIR/static-no-inner-mut.rs:16:56 | LL | static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}}; | ^^^^ help: skipping check that does not even have a feature gate - --> $DIR/static-no-inner-mut.rs:23:44 + --> $DIR/static-no-inner-mut.rs:17:44 | LL | static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}}; | ^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/static-no-inner-mut.rs:41:52 + --> $DIR/static-no-inner-mut.rs:32:52 | LL | static RAW_SYNC: SyncPtr = SyncPtr { x: &AtomicI32::new(42) }; | ^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/static-no-inner-mut.rs:45:51 + --> $DIR/static-no-inner-mut.rs:36:51 | LL | static RAW_MUT_CAST: SyncPtr = SyncPtr { x : &mut 42 as *mut _ as *const _ }; | ^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/static-no-inner-mut.rs:49:52 + --> $DIR/static-no-inner-mut.rs:40:52 | LL | static RAW_MUT_COERCE: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^ -error: aborting due to 9 previous errors; 1 warning emitted +error: aborting due to 7 previous errors; 1 warning emitted 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:9:1 - | -LL | static REF: &AtomicI32 = &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 -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:13:1 - | -LL | static REFMUT: &mut i32 = &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 -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:19:1 - | -LL | static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}}; - | ^^^^^^^^^^^^^^^^^^^^^^^ - | - = 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 -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:23:1 - | -LL | static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}}; - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = 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 -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:41:1 + --> $DIR/static-no-inner-mut.rs:32:1 | LL | static RAW_SYNC: SyncPtr = SyncPtr { x: &AtomicI32::new(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -206,7 +132,7 @@ 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:45:1 + --> $DIR/static-no-inner-mut.rs:36:1 | LL | static RAW_MUT_CAST: SyncPtr = SyncPtr { x : &mut 42 as *mut _ as *const _ }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -221,7 +147,7 @@ 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:49:1 + --> $DIR/static-no-inner-mut.rs:40:1 | LL | static RAW_MUT_COERCE: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/consts/miri_unleashed/static-no-inner-mut.rs b/tests/ui/consts/miri_unleashed/static-no-inner-mut.rs index e82ca50d8822d..3cf1dfe6d76dc 100644 --- a/tests/ui/consts/miri_unleashed/static-no-inner-mut.rs +++ b/tests/ui/consts/miri_unleashed/static-no-inner-mut.rs @@ -7,23 +7,14 @@ use std::sync::atomic::*; static REF: &AtomicI32 = &AtomicI32::new(42); -//~^ ERROR mutable pointer in final value -//~| WARNING this was previously accepted by the compiler +//~^ ERROR it is undefined behavior to use this value static REFMUT: &mut i32 = &mut 0; -//~^ ERROR mutable pointer in final value -//~| WARNING this was previously accepted by the compiler -//~| ERROR it is undefined behavior to use this value +//~^ ERROR it is undefined behavior to use this value // Different way of writing this that avoids promotion. -static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}}; -//~^ ERROR mutable pointer in final value -//~| WARNING this was previously accepted by the compiler - -static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}}; -//~^ ERROR mutable pointer in final value -//~| WARNING this was previously accepted by the compiler -//~| ERROR it is undefined behavior to use this value +static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}}; //~ERROR it is undefined behavior to use this value +static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}}; //~ERROR it is undefined behavior to use this value // This one is obvious, since it is non-Sync. (It also suppresses the other errors, so it is // commented out.) diff --git a/tests/ui/consts/std/cell.rs b/tests/ui/consts/std/cell.rs index f1ef541319a4b..a97ec9e522ac8 100644 --- a/tests/ui/consts/std/cell.rs +++ b/tests/ui/consts/std/cell.rs @@ -4,9 +4,9 @@ use std::cell::*; // not ok, because this creates a dangling pointer, just like `let x = Cell::new(42).as_ptr()` would static FOO: Wrap<*mut u32> = Wrap(Cell::new(42).as_ptr()); -//~^ ERROR encountered dangling pointer +//~^ ERROR it is undefined behavior const FOO_CONST: Wrap<*mut u32> = Wrap(Cell::new(42).as_ptr()); -//~^ ERROR encountered dangling pointer +//~^ ERROR it is undefined behavior // Ok, these are just base values and it is the `Wrap` author's job to uphold `Send` and `Sync` // invariants, since they used `unsafe impl`. @@ -20,12 +20,12 @@ static FOO4: Wrap<*mut u32> = Wrap(FOO3.0.as_ptr()); // its memory will get freed before the constant is finished evaluating, thus creating a dangling // pointer. This would happen exactly the same at runtime. const FOO4_CONST: Wrap<*mut u32> = Wrap(FOO3_CONST.0.as_ptr()); -//~^ ERROR encountered dangling pointer +//~^ ERROR it is undefined behavior // not ok, because the `as_ptr` call takes a reference to a temporary that will get freed // before the constant is finished evaluating. const FOO2: *mut u32 = Cell::new(42).as_ptr(); -//~^ ERROR encountered dangling pointer +//~^ ERROR it is undefined behavior struct IMSafeTrustMe(UnsafeCell); unsafe impl Send for IMSafeTrustMe {} @@ -33,14 +33,14 @@ unsafe impl Sync for IMSafeTrustMe {} static BAR: IMSafeTrustMe = IMSafeTrustMe(UnsafeCell::new(5)); - - struct Wrap(T); unsafe impl Send for Wrap {} unsafe impl Sync for Wrap {} static BAR_PTR: Wrap<*mut u32> = Wrap(BAR.0.get()); -const fn fst_ref(x: &(T, U)) -> &T { &x.0 } +const fn fst_ref(x: &(T, U)) -> &T { + &x.0 +} fn main() {} diff --git a/tests/ui/consts/std/cell.stderr b/tests/ui/consts/std/cell.stderr index 873b797a466db..fda4bab087094 100644 --- a/tests/ui/consts/std/cell.stderr +++ b/tests/ui/consts/std/cell.stderr @@ -1,26 +1,47 @@ -error: encountered dangling pointer in final value of static +error[E0080]: it is undefined behavior to use this value --> $DIR/cell.rs:6:1 | LL | static FOO: Wrap<*mut u32> = Wrap(Cell::new(42).as_ptr()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered a dangling reference (use-after-free) + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾ALLOC0╼ │ ╾──────╼ + } -error: encountered dangling pointer in final value of constant +error[E0080]: it is undefined behavior to use this value --> $DIR/cell.rs:8:1 | LL | const FOO_CONST: Wrap<*mut u32> = Wrap(Cell::new(42).as_ptr()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered a dangling reference (use-after-free) + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾ALLOC1╼ │ ╾──────╼ + } -error: encountered dangling pointer in final value of constant +error[E0080]: it is undefined behavior to use this value --> $DIR/cell.rs:22:1 | LL | const FOO4_CONST: Wrap<*mut u32> = Wrap(FOO3_CONST.0.as_ptr()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered a dangling reference (use-after-free) + | + = 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╼ │ ╾──────╼ + } -error: encountered dangling pointer in final value of constant +error[E0080]: it is undefined behavior to use this value --> $DIR/cell.rs:27:1 | LL | const FOO2: *mut u32 = Cell::new(42).as_ptr(); - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (use-after-free) + | + = 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) { + ╾ALLOC3╼ │ ╾──────╼ + } error: aborting due to 4 previous errors +For more information about this error, try `rustc --explain E0080`.