Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit aee26a8

Browse files
committedJan 6, 2024
validation: descend from consts into statics
1 parent 60b12fd commit aee26a8

25 files changed

+327
-210
lines changed
 

‎compiler/rustc_const_eval/messages.ftl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,9 +215,6 @@ const_eval_modified_global =
215215
const_eval_mut_deref =
216216
mutation through a reference is not allowed in {const_eval_const_context}s
217217
218-
const_eval_mutable_data_in_const =
219-
constant refers to mutable data
220-
221218
const_eval_mutable_ptr_in_final = encountered mutable pointer in final value of {const_eval_intern_kind}
222219
223220
const_eval_non_const_fmt_macro_call =
@@ -414,6 +411,9 @@ const_eval_upcast_mismatch =
414411
## (We'd love to sort this differently to make that more clear but tidy won't let us...)
415412
const_eval_validation_box_to_static = {$front_matter}: encountered a box pointing to a static variable in a constant
416413
const_eval_validation_box_to_uninhabited = {$front_matter}: encountered a box pointing to uninhabited type {$ty}
414+
415+
const_eval_validation_const_ref_to_mutable = {$front_matter}: encountered reference to mutable memory in `const`
416+
417417
const_eval_validation_dangling_box_no_provenance = {$front_matter}: encountered a dangling box ({$pointer} has no provenance)
418418
const_eval_validation_dangling_box_out_of_bounds = {$front_matter}: encountered a dangling box (going beyond the bounds of its allocation)
419419
const_eval_validation_dangling_box_use_after_free = {$front_matter}: encountered a dangling box (use-after-free)

‎compiler/rustc_const_eval/src/const_eval/mod.rs

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
// Not in interpret to make sure we do not use private implementation details
22

3-
use crate::interpret::InterpCx;
43
use rustc_middle::mir;
5-
use rustc_middle::mir::interpret::{InterpError, InterpErrorInfo};
4+
use rustc_middle::mir::interpret::InterpErrorInfo;
65
use rustc_middle::query::TyCtxtAt;
76
use rustc_middle::ty::{self, Ty};
87

8+
use crate::interpret::{format_interp_error, InterpCx};
9+
910
mod error;
1011
mod eval_queries;
1112
mod fn_queries;
@@ -25,24 +26,17 @@ pub(crate) enum ValTreeCreationError {
2526
NodesOverflow,
2627
/// Values of this type, or this particular value, are not supported as valtrees.
2728
NonSupportedType,
28-
/// The value pointed to non-read-only memory, so we cannot make it a valtree.
29-
NotReadOnly,
30-
Other,
3129
}
3230
pub(crate) type ValTreeCreationResult<'tcx> = Result<ty::ValTree<'tcx>, ValTreeCreationError>;
3331

3432
impl From<InterpErrorInfo<'_>> for ValTreeCreationError {
3533
fn from(err: InterpErrorInfo<'_>) -> Self {
36-
match err.kind() {
37-
InterpError::MachineStop(err) => {
38-
let err = err.downcast_ref::<ConstEvalErrKind>().unwrap();
39-
match err {
40-
ConstEvalErrKind::ConstAccessesMutGlobal => ValTreeCreationError::NotReadOnly,
41-
_ => ValTreeCreationError::Other,
42-
}
43-
}
44-
_ => ValTreeCreationError::Other,
45-
}
34+
ty::tls::with(|tcx| {
35+
bug!(
36+
"Unexpected Undefined Behavior error during valtree construction: {}",
37+
format_interp_error(tcx.dcx(), err),
38+
)
39+
})
4640
}
4741
}
4842

‎compiler/rustc_const_eval/src/const_eval/valtrees.rs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use super::eval_queries::{mk_eval_cx, op_to_const};
99
use super::machine::CompileTimeEvalContext;
1010
use super::{ValTreeCreationError, ValTreeCreationResult, VALTREE_MAX_NODES};
1111
use crate::const_eval::CanAccessMutGlobal;
12-
use crate::errors::{MaxNumNodesInConstErr, MutableDataInConstErr};
12+
use crate::errors::MaxNumNodesInConstErr;
1313
use crate::interpret::MPlaceTy;
1414
use crate::interpret::{
1515
intern_const_alloc_recursive, ImmTy, Immediate, InternKind, MemPlaceMeta, MemoryKind, PlaceTy,
@@ -248,18 +248,6 @@ pub(crate) fn eval_to_valtree<'tcx>(
248248
tcx.dcx().emit_err(MaxNumNodesInConstErr { span, global_const_id });
249249
Err(handled.into())
250250
}
251-
ValTreeCreationError::NotReadOnly => {
252-
let handled =
253-
tcx.dcx().emit_err(MutableDataInConstErr { span, global_const_id });
254-
Err(handled.into())
255-
}
256-
ValTreeCreationError::Other => {
257-
let handled = tcx.dcx().span_delayed_bug(
258-
span.unwrap_or(DUMMY_SP),
259-
"unexpected error during valtree construction",
260-
);
261-
Err(handled.into())
262-
}
263251
ValTreeCreationError::NonSupportedType => Ok(None),
264252
}
265253
}

‎compiler/rustc_const_eval/src/errors.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,6 @@ pub(crate) struct MaxNumNodesInConstErr {
117117
pub global_const_id: String,
118118
}
119119

120-
#[derive(Diagnostic)]
121-
#[diag(const_eval_mutable_data_in_const)]
122-
pub(crate) struct MutableDataInConstErr {
123-
#[primary_span]
124-
pub span: Option<Span>,
125-
pub global_const_id: String,
126-
}
127-
128120
#[derive(Diagnostic)]
129121
#[diag(const_eval_unallowed_fn_pointer_call)]
130122
pub(crate) struct UnallowedFnPointerCall {
@@ -619,6 +611,7 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
619611

620612
PointerAsInt { .. } => const_eval_validation_pointer_as_int,
621613
PartialPointer => const_eval_validation_partial_pointer,
614+
ConstRefToMutable => const_eval_validation_const_ref_to_mutable,
622615
MutableRefInConst => const_eval_validation_mutable_ref_in_const,
623616
MutableRefToImmutable => const_eval_validation_mutable_ref_to_immutable,
624617
NullFnPtr => const_eval_validation_null_fn_ptr,
@@ -773,6 +766,7 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
773766
NullPtr { .. }
774767
| PtrToStatic { .. }
775768
| MutableRefInConst
769+
| ConstRefToMutable
776770
| MutableRefToImmutable
777771
| NullFnPtr
778772
| NeverVal

‎compiler/rustc_const_eval/src/interpret/eval_context.rs

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::{fmt, mem};
44
use either::{Either, Left, Right};
55

66
use hir::CRATE_HIR_ID;
7+
use rustc_errors::DiagCtxt;
78
use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData};
89
use rustc_index::IndexVec;
910
use rustc_middle::mir;
@@ -430,6 +431,26 @@ pub(super) fn from_known_layout<'tcx>(
430431
}
431432
}
432433

434+
/// Turn the given error into a human-readable string. Expects the string to be printed, so if
435+
/// `RUSTC_CTFE_BACKTRACE` is set this will show a backtrace of the rustc internals that
436+
/// triggered the error.
437+
///
438+
/// This is NOT the preferred way to render an error; use `report` from `const_eval` instead.
439+
/// However, this is useful when error messages appear in ICEs.
440+
pub fn format_interp_error<'tcx>(dcx: &DiagCtxt, e: InterpErrorInfo<'tcx>) -> String {
441+
let (e, backtrace) = e.into_parts();
442+
backtrace.print_backtrace();
443+
// FIXME(fee1-dead), HACK: we want to use the error as title therefore we can just extract the
444+
// label and arguments from the InterpError.
445+
#[allow(rustc::untranslatable_diagnostic)]
446+
let mut diag = dcx.struct_allow("");
447+
let msg = e.diagnostic_message();
448+
e.add_args(dcx, &mut diag);
449+
let s = dcx.eagerly_translate_to_string(msg, diag.args());
450+
diag.cancel();
451+
s
452+
}
453+
433454
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
434455
pub fn new(
435456
tcx: TyCtxt<'tcx>,
@@ -462,27 +483,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
462483
.map_or(CRATE_HIR_ID, |def_id| self.tcx.local_def_id_to_hir_id(def_id))
463484
}
464485

465-
/// Turn the given error into a human-readable string. Expects the string to be printed, so if
466-
/// `RUSTC_CTFE_BACKTRACE` is set this will show a backtrace of the rustc internals that
467-
/// triggered the error.
468-
///
469-
/// This is NOT the preferred way to render an error; use `report` from `const_eval` instead.
470-
/// However, this is useful when error messages appear in ICEs.
471-
pub fn format_error(&self, e: InterpErrorInfo<'tcx>) -> String {
472-
let (e, backtrace) = e.into_parts();
473-
backtrace.print_backtrace();
474-
// FIXME(fee1-dead), HACK: we want to use the error as title therefore we can just extract the
475-
// label and arguments from the InterpError.
476-
let dcx = self.tcx.dcx();
477-
#[allow(rustc::untranslatable_diagnostic)]
478-
let mut diag = dcx.struct_allow("");
479-
let msg = e.diagnostic_message();
480-
e.add_args(dcx, &mut diag);
481-
let s = dcx.eagerly_translate_to_string(msg, diag.args());
482-
diag.cancel();
483-
s
484-
}
485-
486486
#[inline(always)]
487487
pub(crate) fn stack(&self) -> &[Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>] {
488488
M::stack(self)

‎compiler/rustc_const_eval/src/interpret/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ mod visitor;
2020

2121
pub use rustc_middle::mir::interpret::*; // have all the `interpret` symbols in one place: here
2222

23-
pub use self::eval_context::{Frame, FrameInfo, InterpCx, StackPopCleanup};
23+
pub use self::eval_context::{format_interp_error, Frame, FrameInfo, InterpCx, StackPopCleanup};
2424
pub use self::intern::{
2525
intern_const_alloc_for_constprop, intern_const_alloc_recursive, InternKind,
2626
};

‎compiler/rustc_const_eval/src/interpret/validity.rs

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ use rustc_target::abi::{
2727
use std::hash::Hash;
2828

2929
use super::{
30-
AllocId, CheckInAllocMsg, GlobalAlloc, ImmTy, Immediate, InterpCx, InterpResult, MPlaceTy,
31-
Machine, MemPlaceMeta, OpTy, Pointer, Projectable, Scalar, ValueVisitor,
30+
format_interp_error, AllocId, CheckInAllocMsg, GlobalAlloc, ImmTy, Immediate, InterpCx,
31+
InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy, Pointer, Projectable, Scalar,
32+
ValueVisitor,
3233
};
3334

3435
// for the validation errors
@@ -460,46 +461,49 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
460461
// Special handling for pointers to statics (irrespective of their type).
461462
assert!(!self.ecx.tcx.is_thread_local_static(did));
462463
assert!(self.ecx.tcx.is_static(did));
464+
let is_mut =
465+
matches!(self.ecx.tcx.def_kind(did), DefKind::Static(Mutability::Mut))
466+
|| !self
467+
.ecx
468+
.tcx
469+
.type_of(did)
470+
.no_bound_vars()
471+
.expect("statics should not have generic parameters")
472+
.is_freeze(*self.ecx.tcx, ty::ParamEnv::reveal_all());
463473
// Mutability check.
464474
if ptr_expected_mutbl == Mutability::Mut {
465-
if matches!(
466-
self.ecx.tcx.def_kind(did),
467-
DefKind::Static(Mutability::Not)
468-
) && self
469-
.ecx
470-
.tcx
471-
.type_of(did)
472-
.no_bound_vars()
473-
.expect("statics should not have generic parameters")
474-
.is_freeze(*self.ecx.tcx, ty::ParamEnv::reveal_all())
475-
{
475+
if !is_mut {
476476
throw_validation_failure!(self.path, MutableRefToImmutable);
477477
}
478478
}
479-
// We skip recursively checking other statics. These statics must be sound by
480-
// themselves, and the only way to get broken statics here is by using
481-
// unsafe code.
482-
// The reasons we don't check other statics is twofold. For one, in all
483-
// sound cases, the static was already validated on its own, and second, we
484-
// trigger cycle errors if we try to compute the value of the other static
485-
// and that static refers back to us.
486-
// We might miss const-invalid data,
487-
// but things are still sound otherwise (in particular re: consts
488-
// referring to statics).
489-
return Ok(());
479+
match self.ctfe_mode {
480+
Some(CtfeValidationMode::Static { .. }) => {
481+
// We skip recursively checking other statics. These statics must be sound by
482+
// themselves, and the only way to get broken statics here is by using
483+
// unsafe code.
484+
// The reasons we don't check other statics is twofold. For one, in all
485+
// sound cases, the static was already validated on its own, and second, we
486+
// trigger cycle errors if we try to compute the value of the other static
487+
// and that static refers back to us.
488+
// This could miss some UB, but that's fine.
489+
return Ok(());
490+
}
491+
Some(CtfeValidationMode::Const { .. }) => {
492+
// For consts on the other hand we have to recursively check;
493+
// pattern matching assumes a valid value. However we better make
494+
// sure this is not mutable.
495+
if is_mut {
496+
throw_validation_failure!(self.path, ConstRefToMutable);
497+
}
498+
}
499+
None => {}
500+
}
490501
}
491502
GlobalAlloc::Memory(alloc) => {
492503
if alloc.inner().mutability == Mutability::Mut
493504
&& matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { .. }))
494505
{
495-
// This is impossible: this can only be some inner allocation of a
496-
// `static mut` (everything else either hits the `GlobalAlloc::Static`
497-
// case or is interned immutably). To get such a pointer we'd have to
498-
// load it from a static, but such loads lead to a CTFE error.
499-
span_bug!(
500-
self.ecx.tcx.span,
501-
"encountered reference to mutable memory inside a `const`"
502-
);
506+
throw_validation_failure!(self.path, ConstRefToMutable);
503507
}
504508
if ptr_expected_mutbl == Mutability::Mut
505509
&& alloc.inner().mutability == Mutability::Not
@@ -979,7 +983,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
979983
Err(err) => {
980984
bug!(
981985
"Unexpected Undefined Behavior error during validation: {}",
982-
self.format_error(err)
986+
format_interp_error(self.tcx.dcx(), err)
983987
);
984988
}
985989
}

‎compiler/rustc_middle/src/mir/interpret/error.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ pub enum ValidationErrorKind<'tcx> {
425425
PtrToUninhabited { ptr_kind: PointerKind, ty: Ty<'tcx> },
426426
PtrToStatic { ptr_kind: PointerKind },
427427
MutableRefInConst,
428+
ConstRefToMutable,
428429
MutableRefToImmutable,
429430
UnsafeCellInImmutable,
430431
NullFnPtr,

‎compiler/rustc_mir_transform/src/const_prop_lint.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use either::Left;
77

88
use rustc_const_eval::interpret::Immediate;
99
use rustc_const_eval::interpret::{
10-
InterpCx, InterpResult, MemoryKind, OpTy, Scalar, StackPopCleanup,
10+
format_interp_error, InterpCx, InterpResult, MemoryKind, OpTy, Scalar, StackPopCleanup,
1111
};
1212
use rustc_const_eval::ReportErrorExt;
1313
use rustc_hir::def::DefKind;
@@ -236,7 +236,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
236236
assert!(
237237
!error.kind().formatted_string(),
238238
"const-prop encountered formatting error: {}",
239-
self.ecx.format_error(error),
239+
format_interp_error(self.ecx.tcx.dcx(), error),
240240
);
241241
None
242242
}

‎src/tools/miri/src/diagnostics.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ pub fn report_error<'tcx, 'mir>(
290290
) =>
291291
{
292292
ecx.handle_ice(); // print interpreter backtrace
293-
bug!("This validation error should be impossible in Miri: {}", ecx.format_error(e));
293+
bug!("This validation error should be impossible in Miri: {}", format_interp_error(ecx.tcx.dcx(), e));
294294
}
295295
UndefinedBehavior(_) => "Undefined Behavior",
296296
ResourceExhaustion(_) => "resource exhaustion",
@@ -304,7 +304,7 @@ pub fn report_error<'tcx, 'mir>(
304304
) => "post-monomorphization error",
305305
_ => {
306306
ecx.handle_ice(); // print interpreter backtrace
307-
bug!("This error should be impossible in Miri: {}", ecx.format_error(e));
307+
bug!("This error should be impossible in Miri: {}", format_interp_error(ecx.tcx.dcx(), e));
308308
}
309309
};
310310
#[rustfmt::skip]
@@ -370,7 +370,7 @@ pub fn report_error<'tcx, 'mir>(
370370
_ => {}
371371
}
372372

373-
msg.insert(0, ecx.format_error(e));
373+
msg.insert(0, format_interp_error(ecx.tcx.dcx(), e));
374374

375375
report_msg(
376376
DiagLevel::Error,

‎tests/ui/consts/const_refs_to_static_fail.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1+
// normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"
2+
// normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP"
13
#![feature(const_refs_to_static, const_mut_refs, sync_unsafe_cell)]
24
use std::cell::SyncUnsafeCell;
35

46
static S: SyncUnsafeCell<i32> = SyncUnsafeCell::new(0);
57
static mut S_MUT: i32 = 0;
68

7-
const C1: &SyncUnsafeCell<i32> = &S;
9+
const C1: &SyncUnsafeCell<i32> = &S; //~ERROR undefined behavior
10+
//~| encountered reference to mutable memory
811
const C1_READ: () = unsafe {
9-
assert!(*C1.get() == 0); //~ERROR evaluation of constant value failed
10-
//~^ constant accesses mutable global memory
12+
assert!(*C1.get() == 0);
1113
};
1214
const C2: *const i32 = unsafe { std::ptr::addr_of!(S_MUT) };
1315
const C2_READ: () = unsafe {

‎tests/ui/consts/const_refs_to_static_fail.stderr

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,22 @@
1-
error[E0080]: evaluation of constant value failed
2-
--> $DIR/const_refs_to_static_fail.rs:9:13
1+
error[E0080]: it is undefined behavior to use this value
2+
--> $DIR/const_refs_to_static_fail.rs:9:1
3+
|
4+
LL | const C1: &SyncUnsafeCell<i32> = &S;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const`
6+
|
7+
= 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.
8+
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
9+
HEX_DUMP
10+
}
11+
12+
note: erroneous constant encountered
13+
--> $DIR/const_refs_to_static_fail.rs:12:14
314
|
415
LL | assert!(*C1.get() == 0);
5-
| ^^^^^^^^^ constant accesses mutable global memory
16+
| ^^
617

718
error[E0080]: evaluation of constant value failed
8-
--> $DIR/const_refs_to_static_fail.rs:14:13
19+
--> $DIR/const_refs_to_static_fail.rs:16:13
920
|
1021
LL | assert!(*C2 == 0);
1122
| ^^^ constant accesses mutable global memory
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"
2+
// normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP"
3+
#![feature(const_refs_to_static)]
4+
5+
static S: i8 = 10;
6+
7+
const C: &bool = unsafe { std::mem::transmute(&S) };
8+
//~^ERROR: undefined behavior
9+
//~| expected a boolean
10+
11+
fn main() {
12+
// This must be rejected here (or earlier), since it's not a valid `&bool`.
13+
match &true {
14+
C => {}, //~ERROR: could not evaluate constant pattern
15+
_ => {},
16+
}
17+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0080]: it is undefined behavior to use this value
2+
--> $DIR/const_refs_to_static_fail_invalid.rs:7:1
3+
|
4+
LL | const C: &bool = unsafe { std::mem::transmute(&S) };
5+
| ^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered 0x0a, but expected a boolean
6+
|
7+
= 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.
8+
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
9+
HEX_DUMP
10+
}
11+
12+
error: could not evaluate constant pattern
13+
--> $DIR/const_refs_to_static_fail_invalid.rs:14:9
14+
|
15+
LL | C => {},
16+
| ^
17+
18+
error: aborting due to 2 previous errors
19+
20+
For more information about this error, try `rustc --explain E0080`.

‎tests/ui/consts/const_refs_to_static_fail_pattern.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
// normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"
2+
// normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP"
13
#![feature(const_refs_to_static)]
24

35
static mut S_MUT: i32 = 0;
46

57
const C: &i32 = unsafe { &S_MUT };
6-
//~^ERROR: constant refers to mutable data
8+
//~^ERROR: undefined behavior
9+
//~| encountered reference to mutable memory
710

811
fn main() {
912
// This *must not build*, the constant we are matching against
Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
1-
error: constant refers to mutable data
2-
--> $DIR/const_refs_to_static_fail_pattern.rs:5:1
1+
error[E0080]: it is undefined behavior to use this value
2+
--> $DIR/const_refs_to_static_fail_pattern.rs:7:1
33
|
44
LL | const C: &i32 = unsafe { &S_MUT };
5-
| ^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const`
6+
|
7+
= 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.
8+
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
9+
HEX_DUMP
10+
}
611

712
error: could not evaluate constant pattern
8-
--> $DIR/const_refs_to_static_fail_pattern.rs:12:9
13+
--> $DIR/const_refs_to_static_fail_pattern.rs:15:9
914
|
1015
LL | C => {},
1116
| ^
1217

1318
error: aborting due to 2 previous errors
1419

20+
For more information about this error, try `rustc --explain E0080`.

‎tests/ui/consts/miri_unleashed/const_refers_to_static.32bit.stderr

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,17 @@ error[E0080]: evaluation of constant value failed
1616
LL | const READ_MUT: u32 = unsafe { MUTABLE };
1717
| ^^^^^^^ constant accesses mutable global memory
1818

19+
error[E0080]: it is undefined behavior to use this value
20+
--> $DIR/const_refers_to_static.rs:21:1
21+
|
22+
LL | const REF_INTERIOR_MUT: &usize = {
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const`
24+
|
25+
= 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.
26+
= note: the raw bytes of the constant (size: 4, align: 4) {
27+
╾ALLOC0<imm>╼ │ ╾──╼
28+
}
29+
1930
warning: skipping const checks
2031
|
2132
help: skipping check for `const_refs_to_static` feature
@@ -44,16 +55,16 @@ help: skipping check for `const_refs_to_static` feature
4455
LL | const READ_MUT: u32 = unsafe { MUTABLE };
4556
| ^^^^^^^
4657
help: skipping check for `const_refs_to_static` feature
47-
--> $DIR/const_refers_to_static.rs:23:18
58+
--> $DIR/const_refers_to_static.rs:24:18
4859
|
4960
LL | unsafe { &*(&FOO as *const _ as *const usize) }
5061
| ^^^
5162
help: skipping check for `const_refs_to_static` feature
52-
--> $DIR/const_refers_to_static.rs:27:25
63+
--> $DIR/const_refers_to_static.rs:28:25
5364
|
5465
LL | const REF_IMMUT: &u8 = &MY_STATIC;
5566
| ^^^^^^^^^
5667

57-
error: aborting due to 3 previous errors; 1 warning emitted
68+
error: aborting due to 4 previous errors; 1 warning emitted
5869

5970
For more information about this error, try `rustc --explain E0080`.

‎tests/ui/consts/miri_unleashed/const_refers_to_static.64bit.stderr

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,17 @@ error[E0080]: evaluation of constant value failed
1616
LL | const READ_MUT: u32 = unsafe { MUTABLE };
1717
| ^^^^^^^ constant accesses mutable global memory
1818

19+
error[E0080]: it is undefined behavior to use this value
20+
--> $DIR/const_refers_to_static.rs:21:1
21+
|
22+
LL | const REF_INTERIOR_MUT: &usize = {
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const`
24+
|
25+
= 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.
26+
= note: the raw bytes of the constant (size: 8, align: 8) {
27+
╾ALLOC0<imm>╼ │ ╾──────╼
28+
}
29+
1930
warning: skipping const checks
2031
|
2132
help: skipping check for `const_refs_to_static` feature
@@ -44,16 +55,16 @@ help: skipping check for `const_refs_to_static` feature
4455
LL | const READ_MUT: u32 = unsafe { MUTABLE };
4556
| ^^^^^^^
4657
help: skipping check for `const_refs_to_static` feature
47-
--> $DIR/const_refers_to_static.rs:23:18
58+
--> $DIR/const_refers_to_static.rs:24:18
4859
|
4960
LL | unsafe { &*(&FOO as *const _ as *const usize) }
5061
| ^^^
5162
help: skipping check for `const_refs_to_static` feature
52-
--> $DIR/const_refers_to_static.rs:27:25
63+
--> $DIR/const_refers_to_static.rs:28:25
5364
|
5465
LL | const REF_IMMUT: &u8 = &MY_STATIC;
5566
| ^^^^^^^^^
5667

57-
error: aborting due to 3 previous errors; 1 warning emitted
68+
error: aborting due to 4 previous errors; 1 warning emitted
5869

5970
For more information about this error, try `rustc --explain E0080`.

‎tests/ui/consts/miri_unleashed/const_refers_to_static.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ static mut MUTABLE: u32 = 0;
1818
const READ_MUT: u32 = unsafe { MUTABLE }; //~ERROR evaluation of constant value failed
1919

2020
// Not actually reading from anything mutable, so these are fine.
21-
const REF_INTERIOR_MUT: &usize = {
21+
const REF_INTERIOR_MUT: &usize = { //~ ERROR undefined behavior
22+
//~| encountered reference to mutable memory
2223
static FOO: AtomicUsize = AtomicUsize::new(0);
2324
unsafe { &*(&FOO as *const _ as *const usize) }
2425
};

‎tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,120 @@
1-
error: constant refers to mutable data
1+
error[E0080]: it is undefined behavior to use this value
22
--> $DIR/const_refers_to_static_cross_crate.rs:10:1
33
|
44
LL | const SLICE_MUT: &[u8; 1] = {
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const`
6+
|
7+
= 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.
8+
= note: the raw bytes of the constant (size: 4, align: 4) {
9+
╾ALLOC0<imm>╼ │ ╾──╼
10+
}
611

712
error: could not evaluate constant pattern
8-
--> $DIR/const_refers_to_static_cross_crate.rs:30:9
13+
--> $DIR/const_refers_to_static_cross_crate.rs:33:9
914
|
1015
LL | SLICE_MUT => true,
1116
| ^^^^^^^^^
1217

13-
error: constant refers to mutable data
14-
--> $DIR/const_refers_to_static_cross_crate.rs:14:1
18+
error[E0080]: it is undefined behavior to use this value
19+
--> $DIR/const_refers_to_static_cross_crate.rs:15:1
1520
|
1621
LL | const U8_MUT: &u8 = {
17-
| ^^^^^^^^^^^^^^^^^
22+
| ^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const`
23+
|
24+
= 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.
25+
= note: the raw bytes of the constant (size: 4, align: 4) {
26+
╾ALLOC0<imm>╼ │ ╾──╼
27+
}
1828

1929
error: could not evaluate constant pattern
20-
--> $DIR/const_refers_to_static_cross_crate.rs:38:9
30+
--> $DIR/const_refers_to_static_cross_crate.rs:41:9
2131
|
2232
LL | U8_MUT => true,
2333
| ^^^^^^
2434

25-
error: constant refers to mutable data
26-
--> $DIR/const_refers_to_static_cross_crate.rs:19:1
35+
error[E0080]: it is undefined behavior to use this value
36+
--> $DIR/const_refers_to_static_cross_crate.rs:21:1
2737
|
2838
LL | const U8_MUT2: &u8 = {
29-
| ^^^^^^^^^^^^^^^^^^
39+
| ^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const`
40+
|
41+
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
42+
= note: the raw bytes of the constant (size: 4, align: 4) {
43+
╾ALLOC0<imm>╼ │ ╾──╼
44+
}
3045

3146
error: could not evaluate constant pattern
32-
--> $DIR/const_refers_to_static_cross_crate.rs:48:9
47+
--> $DIR/const_refers_to_static_cross_crate.rs:51:9
3348
|
3449
LL | U8_MUT2 => true,
3550
| ^^^^^^^
3651

3752
error[E0080]: evaluation of constant value failed
38-
--> $DIR/const_refers_to_static_cross_crate.rs:23:20
53+
--> $DIR/const_refers_to_static_cross_crate.rs:26:20
3954
|
4055
LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
4156
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses mutable global memory
4257

4358
error: could not evaluate constant pattern
44-
--> $DIR/const_refers_to_static_cross_crate.rs:55:9
59+
--> $DIR/const_refers_to_static_cross_crate.rs:58:9
4560
|
4661
LL | U8_MUT3 => true,
4762
| ^^^^^^^
4863

4964
warning: skipping const checks
5065
|
5166
help: skipping check for `const_refs_to_static` feature
52-
--> $DIR/const_refers_to_static_cross_crate.rs:11:15
67+
--> $DIR/const_refers_to_static_cross_crate.rs:12:15
5368
|
5469
LL | unsafe { &static_cross_crate::ZERO }
5570
| ^^^^^^^^^^^^^^^^^^^^^^^^
5671
help: skipping check for `const_refs_to_static` feature
57-
--> $DIR/const_refers_to_static_cross_crate.rs:11:15
72+
--> $DIR/const_refers_to_static_cross_crate.rs:12:15
5873
|
5974
LL | unsafe { &static_cross_crate::ZERO }
6075
| ^^^^^^^^^^^^^^^^^^^^^^^^
6176
help: skipping check for `const_refs_to_static` feature
62-
--> $DIR/const_refers_to_static_cross_crate.rs:15:15
77+
--> $DIR/const_refers_to_static_cross_crate.rs:17:15
6378
|
6479
LL | unsafe { &static_cross_crate::ZERO[0] }
6580
| ^^^^^^^^^^^^^^^^^^^^^^^^
6681
help: skipping check for `const_refs_to_static` feature
67-
--> $DIR/const_refers_to_static_cross_crate.rs:15:15
82+
--> $DIR/const_refers_to_static_cross_crate.rs:17:15
6883
|
6984
LL | unsafe { &static_cross_crate::ZERO[0] }
7085
| ^^^^^^^^^^^^^^^^^^^^^^^^
7186
help: skipping check for `const_refs_to_static` feature
72-
--> $DIR/const_refers_to_static_cross_crate.rs:15:15
87+
--> $DIR/const_refers_to_static_cross_crate.rs:17:15
7388
|
7489
LL | unsafe { &static_cross_crate::ZERO[0] }
7590
| ^^^^^^^^^^^^^^^^^^^^^^^^
7691
help: skipping check for `const_refs_to_static` feature
77-
--> $DIR/const_refers_to_static_cross_crate.rs:20:17
92+
--> $DIR/const_refers_to_static_cross_crate.rs:23:17
7893
|
7994
LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] }
8095
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8196
help: skipping check for `const_refs_to_static` feature
82-
--> $DIR/const_refers_to_static_cross_crate.rs:23:20
97+
--> $DIR/const_refers_to_static_cross_crate.rs:26:20
8398
|
8499
LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
85100
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
86101
help: skipping check for `const_refs_to_static` feature
87-
--> $DIR/const_refers_to_static_cross_crate.rs:23:20
102+
--> $DIR/const_refers_to_static_cross_crate.rs:26:20
88103
|
89104
LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
90105
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
91106
help: skipping check for `const_refs_to_static` feature
92-
--> $DIR/const_refers_to_static_cross_crate.rs:23:20
107+
--> $DIR/const_refers_to_static_cross_crate.rs:26:20
93108
|
94109
LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
95110
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
96111
help: skipping check for `const_refs_to_static` feature
97-
--> $DIR/const_refers_to_static_cross_crate.rs:23:20
112+
--> $DIR/const_refers_to_static_cross_crate.rs:26:20
98113
|
99114
LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
100115
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
101116
help: skipping check for `const_refs_to_static` feature
102-
--> $DIR/const_refers_to_static_cross_crate.rs:23:20
117+
--> $DIR/const_refers_to_static_cross_crate.rs:26:20
103118
|
104119
LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
105120
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

‎tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,120 @@
1-
error: constant refers to mutable data
1+
error[E0080]: it is undefined behavior to use this value
22
--> $DIR/const_refers_to_static_cross_crate.rs:10:1
33
|
44
LL | const SLICE_MUT: &[u8; 1] = {
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const`
6+
|
7+
= 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.
8+
= note: the raw bytes of the constant (size: 8, align: 8) {
9+
╾ALLOC0<imm>╼ │ ╾──────╼
10+
}
611

712
error: could not evaluate constant pattern
8-
--> $DIR/const_refers_to_static_cross_crate.rs:30:9
13+
--> $DIR/const_refers_to_static_cross_crate.rs:33:9
914
|
1015
LL | SLICE_MUT => true,
1116
| ^^^^^^^^^
1217

13-
error: constant refers to mutable data
14-
--> $DIR/const_refers_to_static_cross_crate.rs:14:1
18+
error[E0080]: it is undefined behavior to use this value
19+
--> $DIR/const_refers_to_static_cross_crate.rs:15:1
1520
|
1621
LL | const U8_MUT: &u8 = {
17-
| ^^^^^^^^^^^^^^^^^
22+
| ^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const`
23+
|
24+
= 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.
25+
= note: the raw bytes of the constant (size: 8, align: 8) {
26+
╾ALLOC0<imm>╼ │ ╾──────╼
27+
}
1828

1929
error: could not evaluate constant pattern
20-
--> $DIR/const_refers_to_static_cross_crate.rs:38:9
30+
--> $DIR/const_refers_to_static_cross_crate.rs:41:9
2131
|
2232
LL | U8_MUT => true,
2333
| ^^^^^^
2434

25-
error: constant refers to mutable data
26-
--> $DIR/const_refers_to_static_cross_crate.rs:19:1
35+
error[E0080]: it is undefined behavior to use this value
36+
--> $DIR/const_refers_to_static_cross_crate.rs:21:1
2737
|
2838
LL | const U8_MUT2: &u8 = {
29-
| ^^^^^^^^^^^^^^^^^^
39+
| ^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const`
40+
|
41+
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
42+
= note: the raw bytes of the constant (size: 8, align: 8) {
43+
╾ALLOC0<imm>╼ │ ╾──────╼
44+
}
3045

3146
error: could not evaluate constant pattern
32-
--> $DIR/const_refers_to_static_cross_crate.rs:48:9
47+
--> $DIR/const_refers_to_static_cross_crate.rs:51:9
3348
|
3449
LL | U8_MUT2 => true,
3550
| ^^^^^^^
3651

3752
error[E0080]: evaluation of constant value failed
38-
--> $DIR/const_refers_to_static_cross_crate.rs:23:20
53+
--> $DIR/const_refers_to_static_cross_crate.rs:26:20
3954
|
4055
LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
4156
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses mutable global memory
4257

4358
error: could not evaluate constant pattern
44-
--> $DIR/const_refers_to_static_cross_crate.rs:55:9
59+
--> $DIR/const_refers_to_static_cross_crate.rs:58:9
4560
|
4661
LL | U8_MUT3 => true,
4762
| ^^^^^^^
4863

4964
warning: skipping const checks
5065
|
5166
help: skipping check for `const_refs_to_static` feature
52-
--> $DIR/const_refers_to_static_cross_crate.rs:11:15
67+
--> $DIR/const_refers_to_static_cross_crate.rs:12:15
5368
|
5469
LL | unsafe { &static_cross_crate::ZERO }
5570
| ^^^^^^^^^^^^^^^^^^^^^^^^
5671
help: skipping check for `const_refs_to_static` feature
57-
--> $DIR/const_refers_to_static_cross_crate.rs:11:15
72+
--> $DIR/const_refers_to_static_cross_crate.rs:12:15
5873
|
5974
LL | unsafe { &static_cross_crate::ZERO }
6075
| ^^^^^^^^^^^^^^^^^^^^^^^^
6176
help: skipping check for `const_refs_to_static` feature
62-
--> $DIR/const_refers_to_static_cross_crate.rs:15:15
77+
--> $DIR/const_refers_to_static_cross_crate.rs:17:15
6378
|
6479
LL | unsafe { &static_cross_crate::ZERO[0] }
6580
| ^^^^^^^^^^^^^^^^^^^^^^^^
6681
help: skipping check for `const_refs_to_static` feature
67-
--> $DIR/const_refers_to_static_cross_crate.rs:15:15
82+
--> $DIR/const_refers_to_static_cross_crate.rs:17:15
6883
|
6984
LL | unsafe { &static_cross_crate::ZERO[0] }
7085
| ^^^^^^^^^^^^^^^^^^^^^^^^
7186
help: skipping check for `const_refs_to_static` feature
72-
--> $DIR/const_refers_to_static_cross_crate.rs:15:15
87+
--> $DIR/const_refers_to_static_cross_crate.rs:17:15
7388
|
7489
LL | unsafe { &static_cross_crate::ZERO[0] }
7590
| ^^^^^^^^^^^^^^^^^^^^^^^^
7691
help: skipping check for `const_refs_to_static` feature
77-
--> $DIR/const_refers_to_static_cross_crate.rs:20:17
92+
--> $DIR/const_refers_to_static_cross_crate.rs:23:17
7893
|
7994
LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] }
8095
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8196
help: skipping check for `const_refs_to_static` feature
82-
--> $DIR/const_refers_to_static_cross_crate.rs:23:20
97+
--> $DIR/const_refers_to_static_cross_crate.rs:26:20
8398
|
8499
LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
85100
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
86101
help: skipping check for `const_refs_to_static` feature
87-
--> $DIR/const_refers_to_static_cross_crate.rs:23:20
102+
--> $DIR/const_refers_to_static_cross_crate.rs:26:20
88103
|
89104
LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
90105
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
91106
help: skipping check for `const_refs_to_static` feature
92-
--> $DIR/const_refers_to_static_cross_crate.rs:23:20
107+
--> $DIR/const_refers_to_static_cross_crate.rs:26:20
93108
|
94109
LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
95110
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
96111
help: skipping check for `const_refs_to_static` feature
97-
--> $DIR/const_refers_to_static_cross_crate.rs:23:20
112+
--> $DIR/const_refers_to_static_cross_crate.rs:26:20
98113
|
99114
LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
100115
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
101116
help: skipping check for `const_refs_to_static` feature
102-
--> $DIR/const_refers_to_static_cross_crate.rs:23:20
117+
--> $DIR/const_refers_to_static_cross_crate.rs:26:20
103118
|
104119
LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
105120
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

‎tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,19 @@ extern crate static_cross_crate;
77

88
// Sneaky: reference to a mutable static.
99
// Allowing this would be a disaster for pattern matching, we could violate exhaustiveness checking!
10-
const SLICE_MUT: &[u8; 1] = { //~ ERROR constant refers to mutable data
10+
const SLICE_MUT: &[u8; 1] = { //~ ERROR undefined behavior
11+
//~| encountered reference to mutable memory
1112
unsafe { &static_cross_crate::ZERO }
1213
};
1314

14-
const U8_MUT: &u8 = { //~ ERROR constant refers to mutable data
15+
const U8_MUT: &u8 = { //~ ERROR undefined behavior
16+
//~| encountered reference to mutable memory
1517
unsafe { &static_cross_crate::ZERO[0] }
1618
};
1719

1820
// Also test indirection that reads from other static.
19-
const U8_MUT2: &u8 = { //~ ERROR constant refers to mutable data
21+
const U8_MUT2: &u8 = { //~ ERROR undefined behavior
22+
//~| encountered reference to mutable memory
2023
unsafe { &(*static_cross_crate::ZERO_REF)[0] }
2124
};
2225
const U8_MUT3: &u8 = {

‎tests/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -38,50 +38,61 @@ LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const
3838
╾ALLOC1<imm>╼ │ ╾──╼
3939
}
4040

41-
error[E0080]: evaluation of constant value failed
42-
--> $DIR/mutable_references_err.rs:48:33
41+
error[E0080]: it is undefined behavior to use this value
42+
--> $DIR/mutable_references_err.rs:47:1
43+
|
44+
LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE };
45+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const`
46+
|
47+
= 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.
48+
= note: the raw bytes of the constant (size: 4, align: 4) {
49+
╾ALLOC2<imm>╼ │ ╾──╼
50+
}
51+
52+
note: erroneous constant encountered
53+
--> $DIR/mutable_references_err.rs:49:34
4354
|
4455
LL | const READS_FROM_MUTABLE: i32 = *POINTS_TO_MUTABLE1;
45-
| ^^^^^^^^^^^^^^^^^^^ constant accesses mutable global memory
56+
| ^^^^^^^^^^^^^^^^^^
4657

4758
error[E0080]: evaluation of constant value failed
48-
--> $DIR/mutable_references_err.rs:52:43
59+
--> $DIR/mutable_references_err.rs:51:43
4960
|
5061
LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
5162
| ^^^^^^^^^^^^^ constant accesses mutable global memory
5263

5364
error: encountered mutable pointer in final value of constant
54-
--> $DIR/mutable_references_err.rs:56:1
65+
--> $DIR/mutable_references_err.rs:55:1
5566
|
5667
LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _;
5768
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5869

5970
error: encountered mutable pointer in final value of constant
60-
--> $DIR/mutable_references_err.rs:58:1
71+
--> $DIR/mutable_references_err.rs:57:1
6172
|
6273
LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _;
6374
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6475

6576
error: encountered mutable pointer in final value of constant
66-
--> $DIR/mutable_references_err.rs:60:1
77+
--> $DIR/mutable_references_err.rs:59:1
6778
|
6879
LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
6980
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7081

7182
error: encountered mutable pointer in final value of constant
72-
--> $DIR/mutable_references_err.rs:70:1
83+
--> $DIR/mutable_references_err.rs:69:1
7384
|
7485
LL | const RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
7586
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7687

7788
error: encountered mutable pointer in final value of constant
78-
--> $DIR/mutable_references_err.rs:72:1
89+
--> $DIR/mutable_references_err.rs:71:1
7990
|
8091
LL | const RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
8192
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8293

8394
error: encountered mutable pointer in final value of constant
84-
--> $DIR/mutable_references_err.rs:74:1
95+
--> $DIR/mutable_references_err.rs:73:1
8596
|
8697
LL | const RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
8798
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -144,47 +155,47 @@ help: skipping check for `const_refs_to_static` feature
144155
LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE };
145156
| ^^^^^^^
146157
help: skipping check that does not even have a feature gate
147-
--> $DIR/mutable_references_err.rs:51:36
158+
--> $DIR/mutable_references_err.rs:50:36
148159
|
149160
LL | static mut MUTABLE_REF: &mut i32 = &mut 42;
150161
| ^^^^^^^
151162
help: skipping check for `const_refs_to_static` feature
152-
--> $DIR/mutable_references_err.rs:52:45
163+
--> $DIR/mutable_references_err.rs:51:45
153164
|
154165
LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
155166
| ^^^^^^^^^^^
156167
help: skipping check for `const_refs_to_static` feature
157-
--> $DIR/mutable_references_err.rs:52:45
168+
--> $DIR/mutable_references_err.rs:51:45
158169
|
159170
LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
160171
| ^^^^^^^^^^^
161172
help: skipping check that does not even have a feature gate
162-
--> $DIR/mutable_references_err.rs:56:45
173+
--> $DIR/mutable_references_err.rs:55:45
163174
|
164175
LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _;
165176
| ^^^^^^^
166177
help: skipping check that does not even have a feature gate
167-
--> $DIR/mutable_references_err.rs:58:46
178+
--> $DIR/mutable_references_err.rs:57:46
168179
|
169180
LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _;
170181
| ^^^^^^^
171182
help: skipping check that does not even have a feature gate
172-
--> $DIR/mutable_references_err.rs:60:47
183+
--> $DIR/mutable_references_err.rs:59:47
173184
|
174185
LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
175186
| ^^^^^^^^^^^^^^^^^^^^
176187
help: skipping check that does not even have a feature gate
177-
--> $DIR/mutable_references_err.rs:70:51
188+
--> $DIR/mutable_references_err.rs:69:51
178189
|
179190
LL | const RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
180191
| ^^^^^^^^^^^^^^^^^^^
181192
help: skipping check that does not even have a feature gate
182-
--> $DIR/mutable_references_err.rs:72:50
193+
--> $DIR/mutable_references_err.rs:71:50
183194
|
184195
LL | const RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
185196
| ^^^^^^^
186197
help: skipping check that does not even have a feature gate
187-
--> $DIR/mutable_references_err.rs:74:51
198+
--> $DIR/mutable_references_err.rs:73:51
188199
|
189200
LL | const RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
190201
| ^^^^^^

‎tests/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -38,50 +38,61 @@ LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const
3838
╾ALLOC1<imm>╼ │ ╾──────╼
3939
}
4040

41-
error[E0080]: evaluation of constant value failed
42-
--> $DIR/mutable_references_err.rs:48:33
41+
error[E0080]: it is undefined behavior to use this value
42+
--> $DIR/mutable_references_err.rs:47:1
43+
|
44+
LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE };
45+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const`
46+
|
47+
= 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.
48+
= note: the raw bytes of the constant (size: 8, align: 8) {
49+
╾ALLOC2<imm>╼ │ ╾──────╼
50+
}
51+
52+
note: erroneous constant encountered
53+
--> $DIR/mutable_references_err.rs:49:34
4354
|
4455
LL | const READS_FROM_MUTABLE: i32 = *POINTS_TO_MUTABLE1;
45-
| ^^^^^^^^^^^^^^^^^^^ constant accesses mutable global memory
56+
| ^^^^^^^^^^^^^^^^^^
4657

4758
error[E0080]: evaluation of constant value failed
48-
--> $DIR/mutable_references_err.rs:52:43
59+
--> $DIR/mutable_references_err.rs:51:43
4960
|
5061
LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
5162
| ^^^^^^^^^^^^^ constant accesses mutable global memory
5263

5364
error: encountered mutable pointer in final value of constant
54-
--> $DIR/mutable_references_err.rs:56:1
65+
--> $DIR/mutable_references_err.rs:55:1
5566
|
5667
LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _;
5768
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5869

5970
error: encountered mutable pointer in final value of constant
60-
--> $DIR/mutable_references_err.rs:58:1
71+
--> $DIR/mutable_references_err.rs:57:1
6172
|
6273
LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _;
6374
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6475

6576
error: encountered mutable pointer in final value of constant
66-
--> $DIR/mutable_references_err.rs:60:1
77+
--> $DIR/mutable_references_err.rs:59:1
6778
|
6879
LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
6980
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7081

7182
error: encountered mutable pointer in final value of constant
72-
--> $DIR/mutable_references_err.rs:70:1
83+
--> $DIR/mutable_references_err.rs:69:1
7384
|
7485
LL | const RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
7586
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7687

7788
error: encountered mutable pointer in final value of constant
78-
--> $DIR/mutable_references_err.rs:72:1
89+
--> $DIR/mutable_references_err.rs:71:1
7990
|
8091
LL | const RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
8192
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8293

8394
error: encountered mutable pointer in final value of constant
84-
--> $DIR/mutable_references_err.rs:74:1
95+
--> $DIR/mutable_references_err.rs:73:1
8596
|
8697
LL | const RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
8798
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -144,47 +155,47 @@ help: skipping check for `const_refs_to_static` feature
144155
LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE };
145156
| ^^^^^^^
146157
help: skipping check that does not even have a feature gate
147-
--> $DIR/mutable_references_err.rs:51:36
158+
--> $DIR/mutable_references_err.rs:50:36
148159
|
149160
LL | static mut MUTABLE_REF: &mut i32 = &mut 42;
150161
| ^^^^^^^
151162
help: skipping check for `const_refs_to_static` feature
152-
--> $DIR/mutable_references_err.rs:52:45
163+
--> $DIR/mutable_references_err.rs:51:45
153164
|
154165
LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
155166
| ^^^^^^^^^^^
156167
help: skipping check for `const_refs_to_static` feature
157-
--> $DIR/mutable_references_err.rs:52:45
168+
--> $DIR/mutable_references_err.rs:51:45
158169
|
159170
LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
160171
| ^^^^^^^^^^^
161172
help: skipping check that does not even have a feature gate
162-
--> $DIR/mutable_references_err.rs:56:45
173+
--> $DIR/mutable_references_err.rs:55:45
163174
|
164175
LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _;
165176
| ^^^^^^^
166177
help: skipping check that does not even have a feature gate
167-
--> $DIR/mutable_references_err.rs:58:46
178+
--> $DIR/mutable_references_err.rs:57:46
168179
|
169180
LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _;
170181
| ^^^^^^^
171182
help: skipping check that does not even have a feature gate
172-
--> $DIR/mutable_references_err.rs:60:47
183+
--> $DIR/mutable_references_err.rs:59:47
173184
|
174185
LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
175186
| ^^^^^^^^^^^^^^^^^^^^
176187
help: skipping check that does not even have a feature gate
177-
--> $DIR/mutable_references_err.rs:70:51
188+
--> $DIR/mutable_references_err.rs:69:51
178189
|
179190
LL | const RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
180191
| ^^^^^^^^^^^^^^^^^^^
181192
help: skipping check that does not even have a feature gate
182-
--> $DIR/mutable_references_err.rs:72:50
193+
--> $DIR/mutable_references_err.rs:71:50
183194
|
184195
LL | const RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
185196
| ^^^^^^^
186197
help: skipping check that does not even have a feature gate
187-
--> $DIR/mutable_references_err.rs:74:51
198+
--> $DIR/mutable_references_err.rs:73:51
188199
|
189200
LL | const RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
190201
| ^^^^^^

‎tests/ui/consts/miri_unleashed/mutable_references_err.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,9 @@ static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as
4444
// Check for consts pointing to mutable memory.
4545
// These are fine as long as they are not being read.
4646
static mut MUTABLE: i32 = 42;
47-
const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE };
47+
const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE }; //~ERROR: undefined behavior
48+
//~| encountered reference to mutable memory
4849
const READS_FROM_MUTABLE: i32 = *POINTS_TO_MUTABLE1;
49-
//~^ ERROR: evaluation of constant value failed
50-
//~| accesses mutable global memory
5150
static mut MUTABLE_REF: &mut i32 = &mut 42;
5251
const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
5352
//~^ ERROR: evaluation of constant value failed

0 commit comments

Comments
 (0)
Please sign in to comment.