Skip to content

Commit

Permalink
Stabilize const_raw_ptr_deref for *const T
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jhpratt committed Nov 6, 2021
1 parent 5ec7d1d commit 0cdbeaa
Show file tree
Hide file tree
Showing 62 changed files with 114 additions and 193 deletions.
10 changes: 8 additions & 2 deletions compiler/rustc_const_eval/src/transform/check_consts/check.rs
Expand Up @@ -725,7 +725,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
match elem {
ProjectionElem::Deref => {
let base_ty = Place::ty_from(place_local, proj_base, self.body, self.tcx).ty;
if let ty::RawPtr(_) = base_ty.kind() {
if base_ty.is_unsafe_ptr() {
if proj_base.is_empty() {
let decl = &self.body.local_decls[place_local];
if let Some(box LocalInfo::StaticRef { def_id, .. }) = decl.local_info {
Expand All @@ -734,7 +734,13 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
return;
}
}
self.check_op(ops::RawPtrDeref);

// `*const T` is stable, `*mut T` is not
if !base_ty.is_mutable_ptr() {
return;
}

self.check_op(ops::RawMutPtrDeref);
}

if context.is_mutating_use() {
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_const_eval/src/transform/check_consts/ops.rs
Expand Up @@ -400,18 +400,18 @@ impl NonConstOp for RawPtrComparison {
}

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

fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_raw_ptr_deref,
sym::const_mut_refs,
span,
&format!("dereferencing raw pointers in {}s is unstable", ccx.const_kind(),),
&format!("dereferencing raw mutable pointers in {}s is unstable", ccx.const_kind(),),
)
}
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/accepted.rs
Expand Up @@ -299,6 +299,8 @@ declare_features! (
(accepted, const_panic, "1.57.0", Some(51999), None),
/// Lessens the requirements for structs to implement `Unsize`.
(accepted, relaxed_struct_unsize, "1.58.0", Some(81793), None),
/// Allows dereferencing raw pointers during const eval.
(accepted, const_raw_ptr_deref, "1.58.0", Some(51911), None),

// -------------------------------------------------------------------------
// feature-group-end: accepted features
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_feature/src/active.rs
Expand Up @@ -408,9 +408,6 @@ declare_features! (
/// Allows inferring `'static` outlives requirements (RFC 2093).
(active, infer_static_outlives_requirements, "1.26.0", Some(54185), None),

/// Allows dereferencing raw pointers during const eval.
(active, const_raw_ptr_deref, "1.27.0", Some(51911), None),

/// Allows inconsistent bounds in where clauses.
(active, trivial_bounds, "1.28.0", Some(48214), None),

Expand Down
2 changes: 1 addition & 1 deletion library/core/src/lib.rs
Expand Up @@ -156,7 +156,7 @@
#![feature(const_impl_trait)]
#![feature(const_mut_refs)]
#![feature(const_precise_live_drops)]
#![feature(const_raw_ptr_deref)]
#![cfg_attr(bootstrap, feature(const_raw_ptr_deref))]
#![feature(const_refs_to_cell)]
#![feature(decl_macro)]
#![feature(doc_cfg)]
Expand Down
2 changes: 1 addition & 1 deletion library/core/tests/lib.rs
Expand Up @@ -56,7 +56,7 @@
#![feature(const_mut_refs)]
#![feature(const_pin)]
#![feature(const_slice_from_raw_parts)]
#![feature(const_raw_ptr_deref)]
#![cfg_attr(bootstrap, feature(const_raw_ptr_deref))]
#![feature(never_type)]
#![feature(unwrap_infallible)]
#![feature(result_into_ok_or_err)]
Expand Down
3 changes: 2 additions & 1 deletion library/std/src/lib.rs
Expand Up @@ -264,7 +264,8 @@
#![feature(const_ipv4)]
#![feature(const_ipv6)]
#![feature(const_option)]
#![feature(const_raw_ptr_deref)]
#![cfg_attr(bootstrap, feature(const_raw_ptr_deref))]
#![cfg_attr(not(bootstrap), feature(const_mut_refs))]
#![feature(const_socketaddr)]
#![feature(const_trait_impl)]
#![feature(container_error_extra)]
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/consts/const-deref-ptr.rs
@@ -1,7 +1,7 @@
// Check that you can't dereference raw pointers in constants.
// Check that you can't dereference invalid raw pointers in constants.

fn main() {
static C: u64 = unsafe {*(0xdeadbeef as *const u64)};
//~^ ERROR dereferencing raw pointers in statics is unstable
//~^ ERROR could not evaluate static initializer
println!("{}", C);
}
9 changes: 3 additions & 6 deletions src/test/ui/consts/const-deref-ptr.stderr
@@ -1,12 +1,9 @@
error[E0658]: dereferencing raw pointers in statics is unstable
error[E0080]: could not evaluate static initializer
--> $DIR/const-deref-ptr.rs:4:29
|
LL | static C: u64 = unsafe {*(0xdeadbeef as *const u64)};
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #51911 <https://github.com/rust-lang/rust/issues/51911> for more information
= help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 0xdeadbeef is not a valid pointer

error: aborting due to previous error

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

This file was deleted.

This file was deleted.

@@ -1,8 +1,6 @@
// New test for #53818: modifying static memory at compile-time is not allowed.
// The test should never compile successfully

#![feature(const_raw_ptr_deref)]

use std::cell::UnsafeCell;

static mut FOO: u32 = 42;
Expand Down
@@ -1,5 +1,5 @@
error[E0080]: could not evaluate static initializer
--> $DIR/assign-to-static-within-other-static.rs:10:5
--> $DIR/assign-to-static-within-other-static.rs:8:5
|
LL | FOO = 5;
| ^^^^^^^ modifying a static's initial value from another static's initializer
Expand Down
2 changes: 0 additions & 2 deletions src/test/ui/consts/const-eval/const_raw_ptr_ops2.rs
@@ -1,5 +1,3 @@
#![feature(const_raw_ptr_deref)]

fn main() {}

// fine
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/consts/const-eval/const_raw_ptr_ops2.stderr
@@ -1,11 +1,11 @@
error[E0080]: evaluation of constant value failed
--> $DIR/const_raw_ptr_ops2.rs:9:26
--> $DIR/const_raw_ptr_ops2.rs:7:26
|
LL | const Z2: i32 = unsafe { *(42 as *const i32) };
| ^^^^^^^^^^^^^^^^^^^ 0x2a is not a valid pointer

error[E0080]: evaluation of constant value failed
--> $DIR/const_raw_ptr_ops2.rs:11:26
--> $DIR/const_raw_ptr_ops2.rs:9:26
|
LL | const Z3: i32 = unsafe { *(44 as *const i32) };
| ^^^^^^^^^^^^^^^^^^^ 0x2c is not a valid pointer
Expand Down
2 changes: 0 additions & 2 deletions src/test/ui/consts/const-eval/dangling.rs
@@ -1,5 +1,3 @@
#![feature(const_raw_ptr_deref)]

use std::mem;

// Make sure we error with the right kind of error on a too large slice.
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/consts/const-eval/dangling.stderr
@@ -1,5 +1,5 @@
error[E0080]: evaluation of constant value failed
--> $DIR/dangling.rs:8:16
--> $DIR/dangling.rs:6:16
|
LL | let _val = &*slice;
| ^^^^^^^ invalid metadata in wide pointer: slice is bigger than largest supported object
Expand Down
@@ -1,6 +1,5 @@
#![feature(core_intrinsics)]
#![feature(const_heap)]
#![feature(const_raw_ptr_deref)]
#![feature(const_mut_refs)]
use std::intrinsics;

Expand Down
@@ -1,14 +1,14 @@
error[E0080]: evaluation of constant value failed
--> $DIR/alloc_intrinsic_errors.rs:10:17
--> $DIR/alloc_intrinsic_errors.rs:9:17
|
LL | const FOO: i32 = foo();
| ----- inside `FOO` at $DIR/alloc_intrinsic_errors.rs:7:18
| ----- inside `FOO` at $DIR/alloc_intrinsic_errors.rs:6:18
...
LL | let _ = intrinsics::const_allocate(4, 3) as * mut i32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| align has to be a power of 2, `3` is not a power of 2
| inside `foo` at $DIR/alloc_intrinsic_errors.rs:10:17
| inside `foo` at $DIR/alloc_intrinsic_errors.rs:9:17

error: aborting due to previous error

Expand Down
@@ -1,7 +1,6 @@
// run-pass
#![feature(core_intrinsics)]
#![feature(const_heap)]
#![feature(const_raw_ptr_deref)]
#![feature(const_mut_refs)]
use std::intrinsics;

Expand Down
@@ -1,6 +1,5 @@
#![feature(core_intrinsics)]
#![feature(const_heap)]
#![feature(const_raw_ptr_deref)]
#![feature(const_mut_refs)]
use std::intrinsics;

Expand Down
@@ -1,5 +1,5 @@
error: untyped pointers are not allowed in constant
--> $DIR/alloc_intrinsic_nontransient_fail.rs:7:1
--> $DIR/alloc_intrinsic_nontransient_fail.rs:6:1
|
LL | const FOO: *const i32 = foo();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
@@ -1,7 +1,6 @@
// run-pass
#![feature(core_intrinsics)]
#![feature(const_heap)]
#![feature(const_raw_ptr_deref)]
#![feature(const_mut_refs)]
use std::intrinsics;

Expand Down
@@ -1,5 +1,5 @@
error[E0080]: it is undefined behavior to use this value
--> $DIR/alloc_intrinsic_uninit.rs:9:1
--> $DIR/alloc_intrinsic_uninit.rs:8:1
|
LL | const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<deref>: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes
Expand Down
@@ -1,5 +1,5 @@
error[E0080]: it is undefined behavior to use this value
--> $DIR/alloc_intrinsic_uninit.rs:9:1
--> $DIR/alloc_intrinsic_uninit.rs:8:1
|
LL | const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<deref>: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes
Expand Down
Expand Up @@ -2,7 +2,6 @@
// compile-test
#![feature(core_intrinsics)]
#![feature(const_heap)]
#![feature(const_raw_ptr_deref)]
#![feature(const_mut_refs)]
use std::intrinsics;

Expand Down
@@ -1,6 +1,5 @@
#![feature(core_intrinsics)]
#![feature(const_heap)]
#![feature(const_raw_ptr_deref)]
#![feature(const_mut_refs)]
use std::intrinsics;

Expand Down
@@ -1,5 +1,5 @@
error: untyped pointers are not allowed in constant
--> $DIR/alloc_intrinsic_untyped.rs:7:1
--> $DIR/alloc_intrinsic_untyped.rs:6:1
|
LL | const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32};
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/consts/const-eval/mod-static-with-const-fn.rs
@@ -1,7 +1,7 @@
// New test for #53818: modifying static memory at compile-time is not allowed.
// The test should never compile successfully

#![feature(const_raw_ptr_deref)]
#![feature(const_mut_refs)]

use std::cell::UnsafeCell;

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

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

fn main() {
Expand Down
9 changes: 3 additions & 6 deletions src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr
@@ -1,12 +1,9 @@
error[E0658]: mutation through a reference is not allowed in statics
error[E0080]: could not evaluate static initializer
--> $DIR/mod-static-with-const-fn.rs:16:5
|
LL | *FOO.0.get() = 5;
| ^^^^^^^^^^^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
| ^^^^^^^^^^^^^^^^ modifying a static's initial value from another static's initializer

error: aborting due to previous error

For more information about this error, try `rustc --explain E0658`.
For more information about this error, try `rustc --explain E0080`.
2 changes: 1 addition & 1 deletion src/test/ui/consts/const-eval/partial_ptr_overwrite.rs
@@ -1,5 +1,5 @@
// Test for the behavior described in <https://github.com/rust-lang/rust/issues/87184>.
#![feature(const_mut_refs, const_raw_ptr_deref)]
#![feature(const_mut_refs)]

const PARTIAL_OVERWRITE: () = {
let mut p = &42;
Expand Down
2 changes: 0 additions & 2 deletions src/test/ui/consts/const-eval/promoted_raw_ptr_ops.rs
@@ -1,5 +1,3 @@
#![feature(const_raw_ptr_deref)]

fn main() {
let x: &'static bool = &(42 as *const i32 == 43 as *const i32);
//~^ ERROR temporary value dropped while borrowed
Expand Down
8 changes: 4 additions & 4 deletions src/test/ui/consts/const-eval/promoted_raw_ptr_ops.stderr
@@ -1,5 +1,5 @@
error[E0716]: temporary value dropped while borrowed
--> $DIR/promoted_raw_ptr_ops.rs:4:29
--> $DIR/promoted_raw_ptr_ops.rs:2:29
|
LL | let x: &'static bool = &(42 as *const i32 == 43 as *const i32);
| ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
Expand All @@ -10,7 +10,7 @@ LL | }
| - temporary value is freed at the end of this statement

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

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

error[E0716]: temporary value dropped while borrowed
--> $DIR/promoted_raw_ptr_ops.rs:10:29
--> $DIR/promoted_raw_ptr_ops.rs:8:29
|
LL | let a: &'static bool = &(main as fn() == main as fn());
| ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
Expand Down
1 change: 0 additions & 1 deletion src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs
@@ -1,6 +1,5 @@
#![feature(const_mut_refs)]
#![feature(raw_ref_op)]
#![feature(const_raw_ptr_deref)]

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

0 comments on commit 0cdbeaa

Please sign in to comment.