Skip to content

Stabilize unsafe extern blocks (RFC 3484) #127921

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 3, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 12 additions & 30 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
@@ -452,11 +452,6 @@ impl<'a> AstValidator<'a> {
item_span: span,
block: Some(self.current_extern_span().shrink_to_lo()),
});
} else if !self.features.unsafe_extern_blocks {
self.dcx().emit_err(errors::InvalidSafetyOnExtern {
item_span: span,
block: None,
});
}
}
}
@@ -1053,32 +1048,19 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
errors::VisibilityNotPermittedNote::IndividualForeignItems,
);

if this.features.unsafe_extern_blocks {
if &Safety::Default == safety {
if item.span.at_least_rust_2024() {
this.dcx()
.emit_err(errors::MissingUnsafeOnExtern { span: item.span });
} else {
this.lint_buffer.buffer_lint(
MISSING_UNSAFE_ON_EXTERN,
item.id,
item.span,
BuiltinLintDiag::MissingUnsafeOnExtern {
suggestion: item.span.shrink_to_lo(),
},
);
}
if &Safety::Default == safety {
if item.span.at_least_rust_2024() {
this.dcx().emit_err(errors::MissingUnsafeOnExtern { span: item.span });
} else {
this.lint_buffer.buffer_lint(
MISSING_UNSAFE_ON_EXTERN,
item.id,
item.span,
BuiltinLintDiag::MissingUnsafeOnExtern {
suggestion: item.span.shrink_to_lo(),
},
);
}
} else if let &Safety::Unsafe(span) = safety {
let mut diag = this
.dcx()
.create_err(errors::UnsafeItem { span, kind: "extern block" });
rustc_session::parse::add_feature_diagnostics(
&mut diag,
self.session,
sym::unsafe_extern_blocks,
);
diag.emit();
}

if abi.is_none() {
4 changes: 0 additions & 4 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
@@ -561,10 +561,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
gate_all!(precise_capturing, "precise captures on `impl Trait` are experimental");
gate_all!(global_registration, "global registration is experimental");
gate_all!(unsafe_attributes, "`#[unsafe()]` markers for attributes are experimental");
gate_all!(
unsafe_extern_blocks,
"`unsafe extern {}` blocks and `safe` keyword are experimental"
);
gate_all!(return_type_notation, "return type notation is experimental");

if !visitor.features.never_patterns {
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/accepted.rs
Original file line number Diff line number Diff line change
@@ -387,6 +387,8 @@ declare_features! (
(accepted, unrestricted_attribute_tokens, "1.34.0", Some(55208)),
/// The `unsafe_op_in_unsafe_fn` lint (allowed by default): no longer treat an unsafe function as an unsafe block.
(accepted, unsafe_block_in_unsafe_fn, "1.52.0", Some(71668)),
/// Allows unsafe on extern declarations and safety qualifiers over internal items.
(accepted, unsafe_extern_blocks, "CURRENT_RUSTC_VERSION", Some(123743)),
/// Allows importing and reexporting macros with `use`,
/// enables macro modularization in general.
(accepted, use_extern_macros, "1.30.0", Some(35896)),
2 changes: 0 additions & 2 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
@@ -628,8 +628,6 @@ declare_features! (
(incomplete, unnamed_fields, "1.74.0", Some(49804)),
/// Allows unsafe attributes.
(unstable, unsafe_attributes, "1.80.0", Some(123757)),
/// Allows unsafe on extern declarations and safety qualifiers over internal items.
(unstable, unsafe_extern_blocks, "1.80.0", Some(123743)),
/// Allows const generic parameters to be defined with types that
/// are not `Sized`, e.g. `fn foo<const N: [u8]>() {`.
(incomplete, unsized_const_params, "CURRENT_RUSTC_VERSION", Some(95174)),
1 change: 0 additions & 1 deletion compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
@@ -4865,7 +4865,6 @@ declare_lint! {
/// ### Example
///
/// ```rust
/// #![feature(unsafe_extern_blocks)]
/// #![warn(missing_unsafe_on_extern)]
/// #![allow(dead_code)]
///
3 changes: 0 additions & 3 deletions compiler/rustc_parse/src/parser/mod.rs
Original file line number Diff line number Diff line change
@@ -1205,9 +1205,6 @@ impl<'a> Parser<'a> {
if self.eat_keyword_case(kw::Unsafe, case) {
Safety::Unsafe(self.prev_token.uninterpolated_span())
} else if self.eat_keyword_case(kw::Safe, case) {
self.psess
.gated_spans
.gate(sym::unsafe_extern_blocks, self.prev_token.uninterpolated_span());
Safety::Safe(self.prev_token.uninterpolated_span())
} else {
Safety::Default
3 changes: 1 addition & 2 deletions tests/rustdoc/unsafe-extern-blocks.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Test to ensure the feature is working as expected.

#![feature(unsafe_extern_blocks)]
#![crate_name = "foo"]

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

unsafe extern {
unsafe extern "C" {
// @has 'foo/static.FOO.html'
// @has - '//pre[@class="rust item-decl"]' 'pub static FOO: i32'
pub safe static FOO: i32;
13 changes: 0 additions & 13 deletions tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.rs

This file was deleted.

23 changes: 0 additions & 23 deletions tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr

This file was deleted.

1 change: 0 additions & 1 deletion tests/ui/lint/unsafe_code/unsafe-extern-blocks.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(unsafe_extern_blocks)]
#![deny(unsafe_code)]

#[allow(unsafe_code)]
4 changes: 2 additions & 2 deletions tests/ui/lint/unsafe_code/unsafe-extern-blocks.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: usage of an `unsafe extern` block
--> $DIR/unsafe-extern-blocks.rs:9:1
--> $DIR/unsafe-extern-blocks.rs:8:1
|
LL | / unsafe extern "C" {
LL | |
@@ -8,7 +8,7 @@ LL | | }
| |_^
|
note: the lint level is defined here
--> $DIR/unsafe-extern-blocks.rs:2:9
--> $DIR/unsafe-extern-blocks.rs:1:9
|
LL | #![deny(unsafe_code)]
| ^^^^^^^^^^^
2 changes: 0 additions & 2 deletions tests/ui/parser/unsafe-foreign-mod-2.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
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() {}
18 changes: 1 addition & 17 deletions tests/ui/parser/unsafe-foreign-mod-2.stderr
Original file line number Diff line number Diff line change
@@ -4,21 +4,5 @@ error: expected `{`, found keyword `unsafe`
LL | extern "C" unsafe {
| ^^^^^^ expected `{`

error: extern block cannot be declared unsafe
--> $DIR/unsafe-foreign-mod-2.rs:1:12
|
LL | extern "C" unsafe {
| ^^^^^^
|
= note: see issue #123743 <https://github.com/rust-lang/rust/issues/123743> for more information
= help: add `#![feature(unsafe_extern_blocks)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error: items in unadorned `extern` blocks cannot have safety qualifiers
--> $DIR/unsafe-foreign-mod-2.rs:4:5
|
LL | unsafe fn foo();
| ^^^^^^^^^^^^^^^^

error: aborting due to 3 previous errors
error: aborting due to 1 previous error

6 changes: 3 additions & 3 deletions tests/ui/parser/unsafe-foreign-mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
unsafe extern "C" {
//~^ ERROR extern block cannot be declared unsafe
}
//@ check-pass

unsafe extern "C" {}

fn main() {}
12 changes: 0 additions & 12 deletions tests/ui/parser/unsafe-foreign-mod.stderr

This file was deleted.

8 changes: 0 additions & 8 deletions tests/ui/rust-2024/safe-outside-extern.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
//@ revisions: gated ungated
#![cfg_attr(gated, feature(unsafe_extern_blocks))]

safe fn foo() {}
//~^ ERROR: items outside of `unsafe extern { }` cannot be declared with `safe` safety qualifier
//[ungated]~| ERROR: unsafe extern {}` blocks and `safe` keyword are experimental [E0658]

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

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

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

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

unsafe static LOL: u8 = 0;
//~^ ERROR: static items cannot be declared with `unsafe` safety qualifier outside of `extern` block
38 changes: 38 additions & 0 deletions tests/ui/rust-2024/safe-outside-extern.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
error: items outside of `unsafe extern { }` cannot be declared with `safe` safety qualifier
--> $DIR/safe-outside-extern.rs:1:1
|
LL | safe fn foo() {}
| ^^^^^^^^^^^^^^^^

error: items outside of `unsafe extern { }` cannot be declared with `safe` safety qualifier
--> $DIR/safe-outside-extern.rs:4:1
|
LL | safe static FOO: i32 = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^

error: items outside of `unsafe extern { }` cannot be declared with `safe` safety qualifier
--> $DIR/safe-outside-extern.rs:8:5
|
LL | safe fn foo();
| ^^^^^^^^^^^^^^

error: items outside of `unsafe extern { }` cannot be declared with `safe` safety qualifier
--> $DIR/safe-outside-extern.rs:13:5
|
LL | safe fn foo() {}
| ^^^^^^^^^^^^^^^^

error: function pointers cannot be declared with `safe` safety qualifier
--> $DIR/safe-outside-extern.rs:17:14
|
LL | type FnPtr = safe fn(i32, i32) -> i32;
| ^^^^^^^^^^^^^^^^^^^^^^^^

error: static items cannot be declared with `unsafe` safety qualifier outside of `extern` block
--> $DIR/safe-outside-extern.rs:20:1
|
LL | unsafe static LOL: u8 = 0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 6 previous errors

Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe function or block
--> $DIR/extern-items-unsafe.rs:14:5
--> $DIR/extern-items-unsafe.rs:12:5
|
LL | test1(TEST1);
| ^^^^^^^^^^^^ call to unsafe function
|
= 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:14:11
--> $DIR/extern-items-unsafe.rs:12:11
|
LL | test1(TEST1);
| ^^^^^ use of extern static
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe block
--> $DIR/extern-items-unsafe.rs:14:5
--> $DIR/extern-items-unsafe.rs:12:5
|
LL | test1(TEST1);
| ^^^^^^^^^^^^ call to unsafe function
|
= 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:14:11
--> $DIR/extern-items-unsafe.rs:12:11
|
LL | test1(TEST1);
| ^^^^^ use of extern static
Original file line number Diff line number Diff line change
@@ -3,8 +3,6 @@
//@[edition2024] edition:2024
//@[edition2024] compile-flags: -Zunstable-options

#![feature(unsafe_extern_blocks)]

unsafe extern "C" {
static TEST1: i32;
fn test1(i: i32);
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: extern blocks must be unsafe
--> $DIR/extern-items.rs:9:1
--> $DIR/extern-items.rs:7:1
|
LL | / extern "C" {
LL | |
2 changes: 0 additions & 2 deletions tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs
Original file line number Diff line number Diff line change
@@ -4,8 +4,6 @@
//@[edition2024] edition:2024
//@[edition2024] compile-flags: -Zunstable-options

#![feature(unsafe_extern_blocks)]

extern "C" {
//[edition2024]~^ ERROR extern blocks must be unsafe
static TEST1: i32;
3 changes: 0 additions & 3 deletions tests/ui/rust-2024/unsafe-extern-blocks/safe-impl-trait.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
//@ revisions: gated ungated
#![cfg_attr(gated, feature(unsafe_extern_blocks))]

trait Bar {}
safe impl Bar for () { }
//~^ ERROR expected one of `!` or `::`, found keyword `impl`
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: expected one of `!` or `::`, found keyword `impl`
--> $DIR/safe-impl-trait.rs:5:6
--> $DIR/safe-impl-trait.rs:2:6
|
LL | safe impl Bar for () { }
| ^^^^ expected one of `!` or `::`
2 changes: 0 additions & 2 deletions tests/ui/rust-2024/unsafe-extern-blocks/safe-items.rs
Original file line number Diff line number Diff line change
@@ -4,8 +4,6 @@
//@[edition2024] compile-flags: -Zunstable-options
//@ check-pass

#![feature(unsafe_extern_blocks)]

unsafe extern "C" {
safe static TEST1: i32;
safe fn test1(i: i32);
3 changes: 0 additions & 3 deletions tests/ui/rust-2024/unsafe-extern-blocks/safe-trait.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
//@ revisions: gated ungated
#![cfg_attr(gated, feature(unsafe_extern_blocks))]

safe trait Foo {}
//~^ ERROR expected one of `!` or `::`, found keyword `trait`

8 changes: 8 additions & 0 deletions tests/ui/rust-2024/unsafe-extern-blocks/safe-trait.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: expected one of `!` or `::`, found keyword `trait`
--> $DIR/safe-trait.rs:1:6
|
LL | safe trait Foo {}
| ^^^^^ expected one of `!` or `::`

error: aborting due to 1 previous error

Loading