Skip to content

Implement parameter validation for functions using x86-interrupt abi. - #162457

Draft
Siech0 wants to merge 1 commit into
rust-lang:mainfrom
Siech0:fix/validate-x86-interrupt-frames-126418
Draft

Siech0 wants to merge 1 commit into
rust-lang:mainfrom
Siech0:fix/validate-x86-interrupt-frames-126418

Conversation

@Siech0

@Siech0 Siech0 commented Sep 8, 2026 •

Copy link
Copy Markdown

View all comments

Unsized parameters or zero sized parameters provided to an function with the x86-interrupt abi could emit ICE. Such parameters are conceptually invalid. This commit implements parameter validation logic for the x86-iterrupt ABI to prevent these error classes and to improve user diagnostics.

Relevant unstable feature: #40180
Fixes #124806
Fixes #126418
(May also close this, a reviewer's input would be optimal: #63018. It depends on what the desired resolution is, because current rules don't bound the size requirements of frame though they could be trivially added. The bug itself seems to be resolved at this point.)


LLM assistance disclosure: An LLM was used in the development of this PR, specifically for the following tasks:

  • Querying about the repository's structure, common types, and existing patterns
  • Preliminary code-review and style checks

There exists no LLM generated code, comments, documentation, or tests in this PR.

@rustbot

rustbot commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

HIR ty lowering was modified

cc @fmease

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Sep 8, 2026
@rustbot

rustbot commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the pull request, and welcome! The Rust Project has assigned @TaKO8Ki (or someone else) to review your changes, you should hear from them (or someone else) within the next two weeks.

Please see the contribution instructions and our LLM policy for more information.

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 75 candidates
  • Random selection from 20 candidates

@Siech0
Siech0 marked this pull request as draft September 8, 2026 07:21
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 8, 2026
@Siech0

Siech0 commented Sep 8, 2026 •

Copy link
Copy Markdown
Author

Converting to draft, while it passed unit tests locally I was able to cause an issue with the validator when running against code in the wild. I will reopen once resolved.

Specifically, this case fails:

struct Addr(u64);

#[repr(C)]
struct ComplexFrame { ip: Addr, cs: u64, flags: u64, sp: Addr, ss: u64 }

struct Idt { function_pointer_member_should_work: extern "x86-interrupt" fn(ComplexFrame) }

I'm adding it to my tests now as a regression test, and I'm going to try to figure out why this is happening. Getting this error:
ERROR: cycle detected when computing the inferred outlives-clauses for items in this crate [E0391]

My original design was based on the cmse.rs impl inside of hir_ty_lowering, I'm rebuilding my LLVM to see if I can find any odd behaviors with their implementation too.

@Siech0
Siech0 force-pushed the fix/validate-x86-interrupt-frames-126418 branch from d5d25f0 to 4610779 Compare September 8, 2026 08:31
@rust-log-analyzer

This comment has been minimized.

@Siech0

Siech0 commented Sep 8, 2026 •

Copy link
Copy Markdown
Author

With a fairly minimal refactor I moved it into check (I'm still not confident on where to integrate it, so advice would be welcome) and the cycle error is resolved against my tests, however, the validation no longer runs against function pointers.

I'm still a bit uphappy about that, but, for now, since I after running more tests on existing code (including the x86_64 crate) I found no regressions, I'm reopening.

@Siech0
Siech0 force-pushed the fix/validate-x86-interrupt-frames-126418 branch 2 times, most recently from 17c3dd0 to 123a52d Compare September 8, 2026 08:53
@Siech0
Siech0 marked this pull request as ready for review September 8, 2026 08:54
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Sep 8, 2026
@Siech0
Siech0 marked this pull request as draft September 8, 2026 18:02
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 8, 2026
@Siech0

Siech0 commented Sep 8, 2026 •

Copy link
Copy Markdown
Author

A quick reference for what shapes GCC/Clang/rustc allows / rejects (pre / post changes)

Charts

Assume 64-bits except if noted otherwise.

Rust types used:

#[repr(C)] pub struct Frame { ip: u64, cs: u64, flags: u64, sp: u64, ss: u64 }
#[repr(C)] pub struct FrameBool { ip: u64, b: bool }
#[repr(transparent)] pub struct Newtype(u64);
#[repr(C)] pub struct NonScalar { a: u8, b: u32 }
#[repr(u64)] pub enum Ec { A }
#[repr(u32)] pub enum EcInt { B }
pub enum Opt<T> { None, Some(T) }

C types used:

typedef unsigned long uword_t;
struct frame { uword_t ip, cs, flags, sp, ss; };
struct empty {};
struct nt { uword_t x; };
struct ns { unsigned char a; unsigned int b; };
struct fb { uword_t ip; _Bool b; };
enum ec : uword_t { EC_A };
enum ec_int { EC_B };
#define ISR __attribute__((interrupt))

Frame parameter

C signature Rust signature Clang GCC rustc nightly (before) rustc + PR
void ISR f(void *fr) _: *const u8 ok ok wrong code reject
void ISR f(struct frame *fr) _: &Frame ok ok wrong code reject
- _: *const [u8] n/a n/a wrong code reject
void ISR f(struct frame *fr) _: Opt<&Frame> ok ok wrong code reject
void ISR f(struct frame fr) _: Frame reject reject ok ok
void ISR f(unsigned char fr) _: u8 reject reject ok ok
void ISR f(uword_t fr) _: u64 reject reject ok ok
void ISR f(_Bool fr) _: bool reject reject accepted reject
void ISR f(struct fb fr) _: FrameBool reject reject accepted reject
void ISR f(struct empty fr) _: () reject reject ICE reject
void ISR f(void) (none) reject reject reject reject

Error code parameter

C signature Rust signature Clang GCC rustc nightly (before) rustc + PR
void ISR f(struct frame *fr, uword_t c) _: Frame, _: u64 ok ok ok ok
void ISR f(struct frame *fr, unsigned int c) _: Frame, _: u32 reject reject accepted reject
void ISR f(struct frame *fr, long c) _: Frame, _: i64 reject ok ok ok
void ISR f(struct frame *fr, unsigned char c) _: Frame, _: u8 reject reject accepted reject
void ISR f(struct frame *fr, unsigned short c) _: Frame, _: u16 reject reject accepted reject
void ISR f(struct frame *fr, __uint128_t c) _: Frame, _: u128 reject reject LLVM fatal reject
void ISR f(struct frame *fr, _Bool c) _: Frame, _: bool reject reject accepted reject
void ISR f(struct frame *fr, enum ec c) _: Frame, _: Ec ok reject accepted reject
void ISR f(struct frame *fr, enum ec_int c) _: Frame, _: EcInt reject reject accepted reject
void ISR f(struct frame *fr, struct nt c) _: Frame, _: Newtype reject reject ok ok
void ISR f(struct frame *fr, struct ns c) _: Frame, _: NonScalar reject reject LLVM fatal reject
void ISR f(struct frame *fr, void *c) _: Frame, _: *const u8 reject reject accepted reject
void ISR f(struct frame *fr, struct empty c) _: Frame, _: () reject reject wrong code reject
void ISR f(struct frame *fr, double c) _: Frame, _: f64 reject reject accepted reject

Whole-signature shape

C signature Rust signature Clang GCC rustc nightly (before) rustc + PR
void ISR f(struct frame *fr, uword_t c, uword_t d) _: Frame, _: u64, _: u64 reject reject reject reject
void ISR f(struct frame *fr, ...) _: Frame, _: ... ok ok reject reject
int ISR f(struct frame *fr) _: Frame) -> u8 reject reject reject reject

32-bit variants

C signature Rust signature Clang GCC rustc nightly (before) rustc + PR
void ISR f(struct frame fr) _: Frame reject reject ok ok
void ISR f(struct frame *fr, unsigned int c) _: Frame, _: u32 ok ok ok ok
void ISR f(struct frame *fr, unsigned long long c) _: Frame, _: u64 reject reject LLVM fatal reject
void ISR f(struct frame *fr, unsigned short c) _: Frame, _: u16 reject reject accepted reject

Notes

Most significant things I note is:

  • Error code table line 12, produced invalid code but emits an FFI safety warning anyway. Change promotes to rejection.
  • two instances where esotetic inputs could generate invalid assembly

Wrong Code (Array)

arr_code:
        push    rax
        push    rax
        push    rcx
        mov     rax, qword ptr [rsp + 24]  ; load the error into rax
        movzx   ecx, byte ptr [rax]            ; ERR: use the error code as address, read c[0] from it
        add     rcx, qword ptr [rsp + 32]   
        movzx   eax, byte ptr [rax + 2]     ; BAD: same address plus 2, read c[2] from it
        add     rax, rcx
        mov     rcx, qword ptr [rip + SINK@GOTPCREL]
        mov     qword ptr [rcx], rax
        pop     rcx
        pop     rax
        add     rsp, 16
        iretq

Basically, error code resides at [rsp + 24], we load it as a pointer into rax and then dereference it twice for accesses into c[0] and c[2]. let err_code == 2, we then dereference 0x2, causing a fault.

Wrong code (ZST Code)

no_code: ; zst code aliases this
        push    rax
        push    rcx
        mov     rax, qword ptr [rsp + 16] ; code thinks frame.ip (2*8 + 0)
                                                            ; however, if installed on a vector that uses code
                                                            ; we would actually be pointing at code rather than frame.ip.                        
        mov     rcx, qword ptr [rip + SINK@GOTPCREL]
        mov     qword ptr [rcx], rax
        pop     rcx
        pop     rax
        ; We don't add rsp, 16 here, so we don't drop the error code before iretq
        ; meaning the iretq here will actually use the error code instead of frame.ip
        iretq
        
zst_code = no_code

If we installed zst_code as a vector for a function that expected a code, the handler would fail because the CPU would still allocate the code onto the stack, but our code would still believe that rsp + 16 is the frame.ip, though it would actually be the inserted code. Additionally, we're missing add rsp, 16 before iretq, so iretq` pops the error code as frame.ip.

@Siech0
Siech0 force-pushed the fix/validate-x86-interrupt-frames-126418 branch from 123a52d to b4510f7 Compare September 8, 2026 22:22
@Siech0
Siech0 marked this pull request as ready for review September 9, 2026 00:21
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Sep 9, 2026
@Siech0

Siech0 commented Sep 9, 2026

Copy link
Copy Markdown
Author

I've implemented generics support and validated against most patterns. Not sure I got all patterns possible since the breadth of possible generic structures is quite high, but I tried to be thorough.

@rust-log-analyzer

This comment has been minimized.

@Siech0
Siech0 force-pushed the fix/validate-x86-interrupt-frames-126418 branch 2 times, most recently from b717173 to 7afa7f1 Compare September 9, 2026 05:37
@mu001999

mu001999 commented Oct 8, 2026

Copy link
Copy Markdown
Member

@rustbot reroll

@rustbot rustbot assigned dingxiangfei2009 and unassigned mu001999 Oct 8, 2026
@Siech0

Siech0 commented Oct 13, 2026 •

Copy link
Copy Markdown
Author

r? workingjubilee

Not sure if this is correct to do, but this has been tossed around a bit and this directly addresses (or seeks to, at least) a TODO left in your name.

@rustbot

rustbot commented Oct 13, 2026

Copy link
Copy Markdown
Collaborator

workingjubilee is currently at their maximum review capacity.
They may take a while to respond.

@workingjubilee

Copy link
Copy Markdown
Member

@Siech0 It is correct as long as you are patient. A moment.

@workingjubilee

Copy link
Copy Markdown
Member

So, it is not actually clear to me that zero-sized parameters must be rejected here as long as they are also zero-aligned. They would be skipped over when lowering to LLVMIR, of course, like we usually do with such arguments.

(...usually.)

#132835 is actually more along the lines of my concern. I reopened that issue.

@workingjubilee

Copy link
Copy Markdown
Member

This would require fixing the codegen to actually ignore it though, of course.

@workingjubilee workingjubilee left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Despite saying that, rejecting ZSTs here is probably easier than that, and we can always relax later if we care, even without stability concerns for this wildly unstable feature. So I can probably accept this if we fix some of this up a little, and we can address the zero-sized codegen thing in a separate PR if and only if you are interested, and then just relax that restriction. I don't want to quibble too much on the proper implementation of a feature I'm not sure will ever reach stable.

View changes since this review

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 30, 2026
@rustbot

rustbot commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator

Reminder, once the PR becomes ready for a review, use @rustbot ready.

// 1. 1-2 parameters (validated in AST layer)
// 2. Neither type may be unsized -> X86InterruptUnsized
// 3. Neither type may be zero-sized -> X86InterruptZeroSized
// 4. First parameter (frame) must be valid for any bit pattern -> X86InterruptInvalidFrame

@workingjubilee workingjubilee Oct 30, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really understand the intent of this restriction.

If we consider this: https://docs.rs/x86_64/latest/src/x86_64/structures/idt.rs.html#1078-1095

If those "reserved" segments were replaced by padding, which would require adjusting a bunch of details about the struct but could be done at least partially, what would be incorrect about it? It's not like the CPU reads the ISR's frame back, right? We're not relying on writing to this, yeah?

View changes since the review

@Siech0 Siech0 Oct 31, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may have been overly reading into (and probably misinterpreting!) the requirements of 'safe' rust. Currently the x86-interrupt abi doesn't explicitly require us to mark functions as unsafe, so I assumed data received in the signature must be valid according to those rules.

My thinking on the matter was that rust disallows types like bool to contain bit-signatures out of their range (i.e, bool may be 0 or 1, but 2 or 3 would be invalid), so following that logic, something like 5 bools separated by usize-1 padding should be invalid because the processor could hand you bit patterns outside of their valid range. Most Frame types I saw in the wild met this condition (usually just multiple usizes) and so I thought it was a fairly reasonable requirement at the time of writing.

In hindsight, my logic seems a bit flawed and overly terse but I still feel like there should be some level of requirement here but at the very least the array of bools case is certainly invalid? Do you think that simply removing the constraint is the reasonable way forward, or should we replace it with something less terse?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So what you pointed out is actually a deeply interesting question, and is sort of at the heart of the problem of this ABI.

In Rust code, we only discharge an unsafe obligation on calling a function. How then do we describe the safety obligations of a function that must describe a correct signature in order for it to work, but which is called by an external force? Namely, the CPU's interrupt-handling firmware.

For extern things, in Edition 2024 we decided to make it so that every site which defines FFI functions and types like that is itself unsafe, e.g.

unsafe extern "C" {
   fn blah();
}

fn main() {
    unsafe { blah() };
}

That is because merely linking the wrong thing... which is essentially what that declaration tries to do... can have negative effects if the signature is wrong. Your program can go to all sorts of exciting places if you misdeclare malloc, for example.

The unsafety of declaration does not inhere in the function we call, but which is why we allowed declaring functions safe at the same time. It still defaults to unsafe, because other languages don't have the same... ah, philosophy... that Rust does. Rust also is allowed to define a new extern "C" fn that is itself safe to call from Rust, and also can be called correctly by external C code:

unsafe extern "C" {
   safe fn safe_blah();
}

extern "C" fn rust_blah() {}

fn main() {
    // look ma, no unsafe!
    rust_blah();
    safe_blah();
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...So the answer is "that actually is an entirely different category of safety obligation that we don't have the linguistic expressiveness to discharge properly if we decide to place it on the programmer".

@workingjubilee workingjubilee Oct 31, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I do kinda see where you're coming from: since no programmer can handle the obligation due to lacking language surface, let the compiler handle it! But... do we actually handle it? Is it impossible, after this PR, to not create a miscompiled function or one that reads de facto uninit memory by declaring, say, a 1000-byte stack frame?

@workingjubilee workingjubilee Nov 1, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Siech0 Also, sorry if my blather was a bit hard to read, I had lost a better-edited version and kinda rushed rewriting it.

Right, I had also pointed out that I explained that every unsafe fn does not itself make its contents unsafe code, which is what motivated the unsafe_op_in_unsafe_fn lint, e.g. Vec::set_len.

For note, it's not necessary for you to make a hard decision here or make this perfect for me to merge this PR!

I'm just wondering about this particular restriction because I am not sure it is either necessary or sufficient (i.e. it's not clear this over-restriction is enough) for safety here. If decls of these functions raise a hard problem here we can't easily resolve in the compiler, I can take that to lang and you don't have to get involved.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your write-up was informative, I think I mostly understand what you're getting at though I think some of it is a bit beyond my comprehension.

I've thought about it some and I think there a few ideas that might be an improvement:

  1. Simple size bounds ( frame <= 5 * usize ), alignment <= pointer size, drop requirement 4 in favor of this. This doesn't catch some UB but at least doesn't overcorrect for it.
  2. A compiler known InterruptStackFrame type, like how we handle VaList for the variadics ABI. This kinda has a precedent, but it feels like a bit of a stretch to me.
  3. We hand the frame via pointer like LLVM and GCC do, the deref safety obligation is moved to the body which is expressible. I think prior designs for the feature did this and they were changed and it is more in line with how the backend operates. I'm not sure if my memory is faulty or not. If there was a change, I don't know the rationale. Frankly, this seems like it quashes the majority of the can of worms because we can delegate correctness to the user. This change would probably be very much non-trivial and its probably not something I could accomplish at my current understanding level.
  4. We mark the ABI definition unsafe? I suppose this goes into what you were mentioning when talking with lang. (Though the full understanding of the implications is beyond me).

As an aside on the ZST parameters which I failed to fully cover:

  • Frame: Allowing a ZST frame may be sensible, its essentially just us saying that we won't read / write with the parameter at all and we don't particularly care what its structure is.
  • Error Code: Allowing a ZST error code may also be sensible, its essentially just us saying that we won't read / write with the parameter at all and we don't particularly care what its structure is. Currently this results in code-gen which aliases the function onto the frame-only ABI which results in the Wrong code (ZST Code) error I marked above.

We could drop the ZST exclusion then if we think its sensible and just solve the code-gen and ICE issue to support them.

@workingjubilee workingjubilee Nov 3, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re: #4, that is what I was waving in the direction of as not-communicable, yes, or rather not communicative?

Saying every extern "x86-interrupt" function is also unsafe does not immediately make it clear we are saying that the function is unsafe to declare incorrectly, because the "normal" meaning of unsafe fn is that you have to write

unsafe { unsafe_fn() };

This notably says nothing about the actual contents of the unsafe fn or the declaration thereof, which are correctly handled by the Rust compiler for "normal" ABIs. Due to permissiveness in early Rust, you can declare an unsafe extern "C" fn that doesn't actually make much sense to C because it includes types that lack a representation in your platform's C ABI! ...but if anyone calls it, the ABI will be correct, even if it's more the, er, "Rust-enhanced C ABI". You can't cause the code to miscompile just because you gave such a "naughty" signature.

...well, the pile of bugs labeled A-ABI suggest "correctly" and "can't" is a bit of a stretch but it's the compiler's problem, not theirs.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If, knowing this is technically "not the right way", you believe demanding these are unsafe fn will make people wary of misdeclaration concerns... yeah I'll believe that and I'm happy to ship it as a mitigation for the current feature.

@workingjubilee workingjubilee Nov 9, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Siech0 That aside, I think the first solution makes sense to me also and does seem simple. Exploring the 3rd approach and clearly identifying the reason to do it by-value should probably be required for stabilization of this feature, but that's not a concern we have to solve today.

@workingjubilee

workingjubilee commented Oct 30, 2026 •

Copy link
Copy Markdown
Member

A quick reference for what shapes GCC/Clang/rustc allows / rejects (pre / post changes)

Originally posted by @Siech0 in #162457 (comment)

quick, you say.

@workingjubilee

Copy link
Copy Markdown
Member

You drew attention to this case of these two signatures, @Siech0:

void ISR f(struct frame *fr, unsigned char c[3])
fn isr(_: Frame, _: [u8; 3])

So, for the first parameter, in Rust we take the stack frame as a by-value argument, and in C it is a pointer to a stack frame. But as you might guess, the same thing happens in both languages and this is merely identifying data on your stack. The pointerness of it or not is irrelevant.

But in the second parameter, you highlighted unsigned char c[3] and [u8; 3].

These are not equivalent signatures in C and Rust. The first one is genuinely actually a pointer, and is not even required to be of the length suggested by the signature because of course, C doesn't verify that. Meanwhile, in Rust, this is generally bundled into a by-value wad of data we pass along.

That's why there is an FFI safety warning. So, for the Rust case, whatever C compilers do is irrelevant here because there's no equivalent.

@workingjubilee

Copy link
Copy Markdown
Member

For the bad assembly cases, you didn't clearly identify which Rust signatures generated each? I'm a little confused.

@Siech0

Siech0 commented Oct 31, 2026

Copy link
Copy Markdown
Author

For the bad assembly cases, you didn't clearly identify which Rust signatures generated each? I'm a little confused.

Sorry, I originally had that comment written out. I generated the data via a python script that would compile each and every case and record behaviors. Originally I had updated the table by hand to add my additional research on the miscompilations I found but I later added more cases and regenerated it (and forgot to update the links.) I'll spend some time this weekend trying to see if I can remember / recreate the exact cases that I did research on, but it has been a while.

Off the top of my head, I believe Wrong Code (Array) originally referred to behavior encountered when using a slice for the code parameter (i.e, (Frame, [u8; 4])). Wrong Code (ZST) originally referred to when the code parameter was a ZST, (i.e, (Frame, ()).

@Siech0

Siech0 commented Oct 31, 2026

Copy link
Copy Markdown
Author

A quick reference for what shapes GCC/Clang/rustc allows / rejects (pre / post changes)

Originally posted by @Siech0 in #162457 (comment)

quick, you say.

Given the relative length that it could be.. perhaps? I tried to pretty comprehensively cover as many bases as I could while also not writing a full book on it.

@Siech0

Siech0 commented Oct 31, 2026

Copy link
Copy Markdown
Author

You drew attention to this case of these two signatures, @Siech0:

void ISR f(struct frame *fr, unsigned char c[3])
fn isr(_: Frame, _: [u8; 3])

So, for the first parameter, in Rust we take the stack frame as a by-value argument, and in C it is a pointer to a stack frame. But as you might guess, the same thing happens in both languages and this is merely identifying data on your stack. The pointerness of it or not is irrelevant.

But in the second parameter, you highlighted unsigned char c[3] and [u8; 3].

These are not equivalent signatures in C and Rust. The first one is genuinely actually a pointer, and is not even required to be of the length suggested by the signature because of course, C doesn't verify that. Meanwhile, in Rust, this is generally bundled into a by-value wad of data we pass along.

That's why there is an FFI safety warning. So, for the Rust case, whatever C compilers do is irrelevant here because there's no equivalent.

Good catch, I'll update the table, I wrote a lot of this undercaffinated and late into night.

Unsized parameters or zero sized parameters provided to an function
with the x86-interrupt abi could emit ICE. Such parameters are
conceptually invalid. This commit implements parameter validation
logic for the x86-iterrupt ABI to prevent these error classes
and to improve user diagnostics.
@Siech0
Siech0 force-pushed the fix/validate-x86-interrupt-frames-126418 branch from bd36627 to 49a426f Compare October 31, 2026 19:28
@rustbot

rustbot commented Oct 31, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job test-aarch64-gnu-llvm-22-1 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
test [ui] tests/ui/zero-sized/zero-sized-btreemap-insert.rs ... ok

failures:

---- [ui] tests/ui/abi/x86-interrupt-param-types.rs#i686 stdout ----
Saved the actual stderr to `/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/abi/x86-interrupt-param-types.i686/x86-interrupt-param-types.i686.stderr`
diff of stderr:

122    |                                                           ^^
123    |
124    = note: invalid x86-interrupt error code parameter type: `u8`
-    = note: functions with the "x86-interrupt" ABI must have a machine-word sized integer error code parameter that is valid for any bit pattern
+    = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern
126 
127 error: invalid signature for `extern "x86-interrupt"` function
128   --> $DIR/x86-interrupt-param-types.rs:100:60

131    |                                                            ^^^
132    |
133    = note: invalid x86-interrupt error code parameter type: `u16`
-    = note: functions with the "x86-interrupt" ABI must have a machine-word sized integer error code parameter that is valid for any bit pattern
+    = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern
135 
136 error: invalid signature for `extern "x86-interrupt"` function
137   --> $DIR/x86-interrupt-param-types.rs:103:66

140    |                                                                  ^^^
141    |
142    = note: invalid x86-interrupt error code parameter type: `u64`
-    = note: functions with the "x86-interrupt" ABI must have a machine-word sized integer error code parameter that is valid for any bit pattern
+    = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern
144 
145 error: invalid signature for `extern "x86-interrupt"` function
146   --> $DIR/x86-interrupt-param-types.rs:109:70

149    |                                                                      ^^^^^^^^^^^
150    |
151    = note: invalid x86-interrupt error code parameter type: `NonScalar32`
-    = note: functions with the "x86-interrupt" ABI must have a machine-word sized integer error code parameter that is valid for any bit pattern
+    = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern
153 
154 error: invalid signature for `extern "x86-interrupt"` function
155   --> $DIR/x86-interrupt-param-types.rs:114:64

158    |                                                                ^^^^^^^^^
159    |
160    = note: invalid x86-interrupt error code parameter type: `*const u8`
-    = note: functions with the "x86-interrupt" ABI must have a machine-word sized integer error code parameter that is valid for any bit pattern
+    = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern
162 
163 error: invalid signature for `extern "x86-interrupt"` function
164   --> $DIR/x86-interrupt-param-types.rs:116:68

167    |                                                                    ^^^^^^^
168    |
169    = note: invalid x86-interrupt error code parameter type: `*mut u8`
-    = note: functions with the "x86-interrupt" ABI must have a machine-word sized integer error code parameter that is valid for any bit pattern
+    = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern
171 
172 error: invalid signature for `extern "x86-interrupt"` function
173   --> $DIR/x86-interrupt-param-types.rs:118:61

176    |                                                             ^^^^
177    |
178    = note: invalid x86-interrupt error code parameter type: `u128`
-    = note: functions with the "x86-interrupt" ABI must have a machine-word sized integer error code parameter that is valid for any bit pattern
+    = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern
180 
181 error: invalid signature for `extern "x86-interrupt"` function
182   --> $DIR/x86-interrupt-param-types.rs:120:61

185    |                                                             ^^^^
186    |
187    = note: invalid x86-interrupt error code parameter type: `bool`
-    = note: functions with the "x86-interrupt" ABI must have a machine-word sized integer error code parameter that is valid for any bit pattern
+    = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern
189 
190 error: invalid signature for `extern "x86-interrupt"` function
191   --> $DIR/x86-interrupt-param-types.rs:122:62

194    |                                                              ^^^^^^^
195    |
196    = note: invalid x86-interrupt error code parameter type: `[u8; 3]`
-    = note: functions with the "x86-interrupt" ABI must have a machine-word sized integer error code parameter that is valid for any bit pattern
+    = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern
198 
199 error: invalid signature for `extern "x86-interrupt"` function
200   --> $DIR/x86-interrupt-param-types.rs:124:61

203    |                                                             ^^^^^^^^
204    |
205    = note: invalid x86-interrupt error code parameter type: `Enumtype`
-    = note: functions with the "x86-interrupt" ABI must have a machine-word sized integer error code parameter that is valid for any bit pattern
+    = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern
207 
208 error: invalid signature for `extern "x86-interrupt"` function
209   --> $DIR/x86-interrupt-param-types.rs:130:68

212    |                                                                    ^^^
213    |
214    = note: invalid x86-interrupt error code parameter type: `f32`
-    = note: functions with the "x86-interrupt" ABI must have a machine-word sized integer error code parameter that is valid for any bit pattern
+    = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern
216 
217 error: invalid signature for `extern "x86-interrupt"` function
218   --> $DIR/x86-interrupt-param-types.rs:132:61

221    |                                                             ^^^^
222    |
223    = note: invalid x86-interrupt error code parameter type: `char`
-    = note: functions with the "x86-interrupt" ABI must have a machine-word sized integer error code parameter that is valid for any bit pattern
+    = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern
225 
226 error: invalid signature for `extern "x86-interrupt"` function
227   --> $DIR/x86-interrupt-param-types.rs:155:60

302    |                                                 ^^^^^^^^
303    |
304    = note: invalid x86-interrupt error code parameter type: `Enumtype`
-    = note: functions with the "x86-interrupt" ABI must have a machine-word sized integer error code parameter that is valid for any bit pattern
+    = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern
306 
307 error: aborting due to 34 previous errors
308 


The actual stderr differed from the expected stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args abi/x86-interrupt-param-types.rs`

error in revision `i686`: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/abi/x86-interrupt-param-types.rs" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--cfg" "i686" "--check-cfg" "cfg(test,FALSE,x64,i686)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/abi/x86-interrupt-param-types.i686" "-Znext-solver=coherence" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "incomplete_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers" "-Cpanic=abort" "-Cforce-unwind-tables=yes" "--edition=2015" "--target=i686-unknown-linux-gnu" "--crate-type=rlib" "--extern" "minicore=/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/abi/x86-interrupt-param-types.i686/libminicore.rlib"
stdout: none
--- stderr -------------------------------
error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:68:55
   |
LL | extern "x86-interrupt" fn test_frame_unsized_fails(_: str) {}
   |                                                       ^^^
   |
   = note: invalid x86-interrupt parameter type: `str`
   = note: functions with the "x86-interrupt" ABI must not use unsized types in their signature

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:70:51
   |
LL | extern "x86-interrupt" fn test_frame_zst_fails(_: ()) {}
   |                                                   ^^
   |
   = note: invalid x86-interrupt parameter type: `()`
   = note: functions with the "x86-interrupt" ABI must not use zero-sized types in their signature

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:72:52
   |
LL | extern "x86-interrupt" fn test_frame_bool_fails(_: bool) {}
   |                                                    ^^^^
   |
   = note: invalid x86-interrupt frame parameter type: `bool`
   = note: functions with the "x86-interrupt" ABI must have a non-pointer frame parameter that is valid for any bit pattern

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:74:52
   |
LL | extern "x86-interrupt" fn test_frame_char_fails(_: char) {}
   |                                                    ^^^^
   |
   = note: invalid x86-interrupt frame parameter type: `char`
   = note: functions with the "x86-interrupt" ABI must have a non-pointer frame parameter that is valid for any bit pattern

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:76:61
   |
LL | extern "x86-interrupt" fn test_frame_indirect_bool_fails(_: NewBool) {}
   |                                                             ^^^^^^^
   |
   = note: invalid x86-interrupt frame parameter type: `NewBool`
   = note: functions with the "x86-interrupt" ABI must have a non-pointer frame parameter that is valid for any bit pattern

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:78:55
   |
LL | extern "x86-interrupt" fn test_frame_pointer_fails(_: *const u8) {}
   |                                                       ^^^^^^^^^
   |
   = note: invalid x86-interrupt frame parameter type: `*const u8`
   = note: functions with the "x86-interrupt" ABI must have a non-pointer frame parameter that is valid for any bit pattern

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:80:59
   |
LL | extern "x86-interrupt" fn test_frame_mut_pointer_fails(_: *mut u8) {}
   |                                                           ^^^^^^^
   |
   = note: invalid x86-interrupt frame parameter type: `*mut u8`
   = note: functions with the "x86-interrupt" ABI must have a non-pointer frame parameter that is valid for any bit pattern

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:82:57
   |
LL | extern "x86-interrupt" fn test_frame_reference_fails(_: &Frame) {}
   |                                                         ^^^^^^
   |
   = note: invalid x86-interrupt frame parameter type: `&Frame`
   = note: functions with the "x86-interrupt" ABI must have a non-pointer frame parameter that is valid for any bit pattern

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:84:61
   |
LL | extern "x86-interrupt" fn test_frame_mut_reference_fails(_: &mut Frame) {}
   |                                                             ^^^^^^^^^^
   |
   = note: invalid x86-interrupt frame parameter type: `&mut Frame`
   = note: functions with the "x86-interrupt" ABI must have a non-pointer frame parameter that is valid for any bit pattern

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:86:66
   |
LL | extern "x86-interrupt" fn test_frame_optional_reference_fails(_: Opt<&Frame>) {}
   |                                                                  ^^^^^^^^^^^
   |
   = note: invalid x86-interrupt frame parameter type: `Opt<&Frame>`
   = note: functions with the "x86-interrupt" ABI must have a non-pointer frame parameter that is valid for any bit pattern

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:88:70
   |
LL | extern "x86-interrupt" fn test_frame_optional_mut_reference_fails(_: Opt<&mut Frame>) {}
   |                                                                      ^^^^^^^^^^^^^^^
   |
   = note: invalid x86-interrupt frame parameter type: `Opt<&mut Frame>`
   = note: functions with the "x86-interrupt" ABI must have a non-pointer frame parameter that is valid for any bit pattern

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:94:64
   |
LL | extern "x86-interrupt" fn test_code_unsized_fails(_: Frame, _: str) {}
   |                                                                ^^^
   |
   = note: invalid x86-interrupt parameter type: `str`
   = note: functions with the "x86-interrupt" ABI must not use unsized types in their signature

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:96:60
   |
LL | extern "x86-interrupt" fn test_code_zst_fails(_: Frame, _: ()) {}
   |                                                            ^^
   |
   = note: invalid x86-interrupt parameter type: `()`
   = note: functions with the "x86-interrupt" ABI must not use zero-sized types in their signature

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:98:59
   |
LL | extern "x86-interrupt" fn test_code_u8_fails(_: Frame, _: u8) {}
   |                                                           ^^
   |
   = note: invalid x86-interrupt error code parameter type: `u8`
   = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:100:60
   |
LL | extern "x86-interrupt" fn test_code_u16_fails(_: Frame, _: u16) {}
   |                                                            ^^^
   |
   = note: invalid x86-interrupt error code parameter type: `u16`
   = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:103:66
   |
LL | extern "x86-interrupt" fn test_code_32bit_u64_fails(_: Frame, _: u64) {}
   |                                                                  ^^^
   |
   = note: invalid x86-interrupt error code parameter type: `u64`
   = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:109:70
   |
LL | extern "x86-interrupt" fn test_code_non_scalar_32_fails(_: Frame, _: NonScalar32) {}
   |                                                                      ^^^^^^^^^^^
   |
   = note: invalid x86-interrupt error code parameter type: `NonScalar32`
   = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:114:64
   |
LL | extern "x86-interrupt" fn test_code_pointer_fails(_: Frame, _: *const u8) {}
   |                                                                ^^^^^^^^^
   |
   = note: invalid x86-interrupt error code parameter type: `*const u8`
   = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:116:68
   |
LL | extern "x86-interrupt" fn test_code_mut_pointer_fails(_: Frame, _: *mut u8) {}
   |                                                                    ^^^^^^^
   |
   = note: invalid x86-interrupt error code parameter type: `*mut u8`
   = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:118:61
   |
LL | extern "x86-interrupt" fn test_code_u128_fails(_: Frame, _: u128) {}
   |                                                             ^^^^
   |
   = note: invalid x86-interrupt error code parameter type: `u128`
   = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:120:61
   |
LL | extern "x86-interrupt" fn test_code_bool_fails(_: Frame, _: bool) {}
   |                                                             ^^^^
   |
   = note: invalid x86-interrupt error code parameter type: `bool`
   = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:122:62
   |
LL | extern "x86-interrupt" fn test_code_array_fails(_: Frame, _: [u8; 3]) {}
   |                                                              ^^^^^^^
   |
   = note: invalid x86-interrupt error code parameter type: `[u8; 3]`
   = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:124:61
   |
LL | extern "x86-interrupt" fn test_code_enum_fails(_: Frame, _: Enumtype) {}
   |                                                             ^^^^^^^^
   |
   = note: invalid x86-interrupt error code parameter type: `Enumtype`
   = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:130:68
   |
LL | extern "x86-interrupt" fn test_code_32bit_float_fails(_: Frame, _: f32) {}
   |                                                                    ^^^
   |
   = note: invalid x86-interrupt error code parameter type: `f32`
   = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:132:61
   |
LL | extern "x86-interrupt" fn test_code_char_fails(_: Frame, _: char) {}
   |                                                             ^^^^
   |
   = note: invalid x86-interrupt error code parameter type: `char`
   = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:155:60
   |
LL |     extern "x86-interrupt" fn test_impl_frame_zst_fails(_: ()) {}
   |                                                            ^^
   |
   = note: invalid x86-interrupt parameter type: `()`
   = note: functions with the "x86-interrupt" ABI must not use zero-sized types in their signature

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:157:64
   |
LL |     extern "x86-interrupt" fn test_impl_frame_unsized_fails(_: str) {}
   |                                                                ^^^
   |
   = note: invalid x86-interrupt parameter type: `str`
   = note: functions with the "x86-interrupt" ABI must not use unsized types in their signature

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:159:69
   |
LL |     extern "x86-interrupt" fn test_impl_code_zst_fails(_: Frame, _: ()) {}
   |                                                                     ^^
   |
   = note: invalid x86-interrupt parameter type: `()`
   = note: functions with the "x86-interrupt" ABI must not use zero-sized types in their signature

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:161:73
   |
LL |     extern "x86-interrupt" fn test_impl_code_unsized_fails(_: Frame, _: str) {}
   |                                                                         ^^^
   |
   = note: invalid x86-interrupt parameter type: `str`
   = note: functions with the "x86-interrupt" ABI must not use unsized types in their signature

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:176:39
   |
LL |     fn test_extern_frame_zst_fails(_: ());
   |                                       ^^
   |
   = note: invalid x86-interrupt parameter type: `()`
   = note: functions with the "x86-interrupt" ABI must not use zero-sized types in their signature

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:178:43
   |
LL |     fn test_extern_frame_unsized_fails(_: str);
   |                                           ^^^
   |
   = note: invalid x86-interrupt parameter type: `str`
   = note: functions with the "x86-interrupt" ABI must not use unsized types in their signature

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:180:48
   |
LL |     fn test_extern_code_zst_fails(_: Frame, _: ());
   |                                                ^^
   |
   = note: invalid x86-interrupt parameter type: `()`
   = note: functions with the "x86-interrupt" ABI must not use zero-sized types in their signature

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:182:52
   |
LL |     fn test_extern_code_unsized_fails(_: Frame, _: str);
   |                                                    ^^^
   |
   = note: invalid x86-interrupt parameter type: `str`
   = note: functions with the "x86-interrupt" ABI must not use unsized types in their signature

error: invalid signature for `extern "x86-interrupt"` function
##[error]  --> /checkout/tests/ui/abi/x86-interrupt-param-types.rs:184:49
   |
LL |     fn test_extern_code_enum_fails(_: Frame, _: Enumtype);
   |                                                 ^^^^^^^^
   |
   = note: invalid x86-interrupt error code parameter type: `Enumtype`
   = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern

error: aborting due to 34 previous errors
------------------------------------------

---- [ui] tests/ui/abi/x86-interrupt-param-types.rs#i686 stdout end ----
---- [ui] tests/ui/abi/x86-interrupt-param-types.rs#x64 stdout ----
Saved the actual stderr to `/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/abi/x86-interrupt-param-types.x64/x86-interrupt-param-types.x64.stderr`
diff of stderr:

122    |                                                           ^^
123    |
124    = note: invalid x86-interrupt error code parameter type: `u8`
-    = note: functions with the "x86-interrupt" ABI must have a machine-word sized integer error code parameter that is valid for any bit pattern
+    = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern
126 
127 error: invalid signature for `extern "x86-interrupt"` function
128   --> $DIR/x86-interrupt-param-types.rs:100:60

131    |                                                            ^^^
132    |
133    = note: invalid x86-interrupt error code parameter type: `u16`
-    = note: functions with the "x86-interrupt" ABI must have a machine-word sized integer error code parameter that is valid for any bit pattern
+    = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern
135 
136 error: invalid signature for `extern "x86-interrupt"` function
137   --> $DIR/x86-interrupt-param-types.rs:106:66

140    |                                                                  ^^^
141    |
142    = note: invalid x86-interrupt error code parameter type: `u32`
-    = note: functions with the "x86-interrupt" ABI must have a machine-word sized integer error code parameter that is valid for any bit pattern
+    = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern
144 
145 error: invalid signature for `extern "x86-interrupt"` function
146   --> $DIR/x86-interrupt-param-types.rs:112:70

149    |                                                                      ^^^^^^^^^^^
150    |
151    = note: invalid x86-interrupt error code parameter type: `NonScalar64`
-    = note: functions with the "x86-interrupt" ABI must have a machine-word sized integer error code parameter that is valid for any bit pattern
+    = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern
153 
154 error: invalid signature for `extern "x86-interrupt"` function
155   --> $DIR/x86-interrupt-param-types.rs:114:64

158    |                                                                ^^^^^^^^^
159    |
160    = note: invalid x86-interrupt error code parameter type: `*const u8`
-    = note: functions with the "x86-interrupt" ABI must have a machine-word sized integer error code parameter that is valid for any bit pattern
+    = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern
162 
163 error: invalid signature for `extern "x86-interrupt"` function
164   --> $DIR/x86-interrupt-param-types.rs:116:68

167    |                                                                    ^^^^^^^
168    |
169    = note: invalid x86-interrupt error code parameter type: `*mut u8`
-    = note: functions with the "x86-interrupt" ABI must have a machine-word sized integer error code parameter that is valid for any bit pattern
+    = note: functions with the "x86-interrupt" ABI must have a usize error code parameter that is valid for any bit pattern
171 

@workingjubilee

Copy link
Copy Markdown
Member

It is completely okay to be wrong about something, especially something that does not particularly define the correctness of the PR itself. It just seemed important to actually reply to you calling attention to it, since, human conversation and all that. "All we need to do is make sure we keep talking".

@Siech0
Siech0 marked this pull request as draft November 1, 2026 04:17
@rust-bors

rust-bors Bot commented Nov 12, 2026

Copy link
Copy Markdown
Contributor

☔ The latest upstream changes (presumably #165876) made this pull request unmergeable. Please resolve the merge conflicts by rebasing.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ICE: Tried to make Ignore indirect ICE: used byval ABI for unsized layout

8 participants