Fix diagnostic for qualifier in extern block

Closes: https://github.com/rust-lang/rust/issues/123306
This commit is contained in:
Arthur Carcano 2024-04-03 02:43:54 +02:00
parent 45796d1c24
commit 109daa2d4b
10 changed files with 93 additions and 72 deletions

View file

@ -2483,6 +2483,14 @@ pub enum CoroutineKind {
} }
impl CoroutineKind { impl CoroutineKind {
pub fn span(self) -> Span {
match self {
CoroutineKind::Async { span, .. } => span,
CoroutineKind::Gen { span, .. } => span,
CoroutineKind::AsyncGen { span, .. } => span,
}
}
pub fn is_async(self) -> bool { pub fn is_async(self) -> bool {
matches!(self, CoroutineKind::Async { .. }) matches!(self, CoroutineKind::Async { .. })
} }

View file

@ -68,7 +68,7 @@ ast_passes_extern_block_suggestion = if you meant to declare an externally defin
ast_passes_extern_fn_qualifiers = functions in `extern` blocks cannot have qualifiers ast_passes_extern_fn_qualifiers = functions in `extern` blocks cannot have qualifiers
.label = in this `extern` block .label = in this `extern` block
.suggestion = remove the qualifiers .suggestion = remove this qualifier
ast_passes_extern_item_ascii = items in `extern` blocks cannot use non-ascii identifiers ast_passes_extern_item_ascii = items in `extern` blocks cannot use non-ascii identifiers
.label = in this `extern` block .label = in this `extern` block

View file

@ -514,13 +514,32 @@ impl<'a> AstValidator<'a> {
} }
/// An `fn` in `extern { ... }` cannot have qualifiers, e.g. `async fn`. /// An `fn` in `extern { ... }` cannot have qualifiers, e.g. `async fn`.
fn check_foreign_fn_headerless(&self, ident: Ident, span: Span, header: FnHeader) { fn check_foreign_fn_headerless(
if header.has_qualifiers() { &self,
// Deconstruct to ensure exhaustiveness
FnHeader { unsafety, coroutine_kind, constness, ext }: FnHeader,
) {
let report_err = |span| {
self.dcx().emit_err(errors::FnQualifierInExtern { self.dcx().emit_err(errors::FnQualifierInExtern {
span: ident.span, span: span,
block: self.current_extern_span(), block: self.current_extern_span(),
sugg_span: span.until(ident.span.shrink_to_lo()),
}); });
};
match unsafety {
Unsafe::Yes(span) => report_err(span),
Unsafe::No => (),
}
match coroutine_kind {
Some(knd) => report_err(knd.span()),
None => (),
}
match constness {
Const::Yes(span) => report_err(span),
Const::No => (),
}
match ext {
Extern::None => (),
Extern::Implicit(span) | Extern::Explicit(_, span) => report_err(span),
} }
} }
@ -1145,7 +1164,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
ForeignItemKind::Fn(box Fn { defaultness, sig, body, .. }) => { ForeignItemKind::Fn(box Fn { defaultness, sig, body, .. }) => {
self.check_defaultness(fi.span, *defaultness); self.check_defaultness(fi.span, *defaultness);
self.check_foreign_fn_bodyless(fi.ident, body.as_deref()); self.check_foreign_fn_bodyless(fi.ident, body.as_deref());
self.check_foreign_fn_headerless(fi.ident, fi.span, sig.header); self.check_foreign_fn_headerless(sig.header);
self.check_foreign_item_ascii_only(fi.ident); self.check_foreign_item_ascii_only(fi.ident);
} }
ForeignItemKind::TyAlias(box TyAlias { ForeignItemKind::TyAlias(box TyAlias {

View file

@ -270,11 +270,10 @@ pub struct FnBodyInExtern {
#[diag(ast_passes_extern_fn_qualifiers)] #[diag(ast_passes_extern_fn_qualifiers)]
pub struct FnQualifierInExtern { pub struct FnQualifierInExtern {
#[primary_span] #[primary_span]
#[suggestion(code = "", applicability = "maybe-incorrect")]
pub span: Span, pub span: Span,
#[label] #[label]
pub block: Span, pub block: Span,
#[suggestion(code = "fn ", applicability = "maybe-incorrect", style = "verbose")]
pub sugg_span: Span,
} }
#[derive(Diagnostic)] #[derive(Diagnostic)]

View file

@ -16,17 +16,12 @@ LL | | }
= note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html = 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 qualifiers
--> $DIR/issue-95829.rs:4:14 --> $DIR/issue-95829.rs:4:5
| |
LL | extern { LL | extern {
| ------ in this `extern` block | ------ in this `extern` block
LL | async fn L() { LL | async fn L() {
| ^ | ^^^^^ help: remove this qualifier
|
help: remove the qualifiers
|
LL | fn L() {
| ~~
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -48,6 +48,9 @@ fn main() {
const fn fe3(); //~ ERROR functions in `extern` blocks cannot have qualifiers const fn fe3(); //~ ERROR functions in `extern` blocks cannot have qualifiers
extern "C" fn fe4(); //~ ERROR functions in `extern` blocks cannot have qualifiers extern "C" fn fe4(); //~ ERROR functions in `extern` blocks cannot have qualifiers
const async unsafe extern "C" fn fe5(); //~ ERROR functions in `extern` blocks const async unsafe extern "C" fn fe5(); //~ ERROR functions in `extern` blocks
//~^ ERROR functions cannot be both `const` and `async` //~| ERROR functions in `extern` blocks
//~| ERROR functions in `extern` blocks
//~| ERROR functions in `extern` blocks
//~| ERROR functions cannot be both `const` and `async`
} }
} }

View file

@ -71,73 +71,75 @@ LL | const async unsafe extern "C" fn fi5() {}
| `const` because of this | `const` because of this
error: functions in `extern` blocks cannot have qualifiers error: functions in `extern` blocks cannot have qualifiers
--> $DIR/fn-header-semantic-fail.rs:46:18 --> $DIR/fn-header-semantic-fail.rs:46:9
| |
LL | extern "C" { LL | extern "C" {
| ---------- in this `extern` block | ---------- in this `extern` block
LL | async fn fe1(); LL | async fn fe1();
| ^^^ | ^^^^^ help: remove this qualifier
|
help: remove the qualifiers
|
LL | fn fe1();
| ~~
error: functions in `extern` blocks cannot have qualifiers error: functions in `extern` blocks cannot have qualifiers
--> $DIR/fn-header-semantic-fail.rs:47:19 --> $DIR/fn-header-semantic-fail.rs:47:9
| |
LL | extern "C" { LL | extern "C" {
| ---------- in this `extern` block | ---------- in this `extern` block
LL | async fn fe1(); LL | async fn fe1();
LL | unsafe fn fe2(); LL | unsafe fn fe2();
| ^^^ | ^^^^^^ help: remove this qualifier
|
help: remove the qualifiers
|
LL | fn fe2();
| ~~
error: functions in `extern` blocks cannot have qualifiers error: functions in `extern` blocks cannot have qualifiers
--> $DIR/fn-header-semantic-fail.rs:48:18 --> $DIR/fn-header-semantic-fail.rs:48:9
| |
LL | extern "C" { LL | extern "C" {
| ---------- in this `extern` block | ---------- in this `extern` block
... ...
LL | const fn fe3(); LL | const fn fe3();
| ^^^ | ^^^^^ help: remove this qualifier
|
help: remove the qualifiers
|
LL | fn fe3();
| ~~
error: functions in `extern` blocks cannot have qualifiers error: functions in `extern` blocks cannot have qualifiers
--> $DIR/fn-header-semantic-fail.rs:49:23 --> $DIR/fn-header-semantic-fail.rs:49:9
| |
LL | extern "C" { LL | extern "C" {
| ---------- in this `extern` block | ---------- in this `extern` block
... ...
LL | extern "C" fn fe4(); LL | extern "C" fn fe4();
| ^^^ | ^^^^^^^^^^ help: remove this qualifier
|
help: remove the qualifiers
|
LL | fn fe4();
| ~~
error: functions in `extern` blocks cannot have qualifiers error: functions in `extern` blocks cannot have qualifiers
--> $DIR/fn-header-semantic-fail.rs:50:42 --> $DIR/fn-header-semantic-fail.rs:50:21
| |
LL | extern "C" { LL | extern "C" {
| ---------- in this `extern` block | ---------- in this `extern` block
... ...
LL | const async unsafe extern "C" fn fe5(); LL | const async unsafe extern "C" fn fe5();
| ^^^ | ^^^^^^ help: remove this qualifier
error: functions in `extern` blocks cannot have qualifiers
--> $DIR/fn-header-semantic-fail.rs:50:15
| |
help: remove the qualifiers LL | extern "C" {
| ---------- in this `extern` block
...
LL | const async unsafe extern "C" fn fe5();
| ^^^^^ help: remove this qualifier
error: functions in `extern` blocks cannot have qualifiers
--> $DIR/fn-header-semantic-fail.rs:50:9
| |
LL | fn fe5(); LL | extern "C" {
| ~~ | ---------- in this `extern` block
...
LL | const async unsafe extern "C" fn fe5();
| ^^^^^ help: remove this qualifier
error: functions in `extern` blocks cannot have qualifiers
--> $DIR/fn-header-semantic-fail.rs:50:28
|
LL | extern "C" {
| ---------- in this `extern` block
...
LL | const async unsafe extern "C" fn fe5();
| ^^^^^^^^^^ help: remove this qualifier
error: functions cannot be both `const` and `async` error: functions cannot be both `const` and `async`
--> $DIR/fn-header-semantic-fail.rs:50:9 --> $DIR/fn-header-semantic-fail.rs:50:9
@ -148,6 +150,6 @@ LL | const async unsafe extern "C" fn fe5();
| | `async` because of this | | `async` because of this
| `const` because of this | `const` because of this
error: aborting due to 14 previous errors error: aborting due to 17 previous errors
For more information about this error, try `rustc --explain E0379`. For more information about this error, try `rustc --explain E0379`.

View file

@ -3,6 +3,7 @@ extern "C" {
//~^ ERROR functions in `extern` blocks cannot have qualifiers //~^ ERROR functions in `extern` blocks cannot have qualifiers
const unsafe fn bar(); const unsafe fn bar();
//~^ ERROR functions in `extern` blocks cannot have qualifiers //~^ ERROR functions in `extern` blocks cannot have qualifiers
//~| ERROR functions in `extern` blocks cannot have qualifiers
} }
fn main() {} fn main() {}

View file

@ -1,29 +1,28 @@
error: functions in `extern` blocks cannot have qualifiers error: functions in `extern` blocks cannot have qualifiers
--> $DIR/no-const-fn-in-extern-block.rs:2:14 --> $DIR/no-const-fn-in-extern-block.rs:2:5
| |
LL | extern "C" { LL | extern "C" {
| ---------- in this `extern` block | ---------- in this `extern` block
LL | const fn foo(); LL | const fn foo();
| ^^^ | ^^^^^ help: remove this qualifier
|
help: remove the qualifiers
|
LL | fn foo();
| ~~
error: functions in `extern` blocks cannot have qualifiers error: functions in `extern` blocks cannot have qualifiers
--> $DIR/no-const-fn-in-extern-block.rs:4:21 --> $DIR/no-const-fn-in-extern-block.rs:4:11
| |
LL | extern "C" { LL | extern "C" {
| ---------- in this `extern` block | ---------- in this `extern` block
... ...
LL | const unsafe fn bar(); LL | const unsafe fn bar();
| ^^^ | ^^^^^^ help: remove this qualifier
|
help: remove the qualifiers
|
LL | fn bar();
| ~~
error: aborting due to 2 previous errors error: functions in `extern` blocks cannot have qualifiers
--> $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
error: aborting due to 3 previous errors

View file

@ -11,18 +11,13 @@ LL | extern "C" unsafe {
| ^^^^^^ | ^^^^^^
error: functions in `extern` blocks cannot have qualifiers error: functions in `extern` blocks cannot have qualifiers
--> $DIR/unsafe-foreign-mod-2.rs:4:15 --> $DIR/unsafe-foreign-mod-2.rs:4:5
| |
LL | extern "C" unsafe { LL | extern "C" unsafe {
| ----------------- in this `extern` block | ----------------- in this `extern` block
... ...
LL | unsafe fn foo(); LL | unsafe fn foo();
| ^^^ | ^^^^^^ help: remove this qualifier
|
help: remove the qualifiers
|
LL | fn foo();
| ~~
error: aborting due to 3 previous errors error: aborting due to 3 previous errors