about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-06-21 04:22:02 +0000
committerbors <bors@rust-lang.org>2024-06-21 04:22:02 +0000
commit4e6de37349c7838df095b085a2640cb6a007c96a (patch)
tree11f20712d6ea2677bc2824b83bc7314ca60e9e61
parent7a08f84627ff3035de4d66ff3209e5fc93165dcb (diff)
parent108b3f214a7e160ecb7ac2ec05bbb41aedd05a95 (diff)
downloadrust-4e6de37349c7838df095b085a2640cb6a007c96a.tar.gz
rust-4e6de37349c7838df095b085a2640cb6a007c96a.zip
Auto merge of #126757 - compiler-errors:safe, r=spastorino
Properly gate `safe` keyword in pre-expansion

This PR gates `safe` keyword in pre-expansion contexts. Should mitigate the fallout of https://github.com/rust-lang/rust/issues/126755, which is that `safe` is now usable on beta lol.

r? `@spastorino` or `@oli-obk`

cc #124482 tracking #123743
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs4
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs3
-rw-r--r--tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.rs8
-rw-r--r--tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr13
4 files changed, 27 insertions, 1 deletions
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 764d942836c..e1c1a027a30 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -562,6 +562,10 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
     gate_all!(precise_capturing, "precise captures on `impl Trait` are experimental");
     gate_all!(global_registration, "global registration is experimental");
     gate_all!(unsafe_attributes, "`#[unsafe()]` markers for attributes are experimental");
+    gate_all!(
+        unsafe_extern_blocks,
+        "`unsafe extern {}` blocks and `safe` keyword are experimental"
+    );
 
     if !visitor.features.never_patterns {
         if let Some(spans) = spans.get(&sym::never_patterns) {
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 2f12459da57..cfd0a72c056 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -1214,6 +1214,9 @@ impl<'a> Parser<'a> {
         if self.eat_keyword_case(kw::Unsafe, case) {
             Safety::Unsafe(self.prev_token.uninterpolated_span())
         } else if self.eat_keyword_case(kw::Safe, case) {
+            self.psess
+                .gated_spans
+                .gate(sym::unsafe_extern_blocks, self.prev_token.uninterpolated_span());
             Safety::Safe(self.prev_token.uninterpolated_span())
         } else {
             Safety::Default
diff --git a/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.rs b/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.rs
index eab134a4a4d..3ea62e875b8 100644
--- a/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.rs
+++ b/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.rs
@@ -2,4 +2,12 @@ unsafe extern "C" {
     //~^ ERROR extern block cannot be declared unsafe
 }
 
+// We can't gate `unsafe extern` blocks themselves since they were previously
+// allowed, but we should gate the `safe` soft keyword.
+#[cfg(any())]
+unsafe extern "C" {
+    safe fn foo();
+    //~^ ERROR `unsafe extern {}` blocks and `safe` keyword are experimental
+}
+
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr b/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr
index 7e9b199a2db..84f00827c60 100644
--- a/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr
+++ b/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr
@@ -4,5 +4,16 @@ error: extern block cannot be declared unsafe
 LL | unsafe extern "C" {
    | ^^^^^^
 
-error: aborting due to 1 previous error
+error[E0658]: `unsafe extern {}` blocks and `safe` keyword are experimental
+  --> $DIR/feature-gate-unsafe-extern-blocks.rs:9:5
+   |
+LL |     safe fn foo();
+   |     ^^^^
+   |
+   = note: see issue #123743 <https://github.com/rust-lang/rust/issues/123743> for more information
+   = help: add `#![feature(unsafe_extern_blocks)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0658`.