Skip to content

wasm: correctly implement union trivial aggregates - #162806

Merged
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
folkertdev:wasm-union-abi
Sep 15, 2026
Merged

rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
folkertdev:wasm-union-abi

Conversation

@folkertdev

@folkertdev folkertdev commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

A union with two scalar fields, even if they overlap exactly, is not a trivial aggregate, based on the implementation in clang:

https://github.com/llvm/llvm-project/blob/e78970f80f1041de8948cb0b665a9aaae682f6c6/clang/lib/CodeGen/ABIInfoImpl.cpp#L338-L402

It never explicitly considers unions, but essentially views them as records. The clang implementation is a plausible interpretation of the specification (though I'd like it to be a bit clearer):

https://github.com/WebAssembly/tool-conventions/blob/83e5d715d0c18aee51e2d5ae9434f22d67b6e905/BasicCABI.md#function-arguments-and-return-values

[2] Any struct or union that recursively (including through nested structs, unions, and arrays) contains just a single scalar value and is not specified to have greater than natural alignment.

We previously got this wrong. I also don't think this was really tested very well, so I added a bunch of test for various cases.

This change moves away from using the homogeneous_aggregate method, which is convenient because it is a bit broken and now we don't have to consider wasm when we fix that.

I've validated this against clang with abi-cafe.

r? alexcrichton

A union with two scalar fields, even if they overlap exactly, is not a trivial aggregate
@folkertdev folkertdev added O-wasm Target: WASM (WebAssembly), http://webassembly.org/ A-ABI Area: Concerning the application binary interface (ABI) labels Sep 15, 2026
@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 15, 2026
@alexcrichton

Copy link
Copy Markdown
Member

@bors r+

Thanks!

@rust-bors

rust-bors Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

📌 Commit 417882b has been approved by alexcrichton

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 15, 2026
rust-bors Bot pushed a commit that referenced this pull request Sep 15, 2026
…uwer

Rollup of 3 pull requests

Successful merges:

 - #162463 (Fix ICE in GVN that interns allocation containing provenance)
 - #162806 (wasm: correctly implement `union` trivial aggregates)
 - #162711 (cleanup: Move consumed predicate obligations into recursive evaluation)
@hanna-kruppe

Copy link
Copy Markdown
Contributor

Sounds like this fixes #121408, thanks :)

As I found out in that issue, there's also an ABI mismatch for repr(Int) enums with ZST fields, which I don't see represented in the tests added here. I wouldn't be surprised if this change also fixes that case, but might be worth adding a test for as follow-up?

@rust-bors
rust-bors Bot merged commit af5ab58 into rust-lang:main Sep 15, 2026
13 checks passed
@rustbot rustbot added this to the 1.100.0 milestone Sep 15, 2026
rust-bors Bot pushed a commit that referenced this pull request Sep 15, 2026
Rollup merge of #162806 - folkertdev:wasm-union-abi, r=alexcrichton

wasm: correctly implement `union` trivial aggregates

A union with two scalar fields, even if they overlap exactly, is not a trivial aggregate, based on the implementation in `clang`:

https://github.com/llvm/llvm-project/blob/e78970f80f1041de8948cb0b665a9aaae682f6c6/clang/lib/CodeGen/ABIInfoImpl.cpp#L338-L402

It never explicitly considers unions, but essentially views them as records. The `clang` implementation is a plausible interpretation of the specification (though I'd like it to be a bit clearer):

https://github.com/WebAssembly/tool-conventions/blob/83e5d715d0c18aee51e2d5ae9434f22d67b6e905/BasicCABI.md#function-arguments-and-return-values

> [2] Any struct or union that recursively (including through nested structs, unions, and arrays) contains just a single scalar value and is not specified to have greater than natural alignment.

We previously got this wrong. I also don't think this was really tested very well, so I added a bunch of test for various cases.

This change moves away from using the `homogeneous_aggregate` method, which is convenient because it is a bit broken and now we don't have to consider wasm when we fix that.

I've validated this against `clang` with abi-cafe.

r? alexcrichton
Zalathar added a commit to Zalathar/rust that referenced this pull request Sep 16, 2026
…excrichton

wasm: fix ABI for enums with integer layout and ZST fields

fixes rust-lang#121408
follow-up to rust-lang#162806

Clang is doing something that is rather annoying for us to emulate: like with unions it looks at the structure of the type, not the representation. But in rust an `enum` that is represented as an integer is not considered an `aggregate` at all, yet may still need to be passed as one if it has any (even ZST) fields.

r? alexcrichton
cc @hanna-kruppe
Zalathar added a commit to Zalathar/rust that referenced this pull request Sep 16, 2026
…excrichton

wasm: fix ABI for enums with integer layout and ZST fields

fixes rust-lang#121408
follow-up to rust-lang#162806

Clang is doing something that is rather annoying for us to emulate: like with unions it looks at the structure of the type, not the representation. But in rust an `enum` that is represented as an integer is not considered an `aggregate` at all, yet may still need to be passed as one if it has any (even ZST) fields.

r? alexcrichton
cc @hanna-kruppe
rust-bors Bot pushed a commit that referenced this pull request Sep 16, 2026
Rollup merge of #162826 - folkertdev:wasm-int-enum-abi, r=alexcrichton

wasm: fix ABI for enums with integer layout and ZST fields

fixes #121408
follow-up to #162806

Clang is doing something that is rather annoying for us to emulate: like with unions it looks at the structure of the type, not the representation. But in rust an `enum` that is represented as an integer is not considered an `aggregate` at all, yet may still need to be passed as one if it has any (even ZST) fields.

r? alexcrichton
cc @hanna-kruppe
pull Bot pushed a commit to LeeeeeeM/miri that referenced this pull request Sep 17, 2026
wasm: fix ABI for enums with integer layout and ZST fields

fixes rust-lang/rust#121408
follow-up to rust-lang/rust#162806

Clang is doing something that is rather annoying for us to emulate: like with unions it looks at the structure of the type, not the representation. But in rust an `enum` that is represented as an integer is not considered an `aggregate` at all, yet may still need to be passed as one if it has any (even ZST) fields.

r? alexcrichton
cc @hanna-kruppe
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-ABI Area: Concerning the application binary interface (ABI) O-wasm Target: WASM (WebAssembly), http://webassembly.org/ S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. 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.

4 participants