Skip to content

Commit 0cdbeaa

Browse files
committed
Stabilize const_raw_ptr_deref for *const T
This stabilizes dereferencing immutable raw pointers in const contexts. It does not stabilize `*mut T` dereferencing. This is placed behind the `const_raw_mut_ptr_deref` feature gate.
1 parent 5ec7d1d commit 0cdbeaa

File tree

62 files changed

+114
-193
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+114
-193
lines changed

compiler/rustc_const_eval/src/transform/check_consts/check.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -725,7 +725,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
725725
match elem {
726726
ProjectionElem::Deref => {
727727
let base_ty = Place::ty_from(place_local, proj_base, self.body, self.tcx).ty;
728-
if let ty::RawPtr(_) = base_ty.kind() {
728+
if base_ty.is_unsafe_ptr() {
729729
if proj_base.is_empty() {
730730
let decl = &self.body.local_decls[place_local];
731731
if let Some(box LocalInfo::StaticRef { def_id, .. }) = decl.local_info {
@@ -734,7 +734,13 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
734734
return;
735735
}
736736
}
737-
self.check_op(ops::RawPtrDeref);
737+
738+
// `*const T` is stable, `*mut T` is not
739+
if !base_ty.is_mutable_ptr() {
740+
return;
741+
}
742+
743+
self.check_op(ops::RawMutPtrDeref);
738744
}
739745

740746
if context.is_mutating_use() {

compiler/rustc_const_eval/src/transform/check_consts/ops.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -400,18 +400,18 @@ impl NonConstOp for RawPtrComparison {
400400
}
401401

402402
#[derive(Debug)]
403-
pub struct RawPtrDeref;
404-
impl NonConstOp for RawPtrDeref {
403+
pub struct RawMutPtrDeref;
404+
impl NonConstOp for RawMutPtrDeref {
405405
fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status {
406-
Status::Unstable(sym::const_raw_ptr_deref)
406+
Status::Unstable(sym::const_mut_refs)
407407
}
408408

409409
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
410410
feature_err(
411411
&ccx.tcx.sess.parse_sess,
412-
sym::const_raw_ptr_deref,
412+
sym::const_mut_refs,
413413
span,
414-
&format!("dereferencing raw pointers in {}s is unstable", ccx.const_kind(),),
414+
&format!("dereferencing raw mutable pointers in {}s is unstable", ccx.const_kind(),),
415415
)
416416
}
417417
}

compiler/rustc_feature/src/accepted.rs

+2
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,8 @@ declare_features! (
299299
(accepted, const_panic, "1.57.0", Some(51999), None),
300300
/// Lessens the requirements for structs to implement `Unsize`.
301301
(accepted, relaxed_struct_unsize, "1.58.0", Some(81793), None),
302+
/// Allows dereferencing raw pointers during const eval.
303+
(accepted, const_raw_ptr_deref, "1.58.0", Some(51911), None),
302304

303305
// -------------------------------------------------------------------------
304306
// feature-group-end: accepted features

compiler/rustc_feature/src/active.rs

-3
Original file line numberDiff line numberDiff line change
@@ -408,9 +408,6 @@ declare_features! (
408408
/// Allows inferring `'static` outlives requirements (RFC 2093).
409409
(active, infer_static_outlives_requirements, "1.26.0", Some(54185), None),
410410

411-
/// Allows dereferencing raw pointers during const eval.
412-
(active, const_raw_ptr_deref, "1.27.0", Some(51911), None),
413-
414411
/// Allows inconsistent bounds in where clauses.
415412
(active, trivial_bounds, "1.28.0", Some(48214), None),
416413

library/core/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@
156156
#![feature(const_impl_trait)]
157157
#![feature(const_mut_refs)]
158158
#![feature(const_precise_live_drops)]
159-
#![feature(const_raw_ptr_deref)]
159+
#![cfg_attr(bootstrap, feature(const_raw_ptr_deref))]
160160
#![feature(const_refs_to_cell)]
161161
#![feature(decl_macro)]
162162
#![feature(doc_cfg)]

library/core/tests/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
#![feature(const_mut_refs)]
5757
#![feature(const_pin)]
5858
#![feature(const_slice_from_raw_parts)]
59-
#![feature(const_raw_ptr_deref)]
59+
#![cfg_attr(bootstrap, feature(const_raw_ptr_deref))]
6060
#![feature(never_type)]
6161
#![feature(unwrap_infallible)]
6262
#![feature(result_into_ok_or_err)]

library/std/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,8 @@
264264
#![feature(const_ipv4)]
265265
#![feature(const_ipv6)]
266266
#![feature(const_option)]
267-
#![feature(const_raw_ptr_deref)]
267+
#![cfg_attr(bootstrap, feature(const_raw_ptr_deref))]
268+
#![cfg_attr(not(bootstrap), feature(const_mut_refs))]
268269
#![feature(const_socketaddr)]
269270
#![feature(const_trait_impl)]
270271
#![feature(container_error_extra)]

src/test/ui/consts/const-deref-ptr.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
// Check that you can't dereference raw pointers in constants.
1+
// Check that you can't dereference invalid raw pointers in constants.
22

33
fn main() {
44
static C: u64 = unsafe {*(0xdeadbeef as *const u64)};
5-
//~^ ERROR dereferencing raw pointers in statics is unstable
5+
//~^ ERROR could not evaluate static initializer
66
println!("{}", C);
77
}
+3-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
error[E0658]: dereferencing raw pointers in statics is unstable
1+
error[E0080]: could not evaluate static initializer
22
--> $DIR/const-deref-ptr.rs:4:29
33
|
44
LL | static C: u64 = unsafe {*(0xdeadbeef as *const u64)};
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
6-
|
7-
= note: see issue #51911 <https://github.com/rust-lang/rust/issues/51911> for more information
8-
= help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 0xdeadbeef is not a valid pointer
96

107
error: aborting due to previous error
118

12-
For more information about this error, try `rustc --explain E0658`.
9+
For more information about this error, try `rustc --explain E0080`.

src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs

-19
This file was deleted.

src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr

-9
This file was deleted.

src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// New test for #53818: modifying static memory at compile-time is not allowed.
22
// The test should never compile successfully
33

4-
#![feature(const_raw_ptr_deref)]
5-
64
use std::cell::UnsafeCell;
75

86
static mut FOO: u32 = 42;

src/test/ui/consts/const-eval/assign-to-static-within-other-static.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0080]: could not evaluate static initializer
2-
--> $DIR/assign-to-static-within-other-static.rs:10:5
2+
--> $DIR/assign-to-static-within-other-static.rs:8:5
33
|
44
LL | FOO = 5;
55
| ^^^^^^^ modifying a static's initial value from another static's initializer

src/test/ui/consts/const-eval/const_raw_ptr_ops2.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![feature(const_raw_ptr_deref)]
2-
31
fn main() {}
42

53
// fine

src/test/ui/consts/const-eval/const_raw_ptr_ops2.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0080]: evaluation of constant value failed
2-
--> $DIR/const_raw_ptr_ops2.rs:9:26
2+
--> $DIR/const_raw_ptr_ops2.rs:7:26
33
|
44
LL | const Z2: i32 = unsafe { *(42 as *const i32) };
55
| ^^^^^^^^^^^^^^^^^^^ 0x2a is not a valid pointer
66

77
error[E0080]: evaluation of constant value failed
8-
--> $DIR/const_raw_ptr_ops2.rs:11:26
8+
--> $DIR/const_raw_ptr_ops2.rs:9:26
99
|
1010
LL | const Z3: i32 = unsafe { *(44 as *const i32) };
1111
| ^^^^^^^^^^^^^^^^^^^ 0x2c is not a valid pointer

src/test/ui/consts/const-eval/dangling.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![feature(const_raw_ptr_deref)]
2-
31
use std::mem;
42

53
// Make sure we error with the right kind of error on a too large slice.

src/test/ui/consts/const-eval/dangling.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0080]: evaluation of constant value failed
2-
--> $DIR/dangling.rs:8:16
2+
--> $DIR/dangling.rs:6:16
33
|
44
LL | let _val = &*slice;
55
| ^^^^^^^ invalid metadata in wide pointer: slice is bigger than largest supported object

src/test/ui/consts/const-eval/heap/alloc_intrinsic_errors.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#![feature(core_intrinsics)]
22
#![feature(const_heap)]
3-
#![feature(const_raw_ptr_deref)]
43
#![feature(const_mut_refs)]
54
use std::intrinsics;
65

src/test/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
error[E0080]: evaluation of constant value failed
2-
--> $DIR/alloc_intrinsic_errors.rs:10:17
2+
--> $DIR/alloc_intrinsic_errors.rs:9:17
33
|
44
LL | const FOO: i32 = foo();
5-
| ----- inside `FOO` at $DIR/alloc_intrinsic_errors.rs:7:18
5+
| ----- inside `FOO` at $DIR/alloc_intrinsic_errors.rs:6:18
66
...
77
LL | let _ = intrinsics::const_allocate(4, 3) as * mut i32;
88
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
99
| |
1010
| align has to be a power of 2, `3` is not a power of 2
11-
| inside `foo` at $DIR/alloc_intrinsic_errors.rs:10:17
11+
| inside `foo` at $DIR/alloc_intrinsic_errors.rs:9:17
1212

1313
error: aborting due to previous error
1414

src/test/ui/consts/const-eval/heap/alloc_intrinsic_nontransient.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// run-pass
22
#![feature(core_intrinsics)]
33
#![feature(const_heap)]
4-
#![feature(const_raw_ptr_deref)]
54
#![feature(const_mut_refs)]
65
use std::intrinsics;
76

src/test/ui/consts/const-eval/heap/alloc_intrinsic_nontransient_fail.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#![feature(core_intrinsics)]
22
#![feature(const_heap)]
3-
#![feature(const_raw_ptr_deref)]
43
#![feature(const_mut_refs)]
54
use std::intrinsics;
65

src/test/ui/consts/const-eval/heap/alloc_intrinsic_nontransient_fail.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: untyped pointers are not allowed in constant
2-
--> $DIR/alloc_intrinsic_nontransient_fail.rs:7:1
2+
--> $DIR/alloc_intrinsic_nontransient_fail.rs:6:1
33
|
44
LL | const FOO: *const i32 = foo();
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

src/test/ui/consts/const-eval/heap/alloc_intrinsic_transient.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// run-pass
22
#![feature(core_intrinsics)]
33
#![feature(const_heap)]
4-
#![feature(const_raw_ptr_deref)]
54
#![feature(const_mut_refs)]
65
use std::intrinsics;
76

src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0080]: it is undefined behavior to use this value
2-
--> $DIR/alloc_intrinsic_uninit.rs:9:1
2+
--> $DIR/alloc_intrinsic_uninit.rs:8:1
33
|
44
LL | const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) };
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<deref>: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes

src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0080]: it is undefined behavior to use this value
2-
--> $DIR/alloc_intrinsic_uninit.rs:9:1
2+
--> $DIR/alloc_intrinsic_uninit.rs:8:1
33
|
44
LL | const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) };
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<deref>: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes

src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.rs

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// compile-test
33
#![feature(core_intrinsics)]
44
#![feature(const_heap)]
5-
#![feature(const_raw_ptr_deref)]
65
#![feature(const_mut_refs)]
76
use std::intrinsics;
87

src/test/ui/consts/const-eval/heap/alloc_intrinsic_untyped.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#![feature(core_intrinsics)]
22
#![feature(const_heap)]
3-
#![feature(const_raw_ptr_deref)]
43
#![feature(const_mut_refs)]
54
use std::intrinsics;
65

src/test/ui/consts/const-eval/heap/alloc_intrinsic_untyped.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: untyped pointers are not allowed in constant
2-
--> $DIR/alloc_intrinsic_untyped.rs:7:1
2+
--> $DIR/alloc_intrinsic_untyped.rs:6:1
33
|
44
LL | const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32};
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

src/test/ui/consts/const-eval/mod-static-with-const-fn.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// New test for #53818: modifying static memory at compile-time is not allowed.
22
// The test should never compile successfully
33

4-
#![feature(const_raw_ptr_deref)]
4+
#![feature(const_mut_refs)]
55

66
use std::cell::UnsafeCell;
77

@@ -14,7 +14,7 @@ static FOO: Foo = Foo(UnsafeCell::new(42));
1414

1515
static BAR: () = unsafe {
1616
*FOO.0.get() = 5;
17-
//~^ mutation through a reference
17+
//~^ ERROR could not evaluate static initializer
1818
};
1919

2020
fn main() {
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
error[E0658]: mutation through a reference is not allowed in statics
1+
error[E0080]: could not evaluate static initializer
22
--> $DIR/mod-static-with-const-fn.rs:16:5
33
|
44
LL | *FOO.0.get() = 5;
5-
| ^^^^^^^^^^^^^^^^
6-
|
7-
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
8-
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
5+
| ^^^^^^^^^^^^^^^^ modifying a static's initial value from another static's initializer
96

107
error: aborting due to previous error
118

12-
For more information about this error, try `rustc --explain E0658`.
9+
For more information about this error, try `rustc --explain E0080`.

src/test/ui/consts/const-eval/partial_ptr_overwrite.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Test for the behavior described in <https://github.com/rust-lang/rust/issues/87184>.
2-
#![feature(const_mut_refs, const_raw_ptr_deref)]
2+
#![feature(const_mut_refs)]
33

44
const PARTIAL_OVERWRITE: () = {
55
let mut p = &42;

src/test/ui/consts/const-eval/promoted_raw_ptr_ops.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![feature(const_raw_ptr_deref)]
2-
31
fn main() {
42
let x: &'static bool = &(42 as *const i32 == 43 as *const i32);
53
//~^ ERROR temporary value dropped while borrowed

src/test/ui/consts/const-eval/promoted_raw_ptr_ops.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0716]: temporary value dropped while borrowed
2-
--> $DIR/promoted_raw_ptr_ops.rs:4:29
2+
--> $DIR/promoted_raw_ptr_ops.rs:2:29
33
|
44
LL | let x: &'static bool = &(42 as *const i32 == 43 as *const i32);
55
| ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
@@ -10,7 +10,7 @@ LL | }
1010
| - temporary value is freed at the end of this statement
1111

1212
error[E0716]: temporary value dropped while borrowed
13-
--> $DIR/promoted_raw_ptr_ops.rs:6:30
13+
--> $DIR/promoted_raw_ptr_ops.rs:4:30
1414
|
1515
LL | let y: &'static usize = &(&1 as *const i32 as usize + 1);
1616
| -------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
@@ -21,7 +21,7 @@ LL | }
2121
| - temporary value is freed at the end of this statement
2222

2323
error[E0716]: temporary value dropped while borrowed
24-
--> $DIR/promoted_raw_ptr_ops.rs:8:28
24+
--> $DIR/promoted_raw_ptr_ops.rs:6:28
2525
|
2626
LL | let z: &'static i32 = &(unsafe { *(42 as *const i32) });
2727
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
@@ -32,7 +32,7 @@ LL | }
3232
| - temporary value is freed at the end of this statement
3333

3434
error[E0716]: temporary value dropped while borrowed
35-
--> $DIR/promoted_raw_ptr_ops.rs:10:29
35+
--> $DIR/promoted_raw_ptr_ops.rs:8:29
3636
|
3737
LL | let a: &'static bool = &(main as fn() == main as fn());
3838
| ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use

src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#![feature(const_mut_refs)]
22
#![feature(raw_ref_op)]
3-
#![feature(const_raw_ptr_deref)]
43

54
const NULL: *mut i32 = std::ptr::null_mut();
65
const A: *const i32 = &4;

0 commit comments

Comments
 (0)