Skip to content

Commit 8e21e78

Browse files
committedJul 18, 2024
Stabilize unsafe extern blocks (RFC 3484)
1 parent b01a977 commit 8e21e78

40 files changed

+86
-139
lines changed
 

‎compiler/rustc_ast_passes/src/ast_validation.rs

+12-30
Original file line numberDiff line numberDiff line change
@@ -447,11 +447,6 @@ impl<'a> AstValidator<'a> {
447447
item_span: span,
448448
block: Some(self.current_extern_span().shrink_to_lo()),
449449
});
450-
} else if !self.features.unsafe_extern_blocks {
451-
self.dcx().emit_err(errors::InvalidSafetyOnExtern {
452-
item_span: span,
453-
block: None,
454-
});
455450
}
456451
}
457452
}
@@ -1048,32 +1043,19 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
10481043
errors::VisibilityNotPermittedNote::IndividualForeignItems,
10491044
);
10501045

1051-
if this.features.unsafe_extern_blocks {
1052-
if &Safety::Default == safety {
1053-
if item.span.at_least_rust_2024() {
1054-
this.dcx()
1055-
.emit_err(errors::MissingUnsafeOnExtern { span: item.span });
1056-
} else {
1057-
this.lint_buffer.buffer_lint(
1058-
MISSING_UNSAFE_ON_EXTERN,
1059-
item.id,
1060-
item.span,
1061-
BuiltinLintDiag::MissingUnsafeOnExtern {
1062-
suggestion: item.span.shrink_to_lo(),
1063-
},
1064-
);
1065-
}
1046+
if &Safety::Default == safety {
1047+
if item.span.at_least_rust_2024() {
1048+
this.dcx().emit_err(errors::MissingUnsafeOnExtern { span: item.span });
1049+
} else {
1050+
this.lint_buffer.buffer_lint(
1051+
MISSING_UNSAFE_ON_EXTERN,
1052+
item.id,
1053+
item.span,
1054+
BuiltinLintDiag::MissingUnsafeOnExtern {
1055+
suggestion: item.span.shrink_to_lo(),
1056+
},
1057+
);
10661058
}
1067-
} else if let &Safety::Unsafe(span) = safety {
1068-
let mut diag = this
1069-
.dcx()
1070-
.create_err(errors::UnsafeItem { span, kind: "extern block" });
1071-
rustc_session::parse::add_feature_diagnostics(
1072-
&mut diag,
1073-
self.session,
1074-
sym::unsafe_extern_blocks,
1075-
);
1076-
diag.emit();
10771059
}
10781060

10791061
if abi.is_none() {

‎compiler/rustc_ast_passes/src/feature_gate.rs

-4
Original file line numberDiff line numberDiff line change
@@ -545,10 +545,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
545545
gate_all!(precise_capturing, "precise captures on `impl Trait` are experimental");
546546
gate_all!(global_registration, "global registration is experimental");
547547
gate_all!(unsafe_attributes, "`#[unsafe()]` markers for attributes are experimental");
548-
gate_all!(
549-
unsafe_extern_blocks,
550-
"`unsafe extern {}` blocks and `safe` keyword are experimental"
551-
);
552548
gate_all!(return_type_notation, "return type notation is experimental");
553549

554550
if !visitor.features.never_patterns {

‎compiler/rustc_feature/src/accepted.rs

+2
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,8 @@ declare_features! (
387387
(accepted, unrestricted_attribute_tokens, "1.34.0", Some(55208)),
388388
/// The `unsafe_op_in_unsafe_fn` lint (allowed by default): no longer treat an unsafe function as an unsafe block.
389389
(accepted, unsafe_block_in_unsafe_fn, "1.52.0", Some(71668)),
390+
/// Allows unsafe on extern declarations and safety qualifiers over internal items.
391+
(accepted, unsafe_extern_blocks, "CURRENT_RUSTC_VERSION", Some(123743)),
390392
/// Allows importing and reexporting macros with `use`,
391393
/// enables macro modularization in general.
392394
(accepted, use_extern_macros, "1.30.0", Some(35896)),

‎compiler/rustc_feature/src/unstable.rs

-2
Original file line numberDiff line numberDiff line change
@@ -628,8 +628,6 @@ declare_features! (
628628
(incomplete, unnamed_fields, "1.74.0", Some(49804)),
629629
/// Allows unsafe attributes.
630630
(unstable, unsafe_attributes, "1.80.0", Some(123757)),
631-
/// Allows unsafe on extern declarations and safety qualifiers over internal items.
632-
(unstable, unsafe_extern_blocks, "1.80.0", Some(123743)),
633631
/// Allows unsized fn parameters.
634632
(internal, unsized_fn_params, "1.49.0", Some(48055)),
635633
/// Allows unsized rvalues at arguments and parameters.

‎compiler/rustc_lint_defs/src/builtin.rs

-1
Original file line numberDiff line numberDiff line change
@@ -4865,7 +4865,6 @@ declare_lint! {
48654865
/// ### Example
48664866
///
48674867
/// ```rust
4868-
/// #![feature(unsafe_extern_blocks)]
48694868
/// #![warn(missing_unsafe_on_extern)]
48704869
/// #![allow(dead_code)]
48714870
///

‎compiler/rustc_parse/src/parser/mod.rs

-3
Original file line numberDiff line numberDiff line change
@@ -1199,9 +1199,6 @@ impl<'a> Parser<'a> {
11991199
if self.eat_keyword_case(kw::Unsafe, case) {
12001200
Safety::Unsafe(self.prev_token.uninterpolated_span())
12011201
} else if self.eat_keyword_case(kw::Safe, case) {
1202-
self.psess
1203-
.gated_spans
1204-
.gate(sym::unsafe_extern_blocks, self.prev_token.uninterpolated_span());
12051202
Safety::Safe(self.prev_token.uninterpolated_span())
12061203
} else {
12071204
Safety::Default

‎tests/rustdoc/unsafe-extern-blocks.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// Test to ensure the feature is working as expected.
22

3-
#![feature(unsafe_extern_blocks)]
43
#![crate_name = "foo"]
54

65
// @has 'foo/index.html'
@@ -13,7 +12,7 @@
1312
// @count - '//ul[@class="item-table"]//sup[@title="unsafe function"]' 1
1413
// @has - '//ul[@class="item-table"]//sup[@title="unsafe function"]' '⚠'
1514

16-
unsafe extern {
15+
unsafe extern "C" {
1716
// @has 'foo/static.FOO.html'
1817
// @has - '//pre[@class="rust item-decl"]' 'pub static FOO: i32'
1918
pub safe static FOO: i32;

‎tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.rs

-13
This file was deleted.

‎tests/ui/lint/unsafe_code/unsafe-extern-blocks.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#![feature(unsafe_extern_blocks)]
21
#![deny(unsafe_code)]
32

43
#[allow(unsafe_code)]

‎tests/ui/lint/unsafe_code/unsafe-extern-blocks.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: usage of an `unsafe extern` block
2-
--> $DIR/unsafe-extern-blocks.rs:9:1
2+
--> $DIR/unsafe-extern-blocks.rs:8:1
33
|
44
LL | / unsafe extern "C" {
55
LL | |
@@ -8,7 +8,7 @@ LL | | }
88
| |_^
99
|
1010
note: the lint level is defined here
11-
--> $DIR/unsafe-extern-blocks.rs:2:9
11+
--> $DIR/unsafe-extern-blocks.rs:1:9
1212
|
1313
LL | #![deny(unsafe_code)]
1414
| ^^^^^^^^^^^
-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
extern "C" unsafe {
22
//~^ ERROR expected `{`, found keyword `unsafe`
3-
//~| ERROR extern block cannot be declared unsafe
43
unsafe fn foo();
5-
//~^ ERROR items in unadorned `extern` blocks cannot have safety qualifiers
64
}
75

86
fn main() {}

‎tests/ui/parser/unsafe-foreign-mod-2.stderr

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

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-
= note: see issue #123743 <https://github.com/rust-lang/rust/issues/123743> for more information
14-
= help: add `#![feature(unsafe_extern_blocks)]` to the crate attributes to enable
15-
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
16-
17-
error: items in unadorned `extern` blocks cannot have safety qualifiers
18-
--> $DIR/unsafe-foreign-mod-2.rs:4:5
19-
|
20-
LL | unsafe fn foo();
21-
| ^^^^^^^^^^^^^^^^
22-
23-
error: aborting due to 3 previous errors
7+
error: aborting due to 1 previous error
248

‎tests/ui/parser/unsafe-foreign-mod.rs

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

55
fn main() {}

‎tests/ui/parser/unsafe-foreign-mod.stderr

-12
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,20 @@
1-
//@ revisions: gated ungated
2-
#![cfg_attr(gated, feature(unsafe_extern_blocks))]
3-
41
safe fn foo() {}
52
//~^ ERROR: items outside of `unsafe extern { }` cannot be declared with `safe` safety qualifier
6-
//[ungated]~| ERROR: unsafe extern {}` blocks and `safe` keyword are experimental [E0658]
73

84
safe static FOO: i32 = 1;
95
//~^ ERROR: items outside of `unsafe extern { }` cannot be declared with `safe` safety qualifier
10-
//[ungated]~| ERROR: unsafe extern {}` blocks and `safe` keyword are experimental [E0658]
116

127
trait Foo {
138
safe fn foo();
149
//~^ ERROR: items outside of `unsafe extern { }` cannot be declared with `safe` safety qualifier
15-
//[ungated]~| ERROR: unsafe extern {}` blocks and `safe` keyword are experimental [E0658]
1610
}
1711

1812
impl Foo for () {
1913
safe fn foo() {}
2014
//~^ ERROR: items outside of `unsafe extern { }` cannot be declared with `safe` safety qualifier
21-
//[ungated]~| ERROR: unsafe extern {}` blocks and `safe` keyword are experimental [E0658]
2215
}
2316

2417
type FnPtr = safe fn(i32, i32) -> i32;
2518
//~^ ERROR: function pointers cannot be declared with `safe` safety qualifier
26-
//[ungated]~| ERROR: unsafe extern {}` blocks and `safe` keyword are experimental [E0658]
2719

2820
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
error: items outside of `unsafe extern { }` cannot be declared with `safe` safety qualifier
2+
--> $DIR/safe-outside-extern.rs:1:1
3+
|
4+
LL | safe fn foo() {}
5+
| ^^^^^^^^^^^^^^^^
6+
7+
error: items outside of `unsafe extern { }` cannot be declared with `safe` safety qualifier
8+
--> $DIR/safe-outside-extern.rs:4:1
9+
|
10+
LL | safe static FOO: i32 = 1;
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error: items outside of `unsafe extern { }` cannot be declared with `safe` safety qualifier
14+
--> $DIR/safe-outside-extern.rs:8:5
15+
|
16+
LL | safe fn foo();
17+
| ^^^^^^^^^^^^^^
18+
19+
error: items outside of `unsafe extern { }` cannot be declared with `safe` safety qualifier
20+
--> $DIR/safe-outside-extern.rs:13:5
21+
|
22+
LL | safe fn foo() {}
23+
| ^^^^^^^^^^^^^^^^
24+
25+
error: function pointers cannot be declared with `safe` safety qualifier
26+
--> $DIR/safe-outside-extern.rs:17:14
27+
|
28+
LL | type FnPtr = safe fn(i32, i32) -> i32;
29+
| ^^^^^^^^^^^^^^^^^^^^^^^^
30+
31+
error: aborting due to 5 previous errors
32+

‎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:14:5
2+
--> $DIR/extern-items-unsafe.rs:12: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:14:11
10+
--> $DIR/extern-items-unsafe.rs:12:11
1111
|
1212
LL | test1(TEST1);
1313
| ^^^^^ use of extern static

‎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:14:5
2+
--> $DIR/extern-items-unsafe.rs:12: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:14:11
10+
--> $DIR/extern-items-unsafe.rs:12:11
1111
|
1212
LL | test1(TEST1);
1313
| ^^^^^ use of extern static

‎tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.rs

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

6-
#![feature(unsafe_extern_blocks)]
7-
86
unsafe extern "C" {
97
static TEST1: i32;
108
fn test1(i: i32);

‎tests/ui/rust-2024/unsafe-extern-blocks/extern-items.edition2024.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: extern blocks must be unsafe
2-
--> $DIR/extern-items.rs:9:1
2+
--> $DIR/extern-items.rs:7:1
33
|
44
LL | / extern "C" {
55
LL | |

‎tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs

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

7-
#![feature(unsafe_extern_blocks)]
8-
97
extern "C" {
108
//[edition2024]~^ ERROR extern blocks must be unsafe
119
static TEST1: i32;

‎tests/ui/rust-2024/unsafe-extern-blocks/safe-impl-trait.rs

-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
//@ revisions: gated ungated
2-
#![cfg_attr(gated, feature(unsafe_extern_blocks))]
3-
41
trait Bar {}
52
safe impl Bar for () { }
63
//~^ ERROR expected one of `!` or `::`, found keyword `impl`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: expected one of `!` or `::`, found keyword `impl`
2+
--> $DIR/safe-impl-trait.rs:2:6
3+
|
4+
LL | safe impl Bar for () { }
5+
| ^^^^ expected one of `!` or `::`
6+
7+
error: aborting due to 1 previous error
8+

‎tests/ui/rust-2024/unsafe-extern-blocks/safe-items.rs

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

7-
#![feature(unsafe_extern_blocks)]
8-
97
unsafe extern "C" {
108
safe static TEST1: i32;
119
safe fn test1(i: i32);

‎tests/ui/rust-2024/unsafe-extern-blocks/safe-trait.rs

-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
//@ revisions: gated ungated
2-
#![cfg_attr(gated, feature(unsafe_extern_blocks))]
3-
41
safe trait Foo {}
52
//~^ ERROR expected one of `!` or `::`, found keyword `trait`
63

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: expected one of `!` or `::`, found keyword `trait`
2+
--> $DIR/safe-trait.rs:1:6
3+
|
4+
LL | safe trait Foo {}
5+
| ^^^^^ expected one of `!` or `::`
6+
7+
error: aborting due to 1 previous error
8+

‎tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2021.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: items in unadorned `extern` blocks cannot have safety qualifiers
2-
--> $DIR/safe-unsafe-on-unadorned-extern-block.rs:10:5
2+
--> $DIR/safe-unsafe-on-unadorned-extern-block.rs:8:5
33
|
44
LL | safe static TEST1: i32;
55
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -10,7 +10,7 @@ LL | unsafe extern "C" {
1010
| ++++++
1111

1212
error: items in unadorned `extern` blocks cannot have safety qualifiers
13-
--> $DIR/safe-unsafe-on-unadorned-extern-block.rs:12:5
13+
--> $DIR/safe-unsafe-on-unadorned-extern-block.rs:10:5
1414
|
1515
LL | safe fn test1(i: i32);
1616
| ^^^^^^^^^^^^^^^^^^^^^^

0 commit comments

Comments
 (0)