Skip to content

Commit 1211237

Browse files
committed
static mut: allow reference to arbitrary types, not just slices and arrays
1 parent 8acf40b commit 1211237

File tree

7 files changed

+40
-56
lines changed

7 files changed

+40
-56
lines changed

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

+10-24
Original file line numberDiff line numberDiff line change
@@ -471,35 +471,21 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
471471
}
472472
}
473473

474-
Rvalue::Ref(_, BorrowKind::Mut { .. }, place) => {
475-
let ty = place.ty(self.body, self.tcx).ty;
476-
let is_allowed = match ty.kind() {
477-
// Inside a `static mut`, `&mut [...]` is allowed.
478-
ty::Array(..) | ty::Slice(_)
479-
if self.const_kind() == hir::ConstContext::Static(hir::Mutability::Mut) =>
480-
{
481-
true
482-
}
483-
484-
// FIXME(ecstaticmorse): We could allow `&mut []` inside a const context given
485-
// that this is merely a ZST and it is already eligible for promotion.
486-
// This may require an RFC?
487-
/*
488-
ty::Array(_, len) if len.try_eval_target_usize(cx.tcx, cx.param_env) == Some(0)
489-
=> true,
490-
*/
491-
_ => false,
492-
};
474+
Rvalue::Ref(_, BorrowKind::Mut { .. }, place) | Rvalue::AddressOf(Mutability::Mut, place) => {
475+
// Inside mutable statics, we allow arbitrary mutable references.
476+
// We've allowed `static mut FOO = &mut [elements];` for a long time (the exact
477+
// reasons why are lost to history), and there is no reason to restrict that to
478+
// arrays and slices.
479+
let is_allowed = self.const_kind() == hir::ConstContext::Static(hir::Mutability::Mut);
493480

494481
if !is_allowed {
495-
self.check_mut_borrow(place.local, hir::BorrowKind::Ref)
482+
self.check_mut_borrow(
483+
place.local,
484+
if matches!(rvalue, Rvalue::Ref(..)) { hir::BorrowKind::Ref } else {hir::BorrowKind::Raw}
485+
);
496486
}
497487
}
498488

499-
Rvalue::AddressOf(Mutability::Mut, place) => {
500-
self.check_mut_borrow(place.local, hir::BorrowKind::Raw)
501-
}
502-
503489
Rvalue::Ref(_, BorrowKind::Shared | BorrowKind::Shallow, place)
504490
| Rvalue::AddressOf(Mutability::Not, place) => {
505491
let borrowed_place_has_mut_interior = qualifs::in_place::<HasMutInterior, _>(

tests/ui/array-slice-vec/check-static-mut-slices.rs

-15
This file was deleted.

tests/ui/consts/const-address-of-mut.rs

-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ const A: () = { let mut x = 2; &raw mut x; }; //~ mutable reference
44

55
static B: () = { let mut x = 2; &raw mut x; }; //~ mutable reference
66

7-
static mut C: () = { let mut x = 2; &raw mut x; }; //~ mutable reference
8-
97
const fn foo() {
108
let mut x = 0;
119
let y = &raw mut x; //~ mutable reference

tests/ui/consts/const-address-of-mut.stderr

+2-11
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,15 @@ LL | static B: () = { let mut x = 2; &raw mut x; };
1616
= note: see issue #57349 <https://github.com./rust-lang/rust/issues/57349> for more information
1717
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
1818

19-
error[E0658]: raw mutable references are not allowed in statics
20-
--> $DIR/const-address-of-mut.rs:7:37
21-
|
22-
LL | static mut C: () = { let mut x = 2; &raw mut x; };
23-
| ^^^^^^^^^^
24-
|
25-
= note: see issue #57349 <https://github.com./rust-lang/rust/issues/57349> for more information
26-
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
27-
2819
error[E0658]: raw mutable references are not allowed in constant functions
29-
--> $DIR/const-address-of-mut.rs:11:13
20+
--> $DIR/const-address-of-mut.rs:9:13
3021
|
3122
LL | let y = &raw mut x;
3223
| ^^^^^^^^^^
3324
|
3425
= note: see issue #57349 <https://github.com./rust-lang/rust/issues/57349> for more information
3526
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
3627

37-
error: aborting due to 4 previous errors
28+
error: aborting due to 3 previous errors
3829

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

tests/ui/consts/static-mut-refs.rs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// run-pass
2+
#![allow(dead_code)]
3+
4+
// Checks that mutable static items can have mutable slices and other references
5+
6+
7+
static mut TEST: &'static mut [isize] = &mut [1];
8+
static mut EMPTY: &'static mut [isize] = &mut [];
9+
static mut INT: &'static mut isize = &mut 1;
10+
11+
// And the same for raw pointers.
12+
13+
static mut TEST_RAW: *mut [isize] = &mut [1isize] as *mut _;
14+
static mut EMPTY_RAW: *mut [isize] = &mut [] as *mut _;
15+
static mut INT_RAW: *mut isize = &mut 1isize as *mut _;
16+
17+
pub fn main() {
18+
unsafe {
19+
TEST[0] += 1;
20+
assert_eq!(TEST[0], 2);
21+
*INT_RAW += 1;
22+
assert_eq!(*INT_RAW, 2);
23+
}
24+
}

tests/ui/consts/static_mut_containing_mut_ref2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ static mut STDERR_BUFFER_SPACE: u8 = 0;
66

77
pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; };
88
//[mut_refs]~^ ERROR could not evaluate static initializer
9-
//[stock]~^^ ERROR mutable references are not allowed in statics
9+
//[stock]~^^ ERROR mutation through a reference is not allowed in statics
1010

1111
fn main() {}

tests/ui/consts/static_mut_containing_mut_ref2.stock.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0658]: mutable references are not allowed in statics
2-
--> $DIR/static_mut_containing_mut_ref2.rs:7:46
1+
error[E0658]: mutation through a reference is not allowed in statics
2+
--> $DIR/static_mut_containing_mut_ref2.rs:7:45
33
|
44
LL | pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; };
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
77
= note: see issue #57349 <https://github.com./rust-lang/rust/issues/57349> for more information
88
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable

0 commit comments

Comments
 (0)