about summary refs log tree commit diff
path: root/compiler/rustc_ast_passes/src
diff options
context:
space:
mode:
authorArthur Carcano <arthur.carcano@ocamlpro.com>2024-04-03 02:43:54 +0200
committerArthur Carcano <arthur.carcano@ocamlpro.com>2024-04-04 11:58:38 +0200
commit109daa2d4bafc37b9e86a751b930aa033b7d4b14 (patch)
tree6593498c2364746537fce4f523e3dac89a707a1d /compiler/rustc_ast_passes/src
parent45796d1c24445b298567752519471cef2cff3298 (diff)
downloadrust-109daa2d4bafc37b9e86a751b930aa033b7d4b14.tar.gz
rust-109daa2d4bafc37b9e86a751b930aa033b7d4b14.zip
Fix diagnostic for qualifier in extern block
Closes: https://github.com/rust-lang/rust/issues/123306
Diffstat (limited to 'compiler/rustc_ast_passes/src')
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs29
-rw-r--r--compiler/rustc_ast_passes/src/errors.rs3
2 files changed, 25 insertions, 7 deletions
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 3edb832b9a0..96a10447393 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -514,13 +514,32 @@ impl<'a> AstValidator<'a> {
     }
 
     /// An `fn` in `extern { ... }` cannot have qualifiers, e.g. `async fn`.
-    fn check_foreign_fn_headerless(&self, ident: Ident, span: Span, header: FnHeader) {
-        if header.has_qualifiers() {
+    fn check_foreign_fn_headerless(
+        &self,
+        // Deconstruct to ensure exhaustiveness
+        FnHeader { unsafety, coroutine_kind, constness, ext }: FnHeader,
+    ) {
+        let report_err = |span| {
             self.dcx().emit_err(errors::FnQualifierInExtern {
-                span: ident.span,
+                span: 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, .. }) => {
                 self.check_defaultness(fi.span, *defaultness);
                 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);
             }
             ForeignItemKind::TyAlias(box TyAlias {
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index 9e8c1d7f5fd..8ae9f7d3966 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -270,11 +270,10 @@ pub struct FnBodyInExtern {
 #[diag(ast_passes_extern_fn_qualifiers)]
 pub struct FnQualifierInExtern {
     #[primary_span]
+    #[suggestion(code = "", applicability = "maybe-incorrect")]
     pub span: Span,
     #[label]
     pub block: Span,
-    #[suggestion(code = "fn ", applicability = "maybe-incorrect", style = "verbose")]
-    pub sugg_span: Span,
 }
 
 #[derive(Diagnostic)]