Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disallow reference to static mut and adding static_mut_ref lint #117556

Merged
merged 6 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Update test for E0796 and static_mut_ref lint
  • Loading branch information
obeis committed Jan 7, 2024
commit a8aa6878f63e53a9b0cfee542e9765407e1ca0d6
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 111,9 @@ fn start<T: Termination 'static>(
}

static mut NUM: u8 = 6 * 7;

// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
#[allow(static_mut_ref)]
obeis marked this conversation as resolved.
Show resolved Hide resolved
static NUM_REF: &'static u8 = unsafe { &NUM };

unsafe fn zeroed<T>() -> T {
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 98,9 @@ fn start<T: Termination 'static>(
}

static mut NUM: u8 = 6 * 7;

// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
#[allow(static_mut_ref)]
static NUM_REF: &'static u8 = unsafe { &NUM };

macro_rules! assert {
Expand Down
4 changes: 4 additions & 0 deletions library/panic_unwind/src/seh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 261,8 @@ cfg_if::cfg_if! {
}
}

// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
#[cfg_attr(not(bootstrap), allow(static_mut_ref))]
pub unsafe fn panic(data: Box<dyn Any Send>) -> u32 {
use core::intrinsics::atomic_store_seqcst;

Expand Down Expand Up @@ -322,6 324,8 @@ pub unsafe fn panic(data: Box<dyn Any Send>) -> u32 {
_CxxThrowException(throw_ptr, &mut THROW_INFO as *mut _ as *mut _);
}

// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
#[cfg_attr(not(bootstrap), allow(static_mut_ref))]
pub unsafe fn cleanup(payload: *mut u8) -> Box<dyn Any Send> {
// A null payload here means that we got here from the catch (...) of
// __rust_try. This happens when a non-Rust foreign exception is caught.
Expand Down
2 changes: 2 additions & 0 deletions library/std/src/panicking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 337,8 @@ pub mod panic_count {
#[doc(hidden)]
#[cfg(not(feature = "panic_immediate_abort"))]
#[unstable(feature = "update_panic_count", issue = "none")]
// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
#[cfg_attr(not(bootstrap), allow(static_mut_ref))]
pub mod panic_count {
use crate::cell::Cell;
use crate::sync::atomic::{AtomicUsize, Ordering};
Expand Down
2 changes: 2 additions & 0 deletions library/std/src/sys/common/thread_local/fast_local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 13,8 @@ pub macro thread_local_inner {
(@key $t:ty, const $init:expr) => {{
#[inline]
#[deny(unsafe_op_in_unsafe_fn)]
// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
#[cfg_attr(not(bootstrap), allow(static_mut_ref))]
unsafe fn __getit(
_init: $crate::option::Option<&mut $crate::option::Option<$t>>,
) -> $crate::option::Option<&'static $t> {
Expand Down
2 changes: 2 additions & 0 deletions library/std/src/sys/common/thread_local/static_local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 11,8 @@ pub macro thread_local_inner {
(@key $t:ty, const $init:expr) => {{
#[inline] // see comments below
#[deny(unsafe_op_in_unsafe_fn)]
// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
#[cfg_attr(not(bootstrap), allow(static_mut_ref))]
unsafe fn __getit(
_init: $crate::option::Option<&mut $crate::option::Option<$t>>,
) -> $crate::option::Option<&'static $t> {
Expand Down
2 changes: 2 additions & 0 deletions library/std/src/thread/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 180,8 @@ impl<T: 'static> fmt::Debug for LocalKey<T> {
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "thread_local_macro")]
#[allow_internal_unstable(thread_local_internals)]
// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
#[cfg_attr(not(bootstrap), allow(static_mut_ref))]
macro_rules! thread_local {
// empty (base case for the recursion)
() => {};
Expand Down
1 change: 1 addition & 0 deletions src/tools/lint-docs/src/groups.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 15,7 @@ static GROUP_DESCRIPTIONS: &[(&str, &str)] = &[
("future-incompatible", "Lints that detect code that has future-compatibility problems"),
("rust-2018-compatibility", "Lints used to transition code from the 2015 edition to 2018"),
("rust-2021-compatibility", "Lints used to transition code from the 2018 edition to 2021"),
("rust-2024-compatibility", "Lints used to transition code from the 2021 edition to 2024"),
];

type LintGroups = BTreeMap<String, BTreeSet<String>>;
Expand Down
2 changes: 2 additions & 0 deletions src/tools/miri/tests/fail/tls/tls_static_dealloc.rs
Original file line number Diff line number Diff line change
@@ -1,6 1,8 @@
//! Ensure that thread-local statics get deallocated when the thread dies.

#![feature(thread_local)]
// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
#![allow(static_mut_ref)]

#[thread_local]
static mut TLS: u8 = 0;
Expand Down
3 changes: 3 additions & 0 deletions src/tools/miri/tests/pass/static_mut.rs
Original file line number Diff line number Diff line change
@@ -1,4 1,7 @@
static mut FOO: i32 = 42;

// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
#[allow(static_mut_ref)]
static BAR: Foo = Foo(unsafe { &FOO as *const _ });

#[allow(dead_code)]
Expand Down
2 changes: 2 additions & 0 deletions src/tools/miri/tests/pass/tls/tls_static.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 8,8 @@
//! test, we also check that thread-locals act as per-thread statics.

#![feature(thread_local)]
// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
#![allow(static_mut_ref)]

use std::thread;

Expand Down
2 changes: 2 additions & 0 deletions tests/ui/abi/statics/static-mut-foreign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 33,9 @@ unsafe fn run() {
rust_dbg_static_mut = -3;
assert_eq!(rust_dbg_static_mut, -3);
static_bound(&rust_dbg_static_mut);
//~^ WARN shared reference of mutable static is discouraged [static_mut_ref]
static_bound_set(&mut rust_dbg_static_mut);
//~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
}

pub fn main() {
Expand Down
31 changes: 31 additions & 0 deletions tests/ui/abi/statics/static-mut-foreign.stderr
Original file line number Diff line number Diff line change
@@ -0,0 1,31 @@
warning: shared reference of mutable static is discouraged
--> $DIR/static-mut-foreign.rs:35:18
|
LL | static_bound(&rust_dbg_static_mut);
| ^^^^^^^^^^^^^^^^^^^^ shared reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
|
LL | static_bound(addr_of!(rust_dbg_static_mut));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

warning: mutable reference of mutable static is discouraged
--> $DIR/static-mut-foreign.rs:37:22
|
LL | static_bound_set(&mut rust_dbg_static_mut);
| ^^^^^^^^^^^^^^^^^^^^^^^^ mutable reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
LL | static_bound_set(addr_of_mut!(rust_dbg_static_mut));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

warning: 2 warnings emitted

36 changes: 24 additions & 12 deletions tests/ui/borrowck/borrowck-access-permissions.rs
Original file line number Diff line number Diff line change
@@ -1,48 1,60 @@
static static_x : i32 = 1;
static mut static_x_mut : i32 = 1;
static static_x: i32 = 1;
static mut static_x_mut: i32 = 1;

fn main() {
let x = 1;
let mut x_mut = 1;

{ // borrow of local
{
// borrow of local
let _y1 = &mut x; //~ ERROR [E0596]
let _y2 = &mut x_mut; // No error
}

{ // borrow of static
{
// borrow of static
let _y1 = &mut static_x; //~ ERROR [E0596]
unsafe { let _y2 = &mut static_x_mut; } // No error
unsafe {
let _y2 = &mut static_x_mut;
//~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
}
}

{ // borrow of deref to box
{
// borrow of deref to box
let box_x = Box::new(1);
let mut box_x_mut = Box::new(1);

let _y1 = &mut *box_x; //~ ERROR [E0596]
let _y2 = &mut *box_x_mut; // No error
}

{ // borrow of deref to reference
{
// borrow of deref to reference
let ref_x = &x;
let ref_x_mut = &mut x_mut;

let _y1 = &mut *ref_x; //~ ERROR [E0596]
let _y2 = &mut *ref_x_mut; // No error
}

{ // borrow of deref to pointer
let ptr_x : *const _ = &x;
let ptr_mut_x : *mut _ = &mut x_mut;
{
// borrow of deref to pointer
let ptr_x: *const _ = &x;
let ptr_mut_x: *mut _ = &mut x_mut;

unsafe {
let _y1 = &mut *ptr_x; //~ ERROR [E0596]
let _y2 = &mut *ptr_mut_x; // No error
}
}

{ // borrowing mutably through an immutable reference
struct Foo<'a> { f: &'a mut i32, g: &'a i32 };
{
// borrowing mutably through an immutable reference
struct Foo<'a> {
f: &'a mut i32,
g: &'a i32,
};
let mut foo = Foo { f: &mut x_mut, g: &x };
let foo_ref = &foo;
let _y = &mut *foo_ref.f; //~ ERROR [E0596]
Expand Down
33 changes: 24 additions & 9 deletions tests/ui/borrowck/borrowck-access-permissions.stderr
Original file line number Diff line number Diff line change
@@ -1,5 1,20 @@
warning: mutable reference of mutable static is discouraged
--> $DIR/borrowck-access-permissions.rs:18:23
|
LL | let _y2 = &mut static_x_mut;
| ^^^^^^^^^^^^^^^^^ mutable reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
LL | let _y2 = addr_of_mut!(static_x_mut);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~

error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/borrowck-access-permissions.rs:9:19
--> $DIR/borrowck-access-permissions.rs:10:19
|
LL | let _y1 = &mut x;
| ^^^^^^ cannot borrow as mutable
Expand All @@ -10,13 25,13 @@ LL | let mut x = 1;
|

error[E0596]: cannot borrow immutable static item `static_x` as mutable
--> $DIR/borrowck-access-permissions.rs:14:19
--> $DIR/borrowck-access-permissions.rs:16:19
|
LL | let _y1 = &mut static_x;
| ^^^^^^^^^^^^^ cannot borrow as mutable

error[E0596]: cannot borrow `*box_x` as mutable, as `box_x` is not declared as mutable
--> $DIR/borrowck-access-permissions.rs:22:19
--> $DIR/borrowck-access-permissions.rs:28:19
|
LL | let _y1 = &mut *box_x;
| ^^^^^^^^^^^ cannot borrow as mutable
Expand All @@ -27,7 42,7 @@ LL | let mut box_x = Box::new(1);
|

error[E0596]: cannot borrow `*ref_x` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-access-permissions.rs:30:19
--> $DIR/borrowck-access-permissions.rs:37:19
|
LL | let _y1 = &mut *ref_x;
| ^^^^^^^^^^^ `ref_x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
Expand All @@ -38,18 53,18 @@ LL | let ref_x = &mut x;
|

error[E0596]: cannot borrow `*ptr_x` as mutable, as it is behind a `*const` pointer
--> $DIR/borrowck-access-permissions.rs:39:23
--> $DIR/borrowck-access-permissions.rs:47:23
|
LL | let _y1 = &mut *ptr_x;
| ^^^^^^^^^^^ `ptr_x` is a `*const` pointer, so the data it refers to cannot be borrowed as mutable
|
help: consider changing this to be a mutable pointer
|
LL | let ptr_x : *const _ = &mut x;
|
LL | let ptr_x: *const _ = &mut x;
|

error[E0596]: cannot borrow `*foo_ref.f` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-access-permissions.rs:48:18
--> $DIR/borrowck-access-permissions.rs:60:18
|
LL | let _y = &mut *foo_ref.f;
| ^^^^^^^^^^^^^^^ `foo_ref` is a `&` reference, so the data it refers to cannot be borrowed as mutable
Expand All @@ -59,6 74,6 @@ help: consider changing this to be a mutable reference
LL | let foo_ref = &mut foo;
|

error: aborting due to 6 previous errors
error: aborting due to 6 previous errors; 1 warning emitted

For more information about this error, try `rustc --explain E0596`.
9 changes: 7 additions & 2 deletions tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 2,22 @@

// Test file taken from issue 45129 (https://github.com/rust-lang/rust/issues/45129)

struct Foo { x: [usize; 2] }
struct Foo {
x: [usize; 2],
}

static mut SFOO: Foo = Foo { x: [23, 32] };

impl Foo {
fn x(&mut self) -> &mut usize { &mut self.x[0] }
fn x(&mut self) -> &mut usize {
&mut self.x[0]
}
}

fn main() {
unsafe {
let sfoo: *mut Foo = &mut SFOO;
//~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
let x = (*sfoo).x();
(*sfoo).x[1] = 1;
*x = 1;
Expand Down
17 changes: 17 additions & 0 deletions tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr
Original file line number Diff line number Diff line change
@@ -0,0 1,17 @@
warning: mutable reference of mutable static is discouraged
--> $DIR/borrowck-unsafe-static-mutable-borrows.rs:19:30
|
LL | let sfoo: *mut Foo = &mut SFOO;
| ^^^^^^^^^ mutable reference of mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: reference of mutable static is a hard error from 2024 edition
= note: mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
= note: `#[warn(static_mut_ref)]` on by default
help: mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
|
LL | let sfoo: *mut Foo = addr_of_mut!(SFOO);
| ~~~~~~~~~~~~~~~~~~

warning: 1 warning emitted

1 change: 1 addition & 0 deletions tests/ui/borrowck/issue-20801.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 12,7 @@ fn imm_ref() -> &'static T {

fn mut_ref() -> &'static mut T {
unsafe { &mut GLOBAL_MUT_T }
//~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
}

fn mut_ptr() -> *mut T {
Expand Down
Loading
Loading