Skip to content

Commit 6fe68f8

Browse files
authored
Rollup merge of #127943 - compiler-errors:no-unsafe, r=spastorino
Don't allow unsafe statics outside of extern blocks This PR fixes a regression where we allowed `unsafe static` items in top-level modules (i.e. outside of `unsafe extern` blocks). It's harder IMO to integrate this into the `check_item_safety` function, so I opted to just put this check on the `static` item itself. Beta version of this lives at #127944. r? ```@oli-obk``` or ```@spastorino```
2 parents 1c66573 + 2f5a84e commit 6fe68f8

File tree

6 files changed

+35
-2
lines changed

6 files changed

+35
-2
lines changed

compiler/rustc_ast_passes/messages.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,9 @@ ast_passes_unsafe_negative_impl = negative impls cannot be unsafe
269269
.negative = negative because of this
270270
.unsafe = unsafe because of this
271271
272+
ast_passes_unsafe_static =
273+
static items cannot be declared with `unsafe` safety qualifier outside of `extern` block
274+
272275
ast_passes_visibility_not_permitted =
273276
visibility qualifiers are not permitted here
274277
.enum_variant = enum variants and their fields always share the visibility of the enum they are in

compiler/rustc_ast_passes/src/ast_validation.rs

+8
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,11 @@ impl<'a> AstValidator<'a> {
438438
}
439439
}
440440

441+
/// This ensures that items can only be `unsafe` (or unmarked) outside of extern
442+
/// blocks.
443+
///
444+
/// This additionally ensures that within extern blocks, items can only be
445+
/// `safe`/`unsafe` inside of a `unsafe`-adorned extern block.
441446
fn check_item_safety(&self, span: Span, safety: Safety) {
442447
match self.extern_mod_safety {
443448
Some(extern_safety) => {
@@ -1177,6 +1182,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
11771182
}
11781183
ItemKind::Static(box StaticItem { expr, safety, .. }) => {
11791184
self.check_item_safety(item.span, *safety);
1185+
if matches!(safety, Safety::Unsafe(_)) {
1186+
self.dcx().emit_err(errors::UnsafeStatic { span: item.span });
1187+
}
11801188

11811189
if expr.is_none() {
11821190
self.dcx().emit_err(errors::StaticWithoutBody {

compiler/rustc_ast_passes/src/errors.rs

+7
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,13 @@ pub struct InvalidSafetyOnBareFn {
224224
pub span: Span,
225225
}
226226

227+
#[derive(Diagnostic)]
228+
#[diag(ast_passes_unsafe_static)]
229+
pub struct UnsafeStatic {
230+
#[primary_span]
231+
pub span: Span,
232+
}
233+
227234
#[derive(Diagnostic)]
228235
#[diag(ast_passes_bound_in_context)]
229236
pub struct BoundInContext<'a> {

tests/ui/rust-2024/safe-outside-extern.gated.stderr

+7-1
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,11 @@ error: function pointers cannot be declared with `safe` safety qualifier
2828
LL | type FnPtr = safe fn(i32, i32) -> i32;
2929
| ^^^^^^^^^^^^^^^^^^^^^^^^
3030

31-
error: aborting due to 5 previous errors
31+
error: static items cannot be declared with `unsafe` safety qualifier outside of `extern` block
32+
--> $DIR/safe-outside-extern.rs:28:1
33+
|
34+
LL | unsafe static LOL: u8 = 0;
35+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
36+
37+
error: aborting due to 6 previous errors
3238

tests/ui/rust-2024/safe-outside-extern.rs

+3
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,7 @@ type FnPtr = safe fn(i32, i32) -> i32;
2525
//~^ ERROR: function pointers cannot be declared with `safe` safety qualifier
2626
//[ungated]~| ERROR: unsafe extern {}` blocks and `safe` keyword are experimental [E0658]
2727

28+
unsafe static LOL: u8 = 0;
29+
//~^ ERROR: static items cannot be declared with `unsafe` safety qualifier outside of `extern` block
30+
2831
fn main() {}

tests/ui/rust-2024/safe-outside-extern.ungated.stderr

+7-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ error: function pointers cannot be declared with `safe` safety qualifier
2828
LL | type FnPtr = safe fn(i32, i32) -> i32;
2929
| ^^^^^^^^^^^^^^^^^^^^^^^^
3030

31+
error: static items cannot be declared with `unsafe` safety qualifier outside of `extern` block
32+
--> $DIR/safe-outside-extern.rs:28:1
33+
|
34+
LL | unsafe static LOL: u8 = 0;
35+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
36+
3137
error[E0658]: `unsafe extern {}` blocks and `safe` keyword are experimental
3238
--> $DIR/safe-outside-extern.rs:4:1
3339
|
@@ -78,6 +84,6 @@ LL | type FnPtr = safe fn(i32, i32) -> i32;
7884
= help: add `#![feature(unsafe_extern_blocks)]` to the crate attributes to enable
7985
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
8086

81-
error: aborting due to 10 previous errors
87+
error: aborting due to 11 previous errors
8288

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

0 commit comments

Comments
 (0)