Skip to content

Commit 0380321

Browse files
committed
Add unsafe_extern_blocks feature flag
1 parent bac72cf commit 0380321

21 files changed

+93
-37
lines changed

Diff for: compiler/rustc_ast_passes/src/ast_validation.rs

+19-17
Original file line numberDiff line numberDiff line change
@@ -440,16 +440,14 @@ impl<'a> AstValidator<'a> {
440440
}
441441

442442
fn check_foreign_item_safety(&self, item_span: Span, safety: Safety) {
443-
match safety {
444-
Safety::Unsafe(_) | Safety::Safe(_)
445-
if self.extern_mod_safety == Some(Safety::Default) =>
446-
{
447-
self.dcx().emit_err(errors::InvalidSafetyOnExtern {
448-
item_span,
449-
block: self.current_extern_span(),
450-
});
451-
}
452-
_ => {}
443+
if matches!(safety, Safety::Unsafe(_) | Safety::Safe(_))
444+
&& (self.extern_mod_safety == Some(Safety::Default)
445+
|| !self.features.unsafe_extern_blocks)
446+
{
447+
self.dcx().emit_err(errors::InvalidSafetyOnExtern {
448+
item_span,
449+
block: self.current_extern_span(),
450+
});
453451
}
454452
}
455453

@@ -1044,13 +1042,17 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
10441042
errors::VisibilityNotPermittedNote::IndividualForeignItems,
10451043
);
10461044

1047-
if &Safety::Default == safety {
1048-
this.lint_buffer.buffer_lint(
1049-
MISSING_UNSAFE_ON_EXTERN,
1050-
item.id,
1051-
item.span,
1052-
BuiltinLintDiag::MissingUnsafeOnExtern,
1053-
);
1045+
if this.features.unsafe_extern_blocks {
1046+
if &Safety::Default == safety {
1047+
this.lint_buffer.buffer_lint(
1048+
MISSING_UNSAFE_ON_EXTERN,
1049+
item.id,
1050+
item.span,
1051+
BuiltinLintDiag::MissingUnsafeOnExtern,
1052+
);
1053+
}
1054+
} else if let &Safety::Unsafe(span) = safety {
1055+
this.dcx().emit_err(errors::UnsafeItem { span, kind: "extern block" });
10541056
}
10551057

10561058
if abi.is_none() {

Diff for: compiler/rustc_feature/src/unstable.rs

+2
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,8 @@ declare_features! (
624624
(unstable, type_changing_struct_update, "1.58.0", Some(86555)),
625625
/// Allows unnamed fields of struct and union type
626626
(incomplete, unnamed_fields, "1.74.0", Some(49804)),
627+
/// Allows unsafe on extern declarations and safety qualifiers over internal items.
628+
(unstable, unsafe_extern_blocks, "CURRENT_RUSTC_VERSION", Some(123743)),
627629
/// Allows unsized fn parameters.
628630
(unstable, unsized_fn_params, "1.49.0", Some(48055)),
629631
/// Allows unsized rvalues at arguments and parameters.

Diff for: compiler/rustc_lint_defs/src/builtin.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -4858,7 +4858,10 @@ declare_lint! {
48584858
///
48594859
/// ### Example
48604860
///
4861-
/// ```rust,edition2024
4861+
/// ```rust,edition2024,ignore
4862+
/// #![feature(unsafe_extern_blocks)]
4863+
/// #![allow(dead_code)]
4864+
///
48624865
/// extern "C" {
48634866
/// fn foo(_: i32);
48644867
/// }
@@ -4880,5 +4883,5 @@ declare_lint! {
48804883
pub MISSING_UNSAFE_ON_EXTERN,
48814884
Allow,
48824885
"detects missing unsafe keyword on extern declarations",
4883-
@edition Edition2024 => Warn;
4886+
@edition Edition2024 => Deny;
48844887
}

Diff for: compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1965,6 +1965,7 @@ symbols! {
19651965
unsafe_block_in_unsafe_fn,
19661966
unsafe_cell,
19671967
unsafe_cell_raw_get,
1968+
unsafe_extern_blocks,
19681969
unsafe_no_drop_flag,
19691970
unsafe_pin_internals,
19701971
unsize,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
unsafe extern "C" {
2+
//~^ ERROR extern block cannot be declared unsafe
3+
}
4+
5+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: extern block cannot be declared unsafe
2+
--> $DIR/feature-gate-unsafe-extern-blocks.rs:1:1
3+
|
4+
LL | unsafe extern "C" {
5+
| ^^^^^^
6+
7+
error: aborting due to 1 previous error
8+

Diff for: tests/ui/parser/unsafe-foreign-mod-2.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
extern "C" unsafe {
22
//~^ ERROR expected `{`, found keyword `unsafe`
3+
//~| ERROR extern block cannot be declared unsafe
34
unsafe fn foo();
5+
//~^ ERROR items in unadorned `extern` blocks cannot have safety qualifiers
46
}
57

68
fn main() {}

Diff for: tests/ui/parser/unsafe-foreign-mod-2.stderr

+16-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,20 @@ error: expected `{`, found keyword `unsafe`
44
LL | extern "C" unsafe {
55
| ^^^^^^ expected `{`
66

7-
error: aborting due to 1 previous error
7+
error: extern block cannot be declared unsafe
8+
--> $DIR/unsafe-foreign-mod-2.rs:1:12
9+
|
10+
LL | extern "C" unsafe {
11+
| ^^^^^^
12+
13+
error: items in unadorned `extern` blocks cannot have safety qualifiers
14+
--> $DIR/unsafe-foreign-mod-2.rs:4:5
15+
|
16+
LL | extern "C" unsafe {
17+
| ----------------- help: add unsafe to this `extern` block
18+
...
19+
LL | unsafe fn foo();
20+
| ^^^^^^^^^^^^^^^^
21+
22+
error: aborting due to 3 previous errors
823

Diff for: tests/ui/parser/unsafe-foreign-mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
//@ build-pass
2-
3-
unsafe extern "C" {}
1+
unsafe extern "C" {
2+
//~^ ERROR extern block cannot be declared unsafe
3+
}
44

55
fn main() {}

Diff for: tests/ui/parser/unsafe-foreign-mod.stderr

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: extern block cannot be declared unsafe
2+
--> $DIR/unsafe-foreign-mod.rs:1:1
3+
|
4+
LL | unsafe extern "C" {
5+
| ^^^^^^
6+
7+
error: aborting due to 1 previous error
8+

Diff for: tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2021.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe function or block
2-
--> $DIR/extern-items-unsafe.rs:12:5
2+
--> $DIR/extern-items-unsafe.rs:14:5
33
|
44
LL | test1(TEST1);
55
| ^^^^^^^^^^^^ call to unsafe function
66
|
77
= note: consult the function's documentation for information on how to avoid undefined behavior
88

99
error[E0133]: use of extern static is unsafe and requires unsafe function or block
10-
--> $DIR/extern-items-unsafe.rs:12:11
10+
--> $DIR/extern-items-unsafe.rs:14:11
1111
|
1212
LL | test1(TEST1);
1313
| ^^^^^ use of extern static

Diff for: tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2024.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe block
2-
--> $DIR/extern-items-unsafe.rs:12:5
2+
--> $DIR/extern-items-unsafe.rs:14:5
33
|
44
LL | test1(TEST1);
55
| ^^^^^^^^^^^^ call to unsafe function
66
|
77
= note: consult the function's documentation for information on how to avoid undefined behavior
88

99
error[E0133]: use of extern static is unsafe and requires unsafe block
10-
--> $DIR/extern-items-unsafe.rs:12:11
10+
--> $DIR/extern-items-unsafe.rs:14:11
1111
|
1212
LL | test1(TEST1);
1313
| ^^^^^ use of extern static

Diff for: tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.rs

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
//@[edition2024] edition:2024
44
//@[edition2024] compile-flags: -Zunstable-options
55

6+
#![feature(unsafe_extern_blocks)]
7+
68
unsafe extern "C" {
79
static TEST1: i32;
810
fn test1(i: i32);
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
warning: extern blocks should be unsafe
2-
--> $DIR/extern-items.rs:7:1
1+
error: extern blocks should be unsafe
2+
--> $DIR/extern-items.rs:9:1
33
|
44
LL | / extern "C" {
55
LL | |
@@ -8,7 +8,7 @@ LL | | fn test1(i: i32);
88
LL | | }
99
| |_^
1010
|
11-
= note: `#[warn(missing_unsafe_on_extern)]` on by default
11+
= note: `#[deny(missing_unsafe_on_extern)]` on by default
1212

13-
warning: 1 warning emitted
13+
error: aborting due to 1 previous error
1414

Diff for: tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
//@ revisions: edition2021 edition2024
22
//@[edition2021] edition:2021
3+
//@[edition2021] check-pass
34
//@[edition2024] edition:2024
45
//@[edition2024] compile-flags: -Zunstable-options
5-
//@ check-pass
6+
7+
#![feature(unsafe_extern_blocks)]
68

79
extern "C" {
8-
//[edition2024]~^ WARN extern blocks should be unsafe [missing_unsafe_on_extern]
10+
//[edition2024]~^ ERROR extern blocks should be unsafe
911
static TEST1: i32;
1012
fn test1(i: i32);
1113
}

Diff for: tests/ui/rust-2024/unsafe-extern-blocks/safe-items.rs

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
//@[edition2024] compile-flags: -Zunstable-options
55
//@ check-pass
66

7+
#![feature(unsafe_extern_blocks)]
8+
79
unsafe extern "C" {
810
safe static TEST1: i32;
911
safe fn test1(i: i32);

Diff for: tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2021.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe function or block
2-
--> $DIR/unsafe-items.rs:18:5
2+
--> $DIR/unsafe-items.rs:20:5
33
|
44
LL | test1(TEST1);
55
| ^^^^^^^^^^^^ call to unsafe function
66
|
77
= note: consult the function's documentation for information on how to avoid undefined behavior
88

99
error[E0133]: use of extern static is unsafe and requires unsafe function or block
10-
--> $DIR/unsafe-items.rs:18:11
10+
--> $DIR/unsafe-items.rs:20:11
1111
|
1212
LL | test1(TEST1);
1313
| ^^^^^ use of extern static

Diff for: tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2024.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe block
2-
--> $DIR/unsafe-items.rs:18:5
2+
--> $DIR/unsafe-items.rs:20:5
33
|
44
LL | test1(TEST1);
55
| ^^^^^^^^^^^^ call to unsafe function
66
|
77
= note: consult the function's documentation for information on how to avoid undefined behavior
88

99
error[E0133]: use of extern static is unsafe and requires unsafe block
10-
--> $DIR/unsafe-items.rs:18:11
10+
--> $DIR/unsafe-items.rs:20:11
1111
|
1212
LL | test1(TEST1);
1313
| ^^^^^ use of extern static

Diff for: tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.rs

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
//@[edition2024] edition:2024
44
//@[edition2024] compile-flags: -Zunstable-options
55

6+
#![feature(unsafe_extern_blocks)]
7+
68
unsafe extern "C" {
79
unsafe static TEST1: i32;
810
unsafe fn test1(i: i32);

Diff for: tests/ui/unpretty/expanded-exhaustive.rs

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#![feature(trait_alias)]
2626
#![feature(try_blocks)]
2727
#![feature(unnamed_fields)]
28+
#![feature(unsafe_extern_blocks)]
2829
#![feature(yeet_expr)]
2930
#![allow(incomplete_features)]
3031

Diff for: tests/ui/unpretty/expanded-exhaustive.stdout

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#![feature(trait_alias)]
2727
#![feature(try_blocks)]
2828
#![feature(unnamed_fields)]
29+
#![feature(unsafe_extern_blocks)]
2930
#![feature(yeet_expr)]
3031
#![allow(incomplete_features)]
3132
#[prelude_import]

0 commit comments

Comments
 (0)