static mut: allow reference to arbitrary types, not just slices and arrays
This commit is contained in:
parent
7df6f4a15e
commit
9a819ab8f7
9 changed files with 46 additions and 77 deletions
|
@ -476,35 +476,27 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rvalue::Ref(_, BorrowKind::Mut { .. }, place) => {
|
Rvalue::Ref(_, BorrowKind::Mut { .. }, place)
|
||||||
let ty = place.ty(self.body, self.tcx).ty;
|
| Rvalue::AddressOf(Mutability::Mut, place) => {
|
||||||
let is_allowed = match ty.kind() {
|
// Inside mutable statics, we allow arbitrary mutable references.
|
||||||
// Inside a `static mut`, `&mut [...]` is allowed.
|
// We've allowed `static mut FOO = &mut [elements];` for a long time (the exact
|
||||||
ty::Array(..) | ty::Slice(_)
|
// reasons why are lost to history), and there is no reason to restrict that to
|
||||||
if self.const_kind() == hir::ConstContext::Static(hir::Mutability::Mut) =>
|
// arrays and slices.
|
||||||
{
|
let is_allowed =
|
||||||
true
|
self.const_kind() == hir::ConstContext::Static(hir::Mutability::Mut);
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME(ecstaticmorse): We could allow `&mut []` inside a const context given
|
|
||||||
// that this is merely a ZST and it is already eligible for promotion.
|
|
||||||
// This may require an RFC?
|
|
||||||
/*
|
|
||||||
ty::Array(_, len) if len.try_eval_target_usize(cx.tcx, cx.param_env) == Some(0)
|
|
||||||
=> true,
|
|
||||||
*/
|
|
||||||
_ => false,
|
|
||||||
};
|
|
||||||
|
|
||||||
if !is_allowed {
|
if !is_allowed {
|
||||||
self.check_mut_borrow(place.local, hir::BorrowKind::Ref)
|
self.check_mut_borrow(
|
||||||
|
place.local,
|
||||||
|
if matches!(rvalue, Rvalue::Ref(..)) {
|
||||||
|
hir::BorrowKind::Ref
|
||||||
|
} else {
|
||||||
|
hir::BorrowKind::Raw
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rvalue::AddressOf(Mutability::Mut, place) => {
|
|
||||||
self.check_mut_borrow(place.local, hir::BorrowKind::Raw)
|
|
||||||
}
|
|
||||||
|
|
||||||
Rvalue::Ref(_, BorrowKind::Shared | BorrowKind::Fake, place)
|
Rvalue::Ref(_, BorrowKind::Shared | BorrowKind::Fake, place)
|
||||||
| Rvalue::AddressOf(Mutability::Not, place) => {
|
| Rvalue::AddressOf(Mutability::Not, place) => {
|
||||||
let borrowed_place_has_mut_interior = qualifs::in_place::<HasMutInterior, _>(
|
let borrowed_place_has_mut_interior = qualifs::in_place::<HasMutInterior, _>(
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
// run-pass
|
|
||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
// Checks that mutable static items can have mutable slices
|
|
||||||
|
|
||||||
|
|
||||||
static mut TEST: &'static mut [isize] = &mut [1];
|
|
||||||
static mut EMPTY: &'static mut [isize] = &mut [];
|
|
||||||
|
|
||||||
pub fn main() {
|
|
||||||
unsafe {
|
|
||||||
TEST[0] += 1;
|
|
||||||
assert_eq!(TEST[0], 2);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,8 +4,6 @@ const A: () = { let mut x = 2; &raw mut x; }; //~ mutable pointer
|
||||||
|
|
||||||
static B: () = { let mut x = 2; &raw mut x; }; //~ mutable pointer
|
static B: () = { let mut x = 2; &raw mut x; }; //~ mutable pointer
|
||||||
|
|
||||||
static mut C: () = { let mut x = 2; &raw mut x; }; //~ mutable pointer
|
|
||||||
|
|
||||||
const fn foo() {
|
const fn foo() {
|
||||||
let mut x = 0;
|
let mut x = 0;
|
||||||
let y = &raw mut x; //~ mutable pointer
|
let y = &raw mut x; //~ mutable pointer
|
||||||
|
|
|
@ -18,18 +18,8 @@ LL | static B: () = { let mut x = 2; &raw mut x; };
|
||||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error[E0658]: raw mutable pointers are not allowed in statics
|
|
||||||
--> $DIR/const-address-of-mut.rs:7:37
|
|
||||||
|
|
|
||||||
LL | static mut C: () = { let mut x = 2; &raw mut x; };
|
|
||||||
| ^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= 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
|
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
||||||
|
|
||||||
error[E0658]: raw mutable pointers are not allowed in constant functions
|
error[E0658]: raw mutable pointers are not allowed in constant functions
|
||||||
--> $DIR/const-address-of-mut.rs:11:13
|
--> $DIR/const-address-of-mut.rs:9:13
|
||||||
|
|
|
|
||||||
LL | let y = &raw mut x;
|
LL | let y = &raw mut x;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
@ -38,6 +28,6 @@ LL | let y = &raw mut x;
|
||||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
For more information about this error, try `rustc --explain E0658`.
|
||||||
|
|
|
@ -133,11 +133,6 @@ help: skipping check for `const_mut_refs` feature
|
||||||
|
|
|
|
||||||
LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
|
LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
|
||||||
--> $DIR/mutable_references_err.rs:40:49
|
|
||||||
|
|
|
||||||
LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/mutable_references_err.rs:47:44
|
--> $DIR/mutable_references_err.rs:47:44
|
||||||
|
|
|
|
||||||
|
@ -148,11 +143,6 @@ help: skipping check that does not even have a feature gate
|
||||||
|
|
|
|
||||||
LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE };
|
LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE };
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
|
||||||
--> $DIR/mutable_references_err.rs:50:36
|
|
||||||
|
|
|
||||||
LL | static mut MUTABLE_REF: &mut i32 = &mut 42;
|
|
||||||
| ^^^^^^^
|
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/mutable_references_err.rs:51:45
|
--> $DIR/mutable_references_err.rs:51:45
|
||||||
|
|
|
|
||||||
|
|
|
@ -133,11 +133,6 @@ help: skipping check for `const_mut_refs` feature
|
||||||
|
|
|
|
||||||
LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
|
LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
|
||||||
--> $DIR/mutable_references_err.rs:40:49
|
|
||||||
|
|
|
||||||
LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/mutable_references_err.rs:47:44
|
--> $DIR/mutable_references_err.rs:47:44
|
||||||
|
|
|
|
||||||
|
@ -148,11 +143,6 @@ help: skipping check that does not even have a feature gate
|
||||||
|
|
|
|
||||||
LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE };
|
LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE };
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
help: skipping check that does not even have a feature gate
|
|
||||||
--> $DIR/mutable_references_err.rs:50:36
|
|
||||||
|
|
|
||||||
LL | static mut MUTABLE_REF: &mut i32 = &mut 42;
|
|
||||||
| ^^^^^^^
|
|
||||||
help: skipping check that does not even have a feature gate
|
help: skipping check that does not even have a feature gate
|
||||||
--> $DIR/mutable_references_err.rs:51:45
|
--> $DIR/mutable_references_err.rs:51:45
|
||||||
|
|
|
|
||||||
|
|
24
tests/ui/consts/static-mut-refs.rs
Normal file
24
tests/ui/consts/static-mut-refs.rs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// run-pass
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
// Checks that mutable static items can have mutable slices and other references
|
||||||
|
|
||||||
|
|
||||||
|
static mut TEST: &'static mut [isize] = &mut [1];
|
||||||
|
static mut EMPTY: &'static mut [isize] = &mut [];
|
||||||
|
static mut INT: &'static mut isize = &mut 1;
|
||||||
|
|
||||||
|
// And the same for raw pointers.
|
||||||
|
|
||||||
|
static mut TEST_RAW: *mut [isize] = &mut [1isize] as *mut _;
|
||||||
|
static mut EMPTY_RAW: *mut [isize] = &mut [] as *mut _;
|
||||||
|
static mut INT_RAW: *mut isize = &mut 1isize as *mut _;
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
unsafe {
|
||||||
|
TEST[0] += 1;
|
||||||
|
assert_eq!(TEST[0], 2);
|
||||||
|
*INT_RAW += 1;
|
||||||
|
assert_eq!(*INT_RAW, 2);
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ static mut STDERR_BUFFER_SPACE: u8 = 0;
|
||||||
pub static mut STDERR_BUFFER: () = unsafe {
|
pub static mut STDERR_BUFFER: () = unsafe {
|
||||||
*(&mut STDERR_BUFFER_SPACE) = 42;
|
*(&mut STDERR_BUFFER_SPACE) = 42;
|
||||||
//[mut_refs]~^ ERROR could not evaluate static initializer
|
//[mut_refs]~^ ERROR could not evaluate static initializer
|
||||||
//[stock]~^^ ERROR mutable references are not allowed in statics
|
//[stock]~^^ ERROR mutation through a reference is not allowed in statics
|
||||||
//[mut_refs]~^^^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
|
//[mut_refs]~^^^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
|
||||||
//[stock]~^^^^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
|
//[stock]~^^^^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,11 +13,11 @@ help: mutable references are dangerous since if there's any other pointer or ref
|
||||||
LL | *addr_of_mut!(STDERR_BUFFER_SPACE) = 42;
|
LL | *addr_of_mut!(STDERR_BUFFER_SPACE) = 42;
|
||||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error[E0658]: mutable references are not allowed in statics
|
error[E0658]: mutation through a reference is not allowed in statics
|
||||||
--> $DIR/static_mut_containing_mut_ref2.rs:8:6
|
--> $DIR/static_mut_containing_mut_ref2.rs:8:5
|
||||||
|
|
|
|
||||||
LL | *(&mut STDERR_BUFFER_SPACE) = 42;
|
LL | *(&mut STDERR_BUFFER_SPACE) = 42;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
|
= 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
|
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue