Skip to content

Commit f2a80a0

Browse files
A raw ref of a deref is always safe
1 parent 1b3b8e7 commit f2a80a0

File tree

4 files changed

+18
-11
lines changed

4 files changed

+18
-11
lines changed

compiler/rustc_mir_build/src/check_unsafety.rs

+3-9
Original file line numberDiff line numberDiff line change
@@ -512,17 +512,11 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
512512
// THIR desugars UNSAFE_STATIC into *UNSAFE_STATIC_REF, where
513513
// UNSAFE_STATIC_REF holds the addr of the UNSAFE_STATIC, so: take two steps
514514
&& let ExprKind::Deref { arg } = self.thir[arg].kind
515-
// FIXME(workingjubiee): we lack a clear reason to reject ThreadLocalRef here,
516-
// but we also have no conclusive reason to allow it either!
517-
&& let ExprKind::StaticRef { .. } = self.thir[arg].kind
518515
{
519-
// A raw ref to a place expr, even an "unsafe static", is okay!
520-
// We short-circuit to not recursively traverse this expression.
516+
// Taking a raw ref to a deref place expr is always safe.
517+
// Make sure the expression we're deref'ing is safe, though.
518+
visit::walk_expr(self, &self.thir[arg]);
521519
return;
522-
// note: const_mut_refs enables this code, and it currently remains unsafe:
523-
// static mut BYTE: u8 = 0;
524-
// static mut BYTE_PTR: *mut u8 = unsafe { addr_of_mut!(BYTE) };
525-
// static mut DEREF_BYTE_PTR: *mut u8 = unsafe { addr_of_mut!(*BYTE_PTR) };
526520
}
527521
}
528522
ExprKind::Deref { arg } => {

tests/ui/static/raw-ref-deref-without-unsafe.rs

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ static mut BYTE_PTR: *mut u8 = ptr::addr_of_mut!(BYTE);
99
// (it's fine to create raw refs to places!) the following derefs the ptr before creating its ref!
1010
static mut DEREF_BYTE_PTR: *mut u8 = ptr::addr_of_mut!(*BYTE_PTR);
1111
//~^ ERROR: use of mutable static
12-
//~| ERROR: dereference of raw pointer
1312

1413
fn main() {
1514
let _ = unsafe { DEREF_BYTE_PTR };

tests/ui/static/raw-ref-deref-without-unsafe.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ LL | static mut DEREF_BYTE_PTR: *mut u8 = ptr::addr_of_mut!(*BYTE_PTR);
1414
|
1515
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
1616

17-
error: aborting due to 2 previous errors
17+
error: aborting due to 1 previous error
1818

1919
For more information about this error, try `rustc --explain E0133`.

tests/ui/unsafe/place-expr-safe.rs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//@ check-pass
2+
3+
fn main() {
4+
let ptr = std::ptr::null_mut::<i32>();
5+
let addr = &raw const *ptr;
6+
7+
let local = 1;
8+
let ptr = &local as *const i32;
9+
let addr = &raw const *ptr;
10+
11+
let boxed = Box::new(1);
12+
let ptr = &*boxed as *const i32;
13+
let addr = &raw const *ptr;
14+
}

0 commit comments

Comments
 (0)