Skip to content

Commit 7d9ed2a

Browse files
authored
Rollup merge of #127921 - spastorino:stabilize-unsafe-extern-blocks, r=compiler-errors
Stabilize unsafe extern blocks (RFC 3484) # Stabilization report ## Summary This is a tracking issue for the RFC 3484: Unsafe Extern Blocks We are stabilizing `#![feature(unsafe_extern_blocks)]`, as described in [Unsafe Extern Blocks RFC 3484](rust-lang/rfcs#3484). This feature makes explicit that declaring an extern block is unsafe. Starting in Rust 2024, all extern blocks must be marked as unsafe. In all editions, items within unsafe extern blocks may be marked as safe to use. RFC: rust-lang/rfcs#3484 Tracking issue: #123743 ## What is stabilized ### Summary of stabilization We now need extern blocks to be marked as unsafe and items inside can also have safety modifiers (unsafe or safe), by default items with no modifiers are unsafe to offer easy migration without surprising results. ```rust unsafe extern { // sqrt (from libm) may be called with any `f64` pub safe fn sqrt(x: f64) -> f64; // strlen (from libc) requires a valid pointer, // so we mark it as being an unsafe fn pub unsafe fn strlen(p: *const c_char) -> usize; // this function doesn't say safe or unsafe, so it defaults to unsafe pub fn free(p: *mut core::ffi::c_void); pub safe static IMPORTANT_BYTES: [u8; 256]; pub safe static LINES: SyncUnsafeCell<i32>; } ``` ## Tests The relevant tests are in `tests/ui/rust-2024/unsafe-extern-blocks`. ## History - #124482 - #124455 - #125077 - #125522 - #126738 - #126749 - #126755 - #126757 - #126758 - #126756 - #126973 - #127535 - rust-lang/rustfmt#6204 ## Unresolved questions I am not aware of any unresolved questions.
2 parents edc4dc3 + 8366c7f commit 7d9ed2a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+85
-163
lines changed

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -453,11 +453,6 @@ impl<'a> AstValidator<'a> {
453453
item_span: span,
454454
block: Some(self.current_extern_span().shrink_to_lo()),
455455
});
456-
} else if !self.features.unsafe_extern_blocks {
457-
self.dcx().emit_err(errors::InvalidSafetyOnExtern {
458-
item_span: span,
459-
block: None,
460-
});
461456
}
462457
}
463458
}
@@ -1054,32 +1049,19 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
10541049
errors::VisibilityNotPermittedNote::IndividualForeignItems,
10551050
);
10561051

1057-
if this.features.unsafe_extern_blocks {
1058-
if &Safety::Default == safety {
1059-
if item.span.at_least_rust_2024() {
1060-
this.dcx()
1061-
.emit_err(errors::MissingUnsafeOnExtern { span: item.span });
1062-
} else {
1063-
this.lint_buffer.buffer_lint(
1064-
MISSING_UNSAFE_ON_EXTERN,
1065-
item.id,
1066-
item.span,
1067-
BuiltinLintDiag::MissingUnsafeOnExtern {
1068-
suggestion: item.span.shrink_to_lo(),
1069-
},
1070-
);
1071-
}
1052+
if &Safety::Default == safety {
1053+
if item.span.at_least_rust_2024() {
1054+
this.dcx().emit_err(errors::MissingUnsafeOnExtern { span: item.span });
1055+
} else {
1056+
this.lint_buffer.buffer_lint(
1057+
MISSING_UNSAFE_ON_EXTERN,
1058+
item.id,
1059+
item.span,
1060+
BuiltinLintDiag::MissingUnsafeOnExtern {
1061+
suggestion: item.span.shrink_to_lo(),
1062+
},
1063+
);
10721064
}
1073-
} else if let &Safety::Unsafe(span) = safety {
1074-
let mut diag = this
1075-
.dcx()
1076-
.create_err(errors::UnsafeItem { span, kind: "extern block" });
1077-
rustc_session::parse::add_feature_diagnostics(
1078-
&mut diag,
1079-
self.session,
1080-
sym::unsafe_extern_blocks,
1081-
);
1082-
diag.emit();
10831065
}
10841066

10851067
if abi.is_none() {

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -560,10 +560,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
560560
gate_all!(precise_capturing, "precise captures on `impl Trait` are experimental");
561561
gate_all!(global_registration, "global registration is experimental");
562562
gate_all!(unsafe_attributes, "`#[unsafe()]` markers for attributes are experimental");
563-
gate_all!(
564-
unsafe_extern_blocks,
565-
"`unsafe extern {}` blocks and `safe` keyword are experimental"
566-
);
567563
gate_all!(return_type_notation, "return type notation is experimental");
568564

569565
if !visitor.features.never_patterns {

compiler/rustc_feature/src/accepted.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,8 @@ declare_features! (
390390
(accepted, unrestricted_attribute_tokens, "1.34.0", Some(55208)),
391391
/// The `unsafe_op_in_unsafe_fn` lint (allowed by default): no longer treat an unsafe function as an unsafe block.
392392
(accepted, unsafe_block_in_unsafe_fn, "1.52.0", Some(71668)),
393+
/// Allows unsafe on extern declarations and safety qualifiers over internal items.
394+
(accepted, unsafe_extern_blocks, "CURRENT_RUSTC_VERSION", Some(123743)),
393395
/// Allows importing and reexporting macros with `use`,
394396
/// enables macro modularization in general.
395397
(accepted, use_extern_macros, "1.30.0", Some(35896)),

compiler/rustc_feature/src/unstable.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -631,8 +631,6 @@ declare_features! (
631631
(incomplete, unnamed_fields, "1.74.0", Some(49804)),
632632
/// Allows unsafe attributes.
633633
(unstable, unsafe_attributes, "1.80.0", Some(123757)),
634-
/// Allows unsafe on extern declarations and safety qualifiers over internal items.
635-
(unstable, unsafe_extern_blocks, "1.80.0", Some(123743)),
636634
/// Allows const generic parameters to be defined with types that
637635
/// are not `Sized`, e.g. `fn foo<const N: [u8]>() {`.
638636
(incomplete, unsized_const_params, "CURRENT_RUSTC_VERSION", Some(95174)),

compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4934,7 +4934,6 @@ declare_lint! {
49344934
/// ### Example
49354935
///
49364936
/// ```rust
4937-
/// #![feature(unsafe_extern_blocks)]
49384937
/// #![warn(missing_unsafe_on_extern)]
49394938
/// #![allow(dead_code)]
49404939
///

compiler/rustc_parse/src/parser/mod.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,9 +1250,6 @@ impl<'a> Parser<'a> {
12501250
if self.eat_keyword_case(kw::Unsafe, case) {
12511251
Safety::Unsafe(self.prev_token.uninterpolated_span())
12521252
} else if self.eat_keyword_case(kw::Safe, case) {
1253-
self.psess
1254-
.gated_spans
1255-
.gate(sym::unsafe_extern_blocks, self.prev_token.uninterpolated_span());
12561253
Safety::Safe(self.prev_token.uninterpolated_span())
12571254
} else {
12581255
Safety::Default

tests/rustdoc/unsafe-extern-blocks.rs

Lines changed: 1 addition & 2 deletions
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

Lines changed: 0 additions & 13 deletions
This file was deleted.

tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr

Lines changed: 0 additions & 23 deletions
This file was deleted.

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

Lines changed: 0 additions & 1 deletion
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)]

0 commit comments

Comments
 (0)