Add unsafe_extern_blocks feature flag

This commit is contained in:
Santiago Pastorino 2024-05-31 16:57:07 -03:00
parent bac72cf7cf
commit 0380321e78
No known key found for this signature in database
GPG Key ID: 8131A24E0C79EFAF
21 changed files with 93 additions and 37 deletions

View File

@ -440,16 +440,14 @@ impl<'a> AstValidator<'a> {
} }
fn check_foreign_item_safety(&self, item_span: Span, safety: Safety) { fn check_foreign_item_safety(&self, item_span: Span, safety: Safety) {
match safety { if matches!(safety, Safety::Unsafe(_) | Safety::Safe(_))
Safety::Unsafe(_) | Safety::Safe(_) && (self.extern_mod_safety == Some(Safety::Default)
if self.extern_mod_safety == Some(Safety::Default) => || !self.features.unsafe_extern_blocks)
{ {
self.dcx().emit_err(errors::InvalidSafetyOnExtern { self.dcx().emit_err(errors::InvalidSafetyOnExtern {
item_span, item_span,
block: self.current_extern_span(), block: self.current_extern_span(),
}); });
}
_ => {}
} }
} }
@ -1044,13 +1042,17 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
errors::VisibilityNotPermittedNote::IndividualForeignItems, errors::VisibilityNotPermittedNote::IndividualForeignItems,
); );
if &Safety::Default == safety { if this.features.unsafe_extern_blocks {
this.lint_buffer.buffer_lint( if &Safety::Default == safety {
MISSING_UNSAFE_ON_EXTERN, this.lint_buffer.buffer_lint(
item.id, MISSING_UNSAFE_ON_EXTERN,
item.span, item.id,
BuiltinLintDiag::MissingUnsafeOnExtern, 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() { if abi.is_none() {

View File

@ -624,6 +624,8 @@ declare_features! (
(unstable, type_changing_struct_update, "1.58.0", Some(86555)), (unstable, type_changing_struct_update, "1.58.0", Some(86555)),
/// Allows unnamed fields of struct and union type /// Allows unnamed fields of struct and union type
(incomplete, unnamed_fields, "1.74.0", Some(49804)), (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. /// Allows unsized fn parameters.
(unstable, unsized_fn_params, "1.49.0", Some(48055)), (unstable, unsized_fn_params, "1.49.0", Some(48055)),
/// Allows unsized rvalues at arguments and parameters. /// Allows unsized rvalues at arguments and parameters.

View File

@ -4858,7 +4858,10 @@ declare_lint! {
/// ///
/// ### Example /// ### Example
/// ///
/// ```rust,edition2024 /// ```rust,edition2024,ignore
/// #![feature(unsafe_extern_blocks)]
/// #![allow(dead_code)]
///
/// extern "C" { /// extern "C" {
/// fn foo(_: i32); /// fn foo(_: i32);
/// } /// }
@ -4880,5 +4883,5 @@ declare_lint! {
pub MISSING_UNSAFE_ON_EXTERN, pub MISSING_UNSAFE_ON_EXTERN,
Allow, Allow,
"detects missing unsafe keyword on extern declarations", "detects missing unsafe keyword on extern declarations",
@edition Edition2024 => Warn; @edition Edition2024 => Deny;
} }

View File

@ -1965,6 +1965,7 @@ symbols! {
unsafe_block_in_unsafe_fn, unsafe_block_in_unsafe_fn,
unsafe_cell, unsafe_cell,
unsafe_cell_raw_get, unsafe_cell_raw_get,
unsafe_extern_blocks,
unsafe_no_drop_flag, unsafe_no_drop_flag,
unsafe_pin_internals, unsafe_pin_internals,
unsize, unsize,

View File

@ -0,0 +1,5 @@
unsafe extern "C" {
//~^ ERROR extern block cannot be declared unsafe
}
fn main() {}

View File

@ -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

View File

@ -1,6 +1,8 @@
extern "C" unsafe { extern "C" unsafe {
//~^ ERROR expected `{`, found keyword `unsafe` //~^ ERROR expected `{`, found keyword `unsafe`
//~| ERROR extern block cannot be declared unsafe
unsafe fn foo(); unsafe fn foo();
//~^ ERROR items in unadorned `extern` blocks cannot have safety qualifiers
} }
fn main() {} fn main() {}

View File

@ -4,5 +4,20 @@ error: expected `{`, found keyword `unsafe`
LL | extern "C" unsafe { LL | extern "C" unsafe {
| ^^^^^^ expected `{` | ^^^^^^ 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

View File

@ -1,5 +1,5 @@
//@ build-pass unsafe extern "C" {
//~^ ERROR extern block cannot be declared unsafe
unsafe extern "C" {} }
fn main() {} fn main() {}

View File

@ -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

View File

@ -1,5 +1,5 @@
error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe function or block 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); LL | test1(TEST1);
| ^^^^^^^^^^^^ call to unsafe function | ^^^^^^^^^^^^ 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 = 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 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); LL | test1(TEST1);
| ^^^^^ use of extern static | ^^^^^ use of extern static

View File

@ -1,5 +1,5 @@
error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe block 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); LL | test1(TEST1);
| ^^^^^^^^^^^^ call to unsafe function | ^^^^^^^^^^^^ 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 = 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 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); LL | test1(TEST1);
| ^^^^^ use of extern static | ^^^^^ use of extern static

View File

@ -3,6 +3,8 @@
//@[edition2024] edition:2024 //@[edition2024] edition:2024
//@[edition2024] compile-flags: -Zunstable-options //@[edition2024] compile-flags: -Zunstable-options
#![feature(unsafe_extern_blocks)]
unsafe extern "C" { unsafe extern "C" {
static TEST1: i32; static TEST1: i32;
fn test1(i: i32); fn test1(i: i32);

View File

@ -1,5 +1,5 @@
warning: extern blocks should be unsafe error: extern blocks should be unsafe
--> $DIR/extern-items.rs:7:1 --> $DIR/extern-items.rs:9:1
| |
LL | / extern "C" { LL | / extern "C" {
LL | | LL | |
@ -8,7 +8,7 @@ LL | | fn test1(i: i32);
LL | | } 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

View File

@ -1,11 +1,13 @@
//@ revisions: edition2021 edition2024 //@ revisions: edition2021 edition2024
//@[edition2021] edition:2021 //@[edition2021] edition:2021
//@[edition2021] check-pass
//@[edition2024] edition:2024 //@[edition2024] edition:2024
//@[edition2024] compile-flags: -Zunstable-options //@[edition2024] compile-flags: -Zunstable-options
//@ check-pass
#![feature(unsafe_extern_blocks)]
extern "C" { extern "C" {
//[edition2024]~^ WARN extern blocks should be unsafe [missing_unsafe_on_extern] //[edition2024]~^ ERROR extern blocks should be unsafe
static TEST1: i32; static TEST1: i32;
fn test1(i: i32); fn test1(i: i32);
} }

View File

@ -4,6 +4,8 @@
//@[edition2024] compile-flags: -Zunstable-options //@[edition2024] compile-flags: -Zunstable-options
//@ check-pass //@ check-pass
#![feature(unsafe_extern_blocks)]
unsafe extern "C" { unsafe extern "C" {
safe static TEST1: i32; safe static TEST1: i32;
safe fn test1(i: i32); safe fn test1(i: i32);

View File

@ -1,5 +1,5 @@
error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe function or block 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); LL | test1(TEST1);
| ^^^^^^^^^^^^ call to unsafe function | ^^^^^^^^^^^^ 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 = 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 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); LL | test1(TEST1);
| ^^^^^ use of extern static | ^^^^^ use of extern static

View File

@ -1,5 +1,5 @@
error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe block 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); LL | test1(TEST1);
| ^^^^^^^^^^^^ call to unsafe function | ^^^^^^^^^^^^ 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 = 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 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); LL | test1(TEST1);
| ^^^^^ use of extern static | ^^^^^ use of extern static

View File

@ -3,6 +3,8 @@
//@[edition2024] edition:2024 //@[edition2024] edition:2024
//@[edition2024] compile-flags: -Zunstable-options //@[edition2024] compile-flags: -Zunstable-options
#![feature(unsafe_extern_blocks)]
unsafe extern "C" { unsafe extern "C" {
unsafe static TEST1: i32; unsafe static TEST1: i32;
unsafe fn test1(i: i32); unsafe fn test1(i: i32);

View File

@ -25,6 +25,7 @@
#![feature(trait_alias)] #![feature(trait_alias)]
#![feature(try_blocks)] #![feature(try_blocks)]
#![feature(unnamed_fields)] #![feature(unnamed_fields)]
#![feature(unsafe_extern_blocks)]
#![feature(yeet_expr)] #![feature(yeet_expr)]
#![allow(incomplete_features)] #![allow(incomplete_features)]

View File

@ -26,6 +26,7 @@
#![feature(trait_alias)] #![feature(trait_alias)]
#![feature(try_blocks)] #![feature(try_blocks)]
#![feature(unnamed_fields)] #![feature(unnamed_fields)]
#![feature(unsafe_extern_blocks)]
#![feature(yeet_expr)] #![feature(yeet_expr)]
#![allow(incomplete_features)] #![allow(incomplete_features)]
#[prelude_import] #[prelude_import]