about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSantiago Pastorino <spastorino@gmail.com>2024-05-31 16:57:07 -0300
committerSantiago Pastorino <spastorino@gmail.com>2024-06-05 09:35:57 -0300
commit0380321e7806bdab232d7e95be2de47fad8f3c09 (patch)
treeff816fc584906f75507dd8f60dbf9f3dc79e9197
parentbac72cf7cf823bbf10e7d093a8225490bf8d1350 (diff)
downloadrust-0380321e7806bdab232d7e95be2de47fad8f3c09.tar.gz
rust-0380321e7806bdab232d7e95be2de47fad8f3c09.zip
Add unsafe_extern_blocks feature flag
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs36
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs7
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.rs5
-rw-r--r--tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr8
-rw-r--r--tests/ui/parser/unsafe-foreign-mod-2.rs2
-rw-r--r--tests/ui/parser/unsafe-foreign-mod-2.stderr17
-rw-r--r--tests/ui/parser/unsafe-foreign-mod.rs6
-rw-r--r--tests/ui/parser/unsafe-foreign-mod.stderr8
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2021.stderr4
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2024.stderr4
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.rs2
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/extern-items.edition2024.stderr8
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs6
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/safe-items.rs2
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2021.stderr4
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2024.stderr4
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.rs2
-rw-r--r--tests/ui/unpretty/expanded-exhaustive.rs1
-rw-r--r--tests/ui/unpretty/expanded-exhaustive.stdout1
21 files changed, 93 insertions, 37 deletions
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index a9f06230faf..dc554ba04df 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -440,16 +440,14 @@ impl<'a> AstValidator<'a> {
     }
 
     fn check_foreign_item_safety(&self, item_span: Span, safety: Safety) {
-        match safety {
-            Safety::Unsafe(_) | Safety::Safe(_)
-                if self.extern_mod_safety == Some(Safety::Default) =>
-            {
-                self.dcx().emit_err(errors::InvalidSafetyOnExtern {
-                    item_span,
-                    block: self.current_extern_span(),
-                });
-            }
-            _ => {}
+        if matches!(safety, Safety::Unsafe(_) | Safety::Safe(_))
+            && (self.extern_mod_safety == Some(Safety::Default)
+                || !self.features.unsafe_extern_blocks)
+        {
+            self.dcx().emit_err(errors::InvalidSafetyOnExtern {
+                item_span,
+                block: self.current_extern_span(),
+            });
         }
     }
 
@@ -1044,13 +1042,17 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                         errors::VisibilityNotPermittedNote::IndividualForeignItems,
                     );
 
-                    if &Safety::Default == safety {
-                        this.lint_buffer.buffer_lint(
-                            MISSING_UNSAFE_ON_EXTERN,
-                            item.id,
-                            item.span,
-                            BuiltinLintDiag::MissingUnsafeOnExtern,
-                        );
+                    if this.features.unsafe_extern_blocks {
+                        if &Safety::Default == safety {
+                            this.lint_buffer.buffer_lint(
+                                MISSING_UNSAFE_ON_EXTERN,
+                                item.id,
+                                item.span,
+                                BuiltinLintDiag::MissingUnsafeOnExtern,
+                            );
+                        }
+                    } else if let &Safety::Unsafe(span) = safety {
+                        this.dcx().emit_err(errors::UnsafeItem { span, kind: "extern block" });
                     }
 
                     if abi.is_none() {
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 8de2cdefa81..486de706e52 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -624,6 +624,8 @@ declare_features! (
     (unstable, type_changing_struct_update, "1.58.0", Some(86555)),
     /// Allows unnamed fields of struct and union type
     (incomplete, unnamed_fields, "1.74.0", Some(49804)),
+    /// Allows unsafe on extern declarations and safety qualifiers over internal items.
+    (unstable, unsafe_extern_blocks, "CURRENT_RUSTC_VERSION", Some(123743)),
     /// Allows unsized fn parameters.
     (unstable, unsized_fn_params, "1.49.0", Some(48055)),
     /// Allows unsized rvalues at arguments and parameters.
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index b4a34b1407d..ec124c3224c 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -4858,7 +4858,10 @@ declare_lint! {
     ///
     /// ### Example
     ///
-    /// ```rust,edition2024
+    /// ```rust,edition2024,ignore
+    /// #![feature(unsafe_extern_blocks)]
+    /// #![allow(dead_code)]
+    ///
     /// extern "C" {
     ///     fn foo(_: i32);
     /// }
@@ -4880,5 +4883,5 @@ declare_lint! {
     pub MISSING_UNSAFE_ON_EXTERN,
     Allow,
     "detects missing unsafe keyword on extern declarations",
-    @edition Edition2024 => Warn;
+    @edition Edition2024 => Deny;
 }
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index ede9b852ba8..f1933806c01 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1965,6 +1965,7 @@ symbols! {
         unsafe_block_in_unsafe_fn,
         unsafe_cell,
         unsafe_cell_raw_get,
+        unsafe_extern_blocks,
         unsafe_no_drop_flag,
         unsafe_pin_internals,
         unsize,
diff --git a/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.rs b/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.rs
new file mode 100644
index 00000000000..eab134a4a4d
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.rs
@@ -0,0 +1,5 @@
+unsafe extern "C" {
+    //~^ ERROR extern block cannot be declared unsafe
+}
+
+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
new file mode 100644
index 00000000000..7e9b199a2db
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr
@@ -0,0 +1,8 @@
+error: extern block cannot be declared unsafe
+  --> $DIR/feature-gate-unsafe-extern-blocks.rs:1:1
+   |
+LL | unsafe extern "C" {
+   | ^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/unsafe-foreign-mod-2.rs b/tests/ui/parser/unsafe-foreign-mod-2.rs
index 6d339cd9088..0b63a993c5b 100644
--- a/tests/ui/parser/unsafe-foreign-mod-2.rs
+++ b/tests/ui/parser/unsafe-foreign-mod-2.rs
@@ -1,6 +1,8 @@
 extern "C" unsafe {
     //~^ ERROR expected `{`, found keyword `unsafe`
+    //~| ERROR extern block cannot be declared unsafe
     unsafe fn foo();
+    //~^ ERROR items in unadorned `extern` blocks cannot have safety qualifiers
 }
 
 fn main() {}
diff --git a/tests/ui/parser/unsafe-foreign-mod-2.stderr b/tests/ui/parser/unsafe-foreign-mod-2.stderr
index 0625e3362ed..e59352395ed 100644
--- a/tests/ui/parser/unsafe-foreign-mod-2.stderr
+++ b/tests/ui/parser/unsafe-foreign-mod-2.stderr
@@ -4,5 +4,20 @@ error: expected `{`, found keyword `unsafe`
 LL | extern "C" unsafe {
    |            ^^^^^^ expected `{`
 
-error: aborting due to 1 previous error
+error: extern block cannot be declared unsafe
+  --> $DIR/unsafe-foreign-mod-2.rs:1:12
+   |
+LL | extern "C" unsafe {
+   |            ^^^^^^
+
+error: items in unadorned `extern` blocks cannot have safety qualifiers
+  --> $DIR/unsafe-foreign-mod-2.rs:4:5
+   |
+LL | extern "C" unsafe {
+   | ----------------- help: add unsafe to this `extern` block
+...
+LL |     unsafe fn foo();
+   |     ^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
 
diff --git a/tests/ui/parser/unsafe-foreign-mod.rs b/tests/ui/parser/unsafe-foreign-mod.rs
index 26015a3c444..eab134a4a4d 100644
--- a/tests/ui/parser/unsafe-foreign-mod.rs
+++ b/tests/ui/parser/unsafe-foreign-mod.rs
@@ -1,5 +1,5 @@
-//@ build-pass
-
-unsafe extern "C" {}
+unsafe extern "C" {
+    //~^ ERROR extern block cannot be declared unsafe
+}
 
 fn main() {}
diff --git a/tests/ui/parser/unsafe-foreign-mod.stderr b/tests/ui/parser/unsafe-foreign-mod.stderr
new file mode 100644
index 00000000000..77f6e93be10
--- /dev/null
+++ b/tests/ui/parser/unsafe-foreign-mod.stderr
@@ -0,0 +1,8 @@
+error: extern block cannot be declared unsafe
+  --> $DIR/unsafe-foreign-mod.rs:1:1
+   |
+LL | unsafe extern "C" {
+   | ^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2021.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2021.stderr
index 77554da10e6..3a99caa719b 100644
--- a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2021.stderr
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2021.stderr
@@ -1,5 +1,5 @@
 error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe function or block
-  --> $DIR/extern-items-unsafe.rs:12:5
+  --> $DIR/extern-items-unsafe.rs:14:5
    |
 LL |     test1(TEST1);
    |     ^^^^^^^^^^^^ call to unsafe function
@@ -7,7 +7,7 @@ LL |     test1(TEST1);
    = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error[E0133]: use of extern static is unsafe and requires unsafe function or block
-  --> $DIR/extern-items-unsafe.rs:12:11
+  --> $DIR/extern-items-unsafe.rs:14:11
    |
 LL |     test1(TEST1);
    |           ^^^^^ use of extern static
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2024.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2024.stderr
index 33b752782d5..fcf937b7ac5 100644
--- a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2024.stderr
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2024.stderr
@@ -1,5 +1,5 @@
 error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe block
-  --> $DIR/extern-items-unsafe.rs:12:5
+  --> $DIR/extern-items-unsafe.rs:14:5
    |
 LL |     test1(TEST1);
    |     ^^^^^^^^^^^^ call to unsafe function
@@ -7,7 +7,7 @@ LL |     test1(TEST1);
    = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error[E0133]: use of extern static is unsafe and requires unsafe block
-  --> $DIR/extern-items-unsafe.rs:12:11
+  --> $DIR/extern-items-unsafe.rs:14:11
    |
 LL |     test1(TEST1);
    |           ^^^^^ use of extern static
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.rs b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.rs
index 721e07acca5..ad569a256db 100644
--- a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.rs
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.rs
@@ -3,6 +3,8 @@
 //@[edition2024] edition:2024
 //@[edition2024] compile-flags: -Zunstable-options
 
+#![feature(unsafe_extern_blocks)]
+
 unsafe extern "C" {
     static TEST1: i32;
     fn test1(i: i32);
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.edition2024.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.edition2024.stderr
index b19369c0a55..8e1ec814635 100644
--- a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.edition2024.stderr
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.edition2024.stderr
@@ -1,5 +1,5 @@
-warning: extern blocks should be unsafe
-  --> $DIR/extern-items.rs:7:1
+error: extern blocks should be unsafe
+  --> $DIR/extern-items.rs:9:1
    |
 LL | / extern "C" {
 LL | |
@@ -8,7 +8,7 @@ LL | |     fn test1(i: i32);
 LL | | }
    | |_^
    |
-   = note: `#[warn(missing_unsafe_on_extern)]` on by default
+   = note: `#[deny(missing_unsafe_on_extern)]` on by default
 
-warning: 1 warning emitted
+error: aborting due to 1 previous error
 
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs
index dfb851e276d..905d1434155 100644
--- a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs
@@ -1,11 +1,13 @@
 //@ revisions: edition2021 edition2024
 //@[edition2021] edition:2021
+//@[edition2021] check-pass
 //@[edition2024] edition:2024
 //@[edition2024] compile-flags: -Zunstable-options
-//@ check-pass
+
+#![feature(unsafe_extern_blocks)]
 
 extern "C" {
-    //[edition2024]~^ WARN extern blocks should be unsafe [missing_unsafe_on_extern]
+    //[edition2024]~^ ERROR extern blocks should be unsafe
     static TEST1: i32;
     fn test1(i: i32);
 }
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/safe-items.rs b/tests/ui/rust-2024/unsafe-extern-blocks/safe-items.rs
index b0b8a8b012a..74cd5621fce 100644
--- a/tests/ui/rust-2024/unsafe-extern-blocks/safe-items.rs
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/safe-items.rs
@@ -4,6 +4,8 @@
 //@[edition2024] compile-flags: -Zunstable-options
 //@ check-pass
 
+#![feature(unsafe_extern_blocks)]
+
 unsafe extern "C" {
     safe static TEST1: i32;
     safe fn test1(i: i32);
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2021.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2021.stderr
index e3626bb497e..8bb7ffefeea 100644
--- a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2021.stderr
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2021.stderr
@@ -1,5 +1,5 @@
 error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe function or block
-  --> $DIR/unsafe-items.rs:18:5
+  --> $DIR/unsafe-items.rs:20:5
    |
 LL |     test1(TEST1);
    |     ^^^^^^^^^^^^ call to unsafe function
@@ -7,7 +7,7 @@ LL |     test1(TEST1);
    = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error[E0133]: use of extern static is unsafe and requires unsafe function or block
-  --> $DIR/unsafe-items.rs:18:11
+  --> $DIR/unsafe-items.rs:20:11
    |
 LL |     test1(TEST1);
    |           ^^^^^ use of extern static
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2024.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2024.stderr
index 89bc501b7b5..9a30142a632 100644
--- a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2024.stderr
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2024.stderr
@@ -1,5 +1,5 @@
 error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe block
-  --> $DIR/unsafe-items.rs:18:5
+  --> $DIR/unsafe-items.rs:20:5
    |
 LL |     test1(TEST1);
    |     ^^^^^^^^^^^^ call to unsafe function
@@ -7,7 +7,7 @@ LL |     test1(TEST1);
    = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error[E0133]: use of extern static is unsafe and requires unsafe block
-  --> $DIR/unsafe-items.rs:18:11
+  --> $DIR/unsafe-items.rs:20:11
    |
 LL |     test1(TEST1);
    |           ^^^^^ use of extern static
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.rs b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.rs
index dc2bae892a9..9066953abc6 100644
--- a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.rs
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.rs
@@ -3,6 +3,8 @@
 //@[edition2024] edition:2024
 //@[edition2024] compile-flags: -Zunstable-options
 
+#![feature(unsafe_extern_blocks)]
+
 unsafe extern "C" {
     unsafe static TEST1: i32;
     unsafe fn test1(i: i32);
diff --git a/tests/ui/unpretty/expanded-exhaustive.rs b/tests/ui/unpretty/expanded-exhaustive.rs
index 29472df897a..92c2e7b4884 100644
--- a/tests/ui/unpretty/expanded-exhaustive.rs
+++ b/tests/ui/unpretty/expanded-exhaustive.rs
@@ -25,6 +25,7 @@
 #![feature(trait_alias)]
 #![feature(try_blocks)]
 #![feature(unnamed_fields)]
+#![feature(unsafe_extern_blocks)]
 #![feature(yeet_expr)]
 #![allow(incomplete_features)]
 
diff --git a/tests/ui/unpretty/expanded-exhaustive.stdout b/tests/ui/unpretty/expanded-exhaustive.stdout
index 0a09a3f6a42..9e45f57af35 100644
--- a/tests/ui/unpretty/expanded-exhaustive.stdout
+++ b/tests/ui/unpretty/expanded-exhaustive.stdout
@@ -26,6 +26,7 @@
 #![feature(trait_alias)]
 #![feature(try_blocks)]
 #![feature(unnamed_fields)]
+#![feature(unsafe_extern_blocks)]
 #![feature(yeet_expr)]
 #![allow(incomplete_features)]
 #[prelude_import]