diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index 7cfbd6c6c6c..92acaaa5f36 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -62,12 +62,12 @@ ast_passes_equality_in_where = equality constraints are not yet supported in `wh ast_passes_extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block -ast_passes_extern_fn_qualifiers = functions in `extern` blocks cannot have qualifiers +ast_passes_extern_fn_qualifiers = functions in `extern` blocks cannot have `{$kw}` qualifier .label = in this `extern` block - .suggestion = remove this qualifier + .suggestion = remove the `{$kw}` qualifier -ast_passes_extern_invalid_safety = items in unadorned `extern` blocks cannot have safety qualifiers - .suggestion = add unsafe to this `extern` block +ast_passes_extern_invalid_safety = items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers + .suggestion = add `unsafe` to this `extern` block ast_passes_extern_item_ascii = items in `extern` blocks cannot use non-ascii identifiers .label = in this `extern` block diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 87e3a6871b9..a36a9f11c0f 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -524,21 +524,24 @@ fn check_foreign_fn_headerless( // Deconstruct to ensure exhaustiveness FnHeader { safety: _, coroutine_kind, constness, ext }: FnHeader, ) { - let report_err = |span| { - self.dcx() - .emit_err(errors::FnQualifierInExtern { span, block: self.current_extern_span() }); + let report_err = |span, kw| { + self.dcx().emit_err(errors::FnQualifierInExtern { + span, + kw, + block: self.current_extern_span(), + }); }; match coroutine_kind { - Some(knd) => report_err(knd.span()), + Some(kind) => report_err(kind.span(), kind.as_str()), None => (), } match constness { - Const::Yes(span) => report_err(span), + Const::Yes(span) => report_err(span, "const"), Const::No => (), } match ext { Extern::None => (), - Extern::Implicit(span) | Extern::Explicit(_, span) => report_err(span), + Extern::Implicit(span) | Extern::Explicit(_, span) => report_err(span, "extern"), } } diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index c60925b3049..4ca1acde1e2 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -295,6 +295,7 @@ pub(crate) struct FnQualifierInExtern { pub span: Span, #[label] pub block: Span, + pub kw: &'static str, } #[derive(Diagnostic)] diff --git a/tests/rustdoc-json/fns/extern_safe.rs b/tests/rustdoc-json/fns/extern_safe.rs index a4a2d2c7f8c..b00f9f50bd2 100644 --- a/tests/rustdoc-json/fns/extern_safe.rs +++ b/tests/rustdoc-json/fns/extern_safe.rs @@ -2,7 +2,7 @@ //@ is "$.index[*][?(@.name=='f1')].inner.function.header.is_unsafe" true pub fn f1(); - // items in unadorned `extern` blocks cannot have safety qualifiers + // items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers } unsafe extern "C" { diff --git a/tests/ui/extern/issue-95829.rs b/tests/ui/extern/issue-95829.rs index ad4e04f7c3a..c5ae4c68265 100644 --- a/tests/ui/extern/issue-95829.rs +++ b/tests/ui/extern/issue-95829.rs @@ -2,7 +2,7 @@ extern { async fn L() { //~ ERROR: incorrect function inside `extern` block - //~^ ERROR: functions in `extern` blocks cannot have qualifiers + //~^ ERROR: functions in `extern` blocks cannot have `async` qualifier async fn M() {} } } diff --git a/tests/ui/extern/issue-95829.stderr b/tests/ui/extern/issue-95829.stderr index 16504d1f0c9..2f396b8cc04 100644 --- a/tests/ui/extern/issue-95829.stderr +++ b/tests/ui/extern/issue-95829.stderr @@ -15,13 +15,13 @@ LL | | } = help: you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html -error: functions in `extern` blocks cannot have qualifiers +error: functions in `extern` blocks cannot have `async` qualifier --> $DIR/issue-95829.rs:4:5 | LL | extern { | ------ in this `extern` block LL | async fn L() { - | ^^^^^ help: remove this qualifier + | ^^^^^ help: remove the `async` qualifier error: aborting due to 2 previous errors diff --git a/tests/ui/parser/fn-header-semantic-fail.rs b/tests/ui/parser/fn-header-semantic-fail.rs index 972e52d75da..202f362c81c 100644 --- a/tests/ui/parser/fn-header-semantic-fail.rs +++ b/tests/ui/parser/fn-header-semantic-fail.rs @@ -41,15 +41,15 @@ extern "C" fn fi4() {} // OK. } extern "C" { - async fn fe1(); //~ ERROR functions in `extern` blocks cannot have qualifiers - unsafe fn fe2(); //~ ERROR items in unadorned `extern` blocks cannot have safety qualifiers - const fn fe3(); //~ ERROR functions in `extern` blocks cannot have qualifiers - extern "C" fn fe4(); //~ ERROR functions in `extern` blocks cannot have qualifiers + async fn fe1(); //~ ERROR functions in `extern` blocks cannot + unsafe fn fe2(); //~ ERROR items in `extern` blocks without an `unsafe` qualifier cannot + const fn fe3(); //~ ERROR functions in `extern` blocks cannot + extern "C" fn fe4(); //~ ERROR functions in `extern` blocks cannot const async unsafe extern "C" fn fe5(); //~^ ERROR functions in `extern` blocks //~| ERROR functions in `extern` blocks //~| ERROR functions in `extern` blocks //~| ERROR functions cannot be both `const` and `async` - //~| ERROR items in unadorned `extern` blocks cannot have safety qualifiers + //~| ERROR items in `extern` blocks without an `unsafe` qualifier cannot have } } diff --git a/tests/ui/parser/fn-header-semantic-fail.stderr b/tests/ui/parser/fn-header-semantic-fail.stderr index dda42f24b32..17e880c3a79 100644 --- a/tests/ui/parser/fn-header-semantic-fail.stderr +++ b/tests/ui/parser/fn-header-semantic-fail.stderr @@ -70,77 +70,77 @@ LL | const async unsafe extern "C" fn fi5() {} | | `async` because of this | `const` because of this -error: functions in `extern` blocks cannot have qualifiers +error: functions in `extern` blocks cannot have `async` qualifier --> $DIR/fn-header-semantic-fail.rs:44:9 | LL | extern "C" { | ---------- in this `extern` block LL | async fn fe1(); - | ^^^^^ help: remove this qualifier + | ^^^^^ help: remove the `async` qualifier -error: items in unadorned `extern` blocks cannot have safety qualifiers +error: items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers --> $DIR/fn-header-semantic-fail.rs:45:9 | LL | unsafe fn fe2(); | ^^^^^^^^^^^^^^^^ | -help: add unsafe to this `extern` block +help: add `unsafe` to this `extern` block | LL | unsafe extern "C" { | ++++++ -error: functions in `extern` blocks cannot have qualifiers +error: functions in `extern` blocks cannot have `const` qualifier --> $DIR/fn-header-semantic-fail.rs:46:9 | LL | extern "C" { | ---------- in this `extern` block ... LL | const fn fe3(); - | ^^^^^ help: remove this qualifier + | ^^^^^ help: remove the `const` qualifier -error: functions in `extern` blocks cannot have qualifiers +error: functions in `extern` blocks cannot have `extern` qualifier --> $DIR/fn-header-semantic-fail.rs:47:9 | LL | extern "C" { | ---------- in this `extern` block ... LL | extern "C" fn fe4(); - | ^^^^^^^^^^ help: remove this qualifier + | ^^^^^^^^^^ help: remove the `extern` qualifier -error: functions in `extern` blocks cannot have qualifiers +error: functions in `extern` blocks cannot have `async` qualifier --> $DIR/fn-header-semantic-fail.rs:48:15 | LL | extern "C" { | ---------- in this `extern` block ... LL | const async unsafe extern "C" fn fe5(); - | ^^^^^ help: remove this qualifier + | ^^^^^ help: remove the `async` qualifier -error: functions in `extern` blocks cannot have qualifiers +error: functions in `extern` blocks cannot have `const` qualifier --> $DIR/fn-header-semantic-fail.rs:48:9 | LL | extern "C" { | ---------- in this `extern` block ... LL | const async unsafe extern "C" fn fe5(); - | ^^^^^ help: remove this qualifier + | ^^^^^ help: remove the `const` qualifier -error: functions in `extern` blocks cannot have qualifiers +error: functions in `extern` blocks cannot have `extern` qualifier --> $DIR/fn-header-semantic-fail.rs:48:28 | LL | extern "C" { | ---------- in this `extern` block ... LL | const async unsafe extern "C" fn fe5(); - | ^^^^^^^^^^ help: remove this qualifier + | ^^^^^^^^^^ help: remove the `extern` qualifier -error: items in unadorned `extern` blocks cannot have safety qualifiers +error: items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers --> $DIR/fn-header-semantic-fail.rs:48:9 | LL | const async unsafe extern "C" fn fe5(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: add unsafe to this `extern` block +help: add `unsafe` to this `extern` block | LL | unsafe extern "C" { | ++++++ diff --git a/tests/ui/parser/no-const-fn-in-extern-block.rs b/tests/ui/parser/no-const-fn-in-extern-block.rs index 3ad9ba006d3..0f1e44ced10 100644 --- a/tests/ui/parser/no-const-fn-in-extern-block.rs +++ b/tests/ui/parser/no-const-fn-in-extern-block.rs @@ -1,9 +1,9 @@ extern "C" { const fn foo(); - //~^ ERROR functions in `extern` blocks cannot have qualifiers + //~^ ERROR functions in `extern` blocks cannot const unsafe fn bar(); - //~^ ERROR functions in `extern` blocks cannot have qualifiers - //~| ERROR items in unadorned `extern` blocks cannot have safety qualifiers + //~^ ERROR functions in `extern` blocks cannot + //~| ERROR items in `extern` blocks without an `unsafe` qualifier cannot } fn main() {} diff --git a/tests/ui/parser/no-const-fn-in-extern-block.stderr b/tests/ui/parser/no-const-fn-in-extern-block.stderr index 8c23824a708..46f845e85c2 100644 --- a/tests/ui/parser/no-const-fn-in-extern-block.stderr +++ b/tests/ui/parser/no-const-fn-in-extern-block.stderr @@ -1,27 +1,27 @@ -error: functions in `extern` blocks cannot have qualifiers +error: functions in `extern` blocks cannot have `const` qualifier --> $DIR/no-const-fn-in-extern-block.rs:2:5 | LL | extern "C" { | ---------- in this `extern` block LL | const fn foo(); - | ^^^^^ help: remove this qualifier + | ^^^^^ help: remove the `const` qualifier -error: functions in `extern` blocks cannot have qualifiers +error: functions in `extern` blocks cannot have `const` qualifier --> $DIR/no-const-fn-in-extern-block.rs:4:5 | LL | extern "C" { | ---------- in this `extern` block ... LL | const unsafe fn bar(); - | ^^^^^ help: remove this qualifier + | ^^^^^ help: remove the `const` qualifier -error: items in unadorned `extern` blocks cannot have safety qualifiers +error: items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers --> $DIR/no-const-fn-in-extern-block.rs:4:5 | LL | const unsafe fn bar(); | ^^^^^^^^^^^^^^^^^^^^^^ | -help: add unsafe to this `extern` block +help: add `unsafe` to this `extern` block | LL | unsafe extern "C" { | ++++++ diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2021.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2021.stderr index 93797987286..ddc5477116f 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2021.stderr +++ b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2021.stderr @@ -1,21 +1,21 @@ -error: items in unadorned `extern` blocks cannot have safety qualifiers +error: items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:8:5 | LL | safe static TEST1: i32; | ^^^^^^^^^^^^^^^^^^^^^^^ | -help: add unsafe to this `extern` block +help: add `unsafe` to this `extern` block | LL | unsafe extern "C" { | ++++++ -error: items in unadorned `extern` blocks cannot have safety qualifiers +error: items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:10:5 | LL | safe fn test1(i: i32); | ^^^^^^^^^^^^^^^^^^^^^^ | -help: add unsafe to this `extern` block +help: add `unsafe` to this `extern` block | LL | unsafe extern "C" { | ++++++ diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2024.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2024.stderr index e9db6006c0b..ae7b4cd47c0 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2024.stderr +++ b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2024.stderr @@ -10,24 +10,24 @@ LL | | LL | | } | |_^ -error: items in unadorned `extern` blocks cannot have safety qualifiers +error: items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:8:5 | LL | safe static TEST1: i32; | ^^^^^^^^^^^^^^^^^^^^^^^ | -help: add unsafe to this `extern` block +help: add `unsafe` to this `extern` block | LL | unsafe extern "C" { | ++++++ -error: items in unadorned `extern` blocks cannot have safety qualifiers +error: items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:10:5 | LL | safe fn test1(i: i32); | ^^^^^^^^^^^^^^^^^^^^^^ | -help: add unsafe to this `extern` block +help: add `unsafe` to this `extern` block | LL | unsafe extern "C" { | ++++++ diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.rs b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.rs index 4badb50b267..89415a69f08 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.rs +++ b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.rs @@ -6,9 +6,9 @@ extern "C" { //[edition2024]~^ ERROR extern blocks must be unsafe safe static TEST1: i32; - //~^ ERROR items in unadorned `extern` blocks cannot have safety qualifiers + //~^ ERROR items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers safe fn test1(i: i32); - //~^ ERROR items in unadorned `extern` blocks cannot have safety qualifiers + //~^ ERROR items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers } fn test2() { diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.fixed b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.fixed index 857d34eef85..79983a64c2b 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.fixed +++ b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.fixed @@ -3,7 +3,7 @@ #![allow(dead_code)] unsafe extern "C" { - unsafe fn foo(); //~ ERROR items in unadorned `extern` blocks cannot have safety qualifiers + unsafe fn foo(); //~ ERROR items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers } fn main() {} diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.rs b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.rs index edab9850d79..cb84d3d1411 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.rs +++ b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.rs @@ -3,7 +3,7 @@ #![allow(dead_code)] extern "C" { - unsafe fn foo(); //~ ERROR items in unadorned `extern` blocks cannot have safety qualifiers + unsafe fn foo(); //~ ERROR items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers } fn main() {} diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.stderr index 073245e650b..cf1c0012f4d 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.stderr +++ b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.stderr @@ -1,10 +1,10 @@ -error: items in unadorned `extern` blocks cannot have safety qualifiers +error: items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers --> $DIR/unsafe-on-extern-block-issue-126756.rs:6:5 | LL | unsafe fn foo(); | ^^^^^^^^^^^^^^^^ | -help: add unsafe to this `extern` block +help: add `unsafe` to this `extern` block | LL | unsafe extern "C" { | ++++++