about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-07-19 05:26:24 +0000
committerbors <bors@rust-lang.org>2024-07-19 05:26:24 +0000
commitb06e8ad97074a624afaebea9117aef79f4f95ca1 (patch)
treefabb3adef40dd2be585197f3bd28c5c49b990f59
parent3ad5ec81fdfbfefda2b594da618e6d4f25e66792 (diff)
parent42c2364325d18b14b977ab1997e8911cb9e4d1fa (diff)
downloadrust-b06e8ad97074a624afaebea9117aef79f4f95ca1.tar.gz
rust-b06e8ad97074a624afaebea9117aef79f4f95ca1.zip
Auto merge of #127944 - compiler-errors:beta-no-unsafe, r=Mark-Simulacrum
Don't allow unsafe statics outside of extern blocks (beta version)

This PR fixes a regression where we allowed `unsafe static` items in top-level modules (i.e. outside of `unsafe extern` blocks).

#127943 does not rebase cleanly, so I've prepared an extremely pared down version of this PR for beta purposes.
-rw-r--r--compiler/rustc_ast_passes/messages.ftl3
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs16
-rw-r--r--compiler/rustc_ast_passes/src/errors.rs7
-rw-r--r--tests/ui/rust-2024/safe-outside-extern.gated.stderr8
-rw-r--r--tests/ui/rust-2024/safe-outside-extern.rs9
-rw-r--r--tests/ui/rust-2024/safe-outside-extern.ungated.stderr8
6 files changed, 46 insertions, 5 deletions
diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl
index 9a8689e27c0..8291d315f61 100644
--- a/compiler/rustc_ast_passes/messages.ftl
+++ b/compiler/rustc_ast_passes/messages.ftl
@@ -264,6 +264,9 @@ ast_passes_unsafe_negative_impl = negative impls cannot be unsafe
     .negative = negative because of this
     .unsafe = unsafe because of this
 
+ast_passes_unsafe_static =
+    static items cannot be declared with `unsafe` safety qualifier outside of `extern` block
+
 ast_passes_visibility_not_permitted =
     visibility qualifiers are not permitted here
     .enum_variant = enum variants and their fields always share the visibility of the enum they are in
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 0fbb288cc96..f367df40e82 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -1161,11 +1161,17 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     });
                 }
             }
-            ItemKind::Static(box StaticItem { expr: None, .. }) => {
-                self.dcx().emit_err(errors::StaticWithoutBody {
-                    span: item.span,
-                    replace_span: self.ending_semi_or_hi(item.span),
-                });
+            ItemKind::Static(box StaticItem { expr, safety, .. }) => {
+                if matches!(safety, Safety::Unsafe(_)) {
+                    self.dcx().emit_err(errors::UnsafeStatic { span: item.span });
+                }
+
+                if expr.is_none() {
+                    self.dcx().emit_err(errors::StaticWithoutBody {
+                        span: item.span,
+                        replace_span: self.ending_semi_or_hi(item.span),
+                    });
+                }
             }
             ItemKind::TyAlias(
                 ty_alias @ box TyAlias { defaultness, bounds, where_clauses, ty, .. },
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index 260c182bd9e..a51595a611b 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -226,6 +226,13 @@ pub struct InvalidSafetyOnExtern {
 }
 
 #[derive(Diagnostic)]
+#[diag(ast_passes_unsafe_static)]
+pub struct UnsafeStatic {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(ast_passes_bound_in_context)]
 pub struct BoundInContext<'a> {
     #[primary_span]
diff --git a/tests/ui/rust-2024/safe-outside-extern.gated.stderr b/tests/ui/rust-2024/safe-outside-extern.gated.stderr
new file mode 100644
index 00000000000..a81f8382859
--- /dev/null
+++ b/tests/ui/rust-2024/safe-outside-extern.gated.stderr
@@ -0,0 +1,8 @@
+error: static items cannot be declared with `unsafe` safety qualifier outside of `extern` block
+  --> $DIR/safe-outside-extern.rs:6:1
+   |
+LL | unsafe static LOL: u8 = 0;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/rust-2024/safe-outside-extern.rs b/tests/ui/rust-2024/safe-outside-extern.rs
new file mode 100644
index 00000000000..137331e9d38
--- /dev/null
+++ b/tests/ui/rust-2024/safe-outside-extern.rs
@@ -0,0 +1,9 @@
+//@ revisions: gated ungated
+
+// Very pared down version of the same named test on nightly, since we only want
+// to validate that `unsafe static` is not being accidentally accepted by the parser.
+
+unsafe static LOL: u8 = 0;
+//~^ ERROR: static items cannot be declared with `unsafe` safety qualifier outside of `extern` block
+
+fn main() {}
diff --git a/tests/ui/rust-2024/safe-outside-extern.ungated.stderr b/tests/ui/rust-2024/safe-outside-extern.ungated.stderr
new file mode 100644
index 00000000000..a81f8382859
--- /dev/null
+++ b/tests/ui/rust-2024/safe-outside-extern.ungated.stderr
@@ -0,0 +1,8 @@
+error: static items cannot be declared with `unsafe` safety qualifier outside of `extern` block
+  --> $DIR/safe-outside-extern.rs:6:1
+   |
+LL | unsafe static LOL: u8 = 0;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+