diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 8e2e4f42a36c9..ee70915a1d03e 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -464,12 +464,13 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { if let ExprKind::StaticRef { def_id, .. } | ExprKind::ThreadLocalRef(def_id) = self.thir[arg].kind { - if self.tcx.is_mutable_static(def_id) && allow_implicit_static_deref { + // The requirements for an extern static are much more stringent + if self.tcx.is_foreign_item(def_id) { + self.requires_unsafe(expr.span, UseOfExternStatic); + } else if self.tcx.is_mutable_static(def_id) && allow_implicit_static_deref { // we're only taking the address of the implicit place expr, it's fine } else if self.tcx.is_mutable_static(def_id) { self.requires_unsafe(expr.span, UseOfMutableStatic); - } else if self.tcx.is_foreign_item(def_id) { - self.requires_unsafe(expr.span, UseOfExternStatic); } } else if self.thir[arg].ty.is_unsafe_ptr() { self.requires_unsafe(expr.span, DerefOfRawPointer); diff --git a/src/tools/miri/tests/pass/static_mut.rs b/src/tools/miri/tests/pass/static_mut.rs index 1b416cc4e9b08..4488b5a09d5ba 100644 --- a/src/tools/miri/tests/pass/static_mut.rs +++ b/src/tools/miri/tests/pass/static_mut.rs @@ -2,7 +2,7 @@ use std::ptr::addr_of; static mut FOO: i32 = 42; -static BAR: Foo = Foo(unsafe { addr_of!(FOO) }); +static BAR: Foo = Foo(addr_of!(FOO)); #[allow(dead_code)] struct Foo(*const i32); diff --git a/tests/ui/static/safe-extern-statics-mut.rs b/tests/ui/static/safe-extern-statics-mut.rs index 05a1bee8891e8..640bcd12f76d0 100644 --- a/tests/ui/static/safe-extern-statics-mut.rs +++ b/tests/ui/static/safe-extern-statics-mut.rs @@ -8,10 +8,10 @@ extern "C" { } fn main() { - let b = B; //~ ERROR use of mutable static is unsafe - let rb = &B; //~ ERROR use of mutable static is unsafe - //~^ WARN shared reference to mutable static is discouraged [static_mut_refs] - let xb = XB; //~ ERROR use of mutable static is unsafe - let xrb = &XB; //~ ERROR use of mutable static is unsafe - //~^ WARN shared reference to mutable static is discouraged [static_mut_refs] + let b = B; //~ static is unsafe + let rb = &B; //~ static is unsafe + //~^ WARN shared reference to mutable static is discouraged [static_mut_refs] + let xb = XB; //~ static is unsafe + let xrb = &XB; //~ static is unsafe + //~^ WARN shared reference to mutable static is discouraged [static_mut_refs] } diff --git a/tests/ui/static/safe-extern-statics-mut.stderr b/tests/ui/static/safe-extern-statics-mut.stderr index 9a4b651405f23..38be3ede7525b 100644 --- a/tests/ui/static/safe-extern-statics-mut.stderr +++ b/tests/ui/static/safe-extern-statics-mut.stderr @@ -27,37 +27,37 @@ help: use `addr_of!` instead to create a raw pointer LL | let xrb = addr_of!(XB); | ~~~~~~~~~~~~ -error[E0133]: use of mutable static is unsafe and requires unsafe function or block +error[E0133]: use of extern static is unsafe and requires unsafe function or block --> $DIR/safe-extern-statics-mut.rs:11:13 | LL | let b = B; - | ^ use of mutable static + | ^ use of extern static | - = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior -error[E0133]: use of mutable static is unsafe and requires unsafe function or block +error[E0133]: use of extern static is unsafe and requires unsafe function or block --> $DIR/safe-extern-statics-mut.rs:12:15 | LL | let rb = &B; - | ^ use of mutable static + | ^ use of extern static | - = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior -error[E0133]: use of mutable static is unsafe and requires unsafe function or block +error[E0133]: use of extern static is unsafe and requires unsafe function or block --> $DIR/safe-extern-statics-mut.rs:14:14 | LL | let xb = XB; - | ^^ use of mutable static + | ^^ use of extern static | - = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior -error[E0133]: use of mutable static is unsafe and requires unsafe function or block +error[E0133]: use of extern static is unsafe and requires unsafe function or block --> $DIR/safe-extern-statics-mut.rs:15:16 | LL | let xrb = &XB; - | ^^ use of mutable static + | ^^ use of extern static | - = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior error: aborting due to 4 previous errors; 2 warnings emitted diff --git a/tests/ui/static/static-mut-foreign-requires-unsafe.stderr b/tests/ui/static/static-mut-foreign-requires-unsafe.stderr index 022f7e9fb1655..422fdcd49d791 100644 --- a/tests/ui/static/static-mut-foreign-requires-unsafe.stderr +++ b/tests/ui/static/static-mut-foreign-requires-unsafe.stderr @@ -1,26 +1,26 @@ -error[E0133]: use of mutable static is unsafe and requires unsafe function or block +error[E0133]: use of extern static is unsafe and requires unsafe function or block --> $DIR/static-mut-foreign-requires-unsafe.rs:6:5 | LL | a += 3; - | ^ use of mutable static + | ^ use of extern static | - = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior -error[E0133]: use of mutable static is unsafe and requires unsafe function or block +error[E0133]: use of extern static is unsafe and requires unsafe function or block --> $DIR/static-mut-foreign-requires-unsafe.rs:7:5 | LL | a = 4; - | ^ use of mutable static + | ^ use of extern static | - = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior -error[E0133]: use of mutable static is unsafe and requires unsafe function or block +error[E0133]: use of extern static is unsafe and requires unsafe function or block --> $DIR/static-mut-foreign-requires-unsafe.rs:8:14 | LL | let _b = a; - | ^ use of mutable static + | ^ use of extern static | - = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior error: aborting due to 3 previous errors