about summary refs log tree commit diff
path: root/compiler/rustc_ast_passes
diff options
context:
space:
mode:
authorPavel Grigorenko <GrigorenkoPV@ya.ru>2025-08-20 14:34:48 +0300
committerPavel Grigorenko <GrigorenkoPV@ya.ru>2025-08-20 18:03:57 +0300
commit2da0ec345300464c9881e8556dcf233d3cc9a724 (patch)
tree6c6466c5895cdc0b4bd591e53a2bb28a10e2f371 /compiler/rustc_ast_passes
parentbec747418c9955de4c3fd0aac4acb99206f00aa2 (diff)
downloadrust-2da0ec345300464c9881e8556dcf233d3cc9a724.tar.gz
rust-2da0ec345300464c9881e8556dcf233d3cc9a724.zip
Enforce correct number of arguments for `"x86-interrupt"` functions
Diffstat (limited to 'compiler/rustc_ast_passes')
-rw-r--r--compiler/rustc_ast_passes/messages.ftl4
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs11
-rw-r--r--compiler/rustc_ast_passes/src/errors.rs9
3 files changed, 24 insertions, 0 deletions
diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl
index 73cbcdd30ce..c0679c1b8ff 100644
--- a/compiler/rustc_ast_passes/messages.ftl
+++ b/compiler/rustc_ast_passes/messages.ftl
@@ -20,6 +20,10 @@ ast_passes_abi_must_not_have_return_type=
     .note = functions with the {$abi} ABI cannot have a return type
     .help = remove the return type
 
+ast_passes_abi_x86_interrupt =
+    invalid signature for `extern "x86-interrupt"` function
+    .note = functions with the "x86-interrupt" ABI must be have either 1 or 2 parameters (but found {$param_count})
+
 ast_passes_assoc_const_without_body =
     associated constant in `impl` without body
     .suggestion = provide a definition for the constant
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 0c72f319007..f85993b3378 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -405,6 +405,17 @@ impl<'a> AstValidator<'a> {
                         if let InterruptKind::X86 = interrupt_kind {
                             // "x86-interrupt" is special because it does have arguments.
                             // FIXME(workingjubilee): properly lint on acceptable input types.
+                            let inputs = &sig.decl.inputs;
+                            let param_count = inputs.len();
+                            if !matches!(param_count, 1 | 2) {
+                                let mut spans: Vec<Span> =
+                                    inputs.iter().map(|arg| arg.span).collect();
+                                if spans.is_empty() {
+                                    spans = vec![sig.span];
+                                }
+                                self.dcx().emit_err(errors::AbiX86Interrupt { spans, param_count });
+                            }
+
                             if let FnRetTy::Ty(ref ret_ty) = sig.decl.output
                                 && match &ret_ty.kind {
                                     TyKind::Never => false,
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index 5ecc0d21411..b9b2d271954 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -891,3 +891,12 @@ pub(crate) struct AbiMustNotHaveReturnType {
     pub span: Span,
     pub abi: ExternAbi,
 }
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_abi_x86_interrupt)]
+#[note]
+pub(crate) struct AbiX86Interrupt {
+    #[primary_span]
+    pub spans: Vec<Span>,
+    pub param_count: usize,
+}