Skip to content

Add a new, unstable, "wasm-multivalue" ABI#157334

Draft
alexcrichton wants to merge 1 commit into
rust-lang:mainfrom
alexcrichton:wasm-multivalue-conv
Draft

Add a new, unstable, "wasm-multivalue" ABI#157334
alexcrichton wants to merge 1 commit into
rust-lang:mainfrom
alexcrichton:wasm-multivalue-conv

Conversation

@alexcrichton
Copy link
Copy Markdown
Member

This commit adds a new ABI string to the Rust compiler, "wasm-multivalue", which corresponds to a new ABI for WebAssembly defined at WebAssembly/tool-conventions#268. The purpose of this ABI is to enable Rust code compiled to WebAssembly to be able to work with WebAssembly functions that have multiple results in their type signature. Currently, despite the multivalue target feature being stable, this is not possible. The reason this isn't possible is that the original "C" ABI was created before multivalue and then there's no realistic means to change it. This new ABI is intended to enable all preexisting targets to use this ABI. One day this may become the default ABI for WebAssembly, but we aren't there yet.

This adds various bits of plumbing and such throughout the compiler to support the new wasm-multivalue ABI. This is only supported with LLVM 23 and later due to required changes in LLVM. This ABI additionally requires the multivalue target feature to be enabled to use it.

This commit adds a new ABI string to the Rust compiler,
"wasm-multivalue", which corresponds to a new ABI for WebAssembly
defined at WebAssembly/tool-conventions#268. The purpose of this ABI is
to enable Rust code compiled to WebAssembly to be able to work with
WebAssembly functions that have multiple results in their type
signature. Currently, despite the `multivalue` target feature being
stable, this is not possible. The reason this isn't possible is that
the original "C" ABI was created before multivalue and then there's no
realistic means to change it. This new ABI is intended to enable all
preexisting targets to use this ABI. One day this may become the default
ABI for WebAssembly, but we aren't there yet.

This adds various bits of plumbing and such throughout the compiler to
support the new `wasm-multivalue` ABI. This is only supported with LLVM
23 and later due to required changes in LLVM. This ABI additionally
requires the `multivalue` target feature to be enabled to use it.
@rustbot rustbot added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. 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. labels Jun 2, 2026
@alexcrichton
Copy link
Copy Markdown
Member Author

I'll note that I'm creating this as a draft at this time because this requires changes to LLVM which haven't yet landed upstream in LLVM. I hope to land the changes in time for LLVM 23, but we'll see. In the meantime I wanted to at least provide this as a reference point for some discussions I'm having. I don't plan on marking this as ready-for-review until the in-tree version of LLVM supports this new ABI.

@rust-log-analyzer
Copy link
Copy Markdown
Collaborator

The job tidy failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
[TIMING:end] tool::Tidy { compiler: Compiler { stage: 0, host: x86_64-unknown-linux-gnu, forced_compiler: false }, target: x86_64-unknown-linux-gnu } -- 0.000
fmt check
fmt: checked 6882 files
tidy check
tidy [target-specific-tests (tests)]: /checkout/tests/assembly-llvm/wasm-multivalue-functype.rs: revision [unspecified] should not specify `needs-llvm-components:` as it doesn't need `--target`
tidy [target-specific-tests (tests)]: FAIL
tidy [rustdoc_json (src)]: `rustdoc-json-types` modified, checking format version
tidy: Skipping binary file check, read-only filesystem

thread 'main' (4231) panicked at src/tools/tidy/src/features.rs:411:28:
called `Result::unwrap()` on an `Err` value: ParseIntError { kind: Zero }
stack backtrace:
   0: __rustc::rust_begin_unwind
             at /rustc/0417c25868d6dfbd1c291dfeae950504faa6f790/library/std/src/panicking.rs:689:5
   1: core::panicking::panic_fmt
             at /rustc/0417c25868d6dfbd1c291dfeae950504faa6f790/library/core/src/panicking.rs:80:14
---
   7: std::thread::scoped::scope::<rust_tidy::main::{closure#1}, ()>
   8: rust_tidy::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Bootstrap failed while executing `test src/tools/tidy tidyselftest --extra-checks=py,cpp,js,spellcheck`
Command `/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-tools-bin/rust-tidy --root-path=/checkout --cargo-path=/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo --output-dir=/checkout/obj/build --concurrency=4 --npm-path=/node/bin/yarn --ci=true --extra-checks=py,cpp,js,spellcheck` failed with exit code 101
Created at: src/bootstrap/src/core/build_steps/tool.rs:1624:23
Executed at: src/bootstrap/src/core/build_steps/test.rs:1475:29

--- BACKTRACE vvv
   0: <bootstrap::utils::exec::DeferredCommand>::finish_process
             at /checkout/src/bootstrap/src/utils/exec.rs:939:17
   1: <bootstrap::utils::exec::DeferredCommand>::wait_for_output::<&bootstrap::utils::exec::ExecutionContext>
             at /checkout/src/bootstrap/src/utils/exec.rs:831:21
   2: <bootstrap::utils::exec::ExecutionContext>::run
             at /checkout/src/bootstrap/src/utils/exec.rs:741:45
   3: <bootstrap::utils::exec::BootstrapCommand>::run::<&bootstrap::core::builder::Builder>
             at /checkout/src/bootstrap/src/utils/exec.rs:339:27
   4: <bootstrap::core::build_steps::test::Tidy as bootstrap::core::builder::Step>::run
             at /checkout/src/bootstrap/src/core/build_steps/test.rs:1475:29
   5: <bootstrap::core::builder::Builder>::ensure::<bootstrap::core::build_steps::test::Tidy>
             at /checkout/src/bootstrap/src/core/builder/mod.rs:1596:36
   6: <bootstrap::core::build_steps::test::Tidy as bootstrap::core::builder::Step>::make_run
             at /checkout/src/bootstrap/src/core/build_steps/test.rs:1397:21
   7: <bootstrap::core::builder::StepDescription>::maybe_run
             at /checkout/src/bootstrap/src/core/builder/mod.rs:476:13
   8: bootstrap::core::builder::cli_paths::match_paths_to_steps_and_run
             at /checkout/src/bootstrap/src/core/builder/cli_paths.rs:232:18
   9: <bootstrap::core::builder::Builder>::run_step_descriptions
             at /checkout/src/bootstrap/src/core/builder/mod.rs:1139:9
  10: <bootstrap::core::builder::Builder>::execute_cli
             at /checkout/src/bootstrap/src/core/builder/mod.rs:1118:14
  11: <bootstrap::Build>::build
             at /checkout/src/bootstrap/src/lib.rs:803:25
  12: bootstrap::main
             at /checkout/src/bootstrap/src/bin/main.rs:130:11
  13: <fn() as core::ops::function::FnOnce<()>>::call_once
             at /rustc/0417c25868d6dfbd1c291dfeae950504faa6f790/library/core/src/ops/function.rs:250:5
  14: std::sys::backtrace::__rust_begin_short_backtrace::<fn(), ()>
             at /rustc/0417c25868d6dfbd1c291dfeae950504faa6f790/library/std/src/sys/backtrace.rs:166:18
  15: std::rt::lang_start::<()>::{closure#0}
             at /rustc/0417c25868d6dfbd1c291dfeae950504faa6f790/library/std/src/rt.rs:206:18
  16: <&dyn core::ops::function::Fn<(), Output = i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe as core::ops::function::FnOnce<()>>::call_once
             at /rustc/0417c25868d6dfbd1c291dfeae950504faa6f790/library/core/src/ops/function.rs:287:21
  17: std::panicking::catch_unwind::do_call::<&dyn core::ops::function::Fn<(), Output = i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe, i32>
             at /rustc/0417c25868d6dfbd1c291dfeae950504faa6f790/library/std/src/panicking.rs:581:40
  18: std::panicking::catch_unwind::<i32, &dyn core::ops::function::Fn<(), Output = i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe>
             at /rustc/0417c25868d6dfbd1c291dfeae950504faa6f790/library/std/src/panicking.rs:544:19
  19: std::panic::catch_unwind::<&dyn core::ops::function::Fn<(), Output = i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe, i32>
             at /rustc/0417c25868d6dfbd1c291dfeae950504faa6f790/library/std/src/panic.rs:359:14
  20: std::rt::lang_start_internal::{closure#0}
             at /rustc/0417c25868d6dfbd1c291dfeae950504faa6f790/library/std/src/rt.rs:175:24
  21: std::panicking::catch_unwind::do_call::<std::rt::lang_start_internal::{closure#0}, isize>
             at /rustc/0417c25868d6dfbd1c291dfeae950504faa6f790/library/std/src/panicking.rs:581:40
---
  28: __libc_start_main
  29: _start


Command has failed. Rerun with -v to see more details.
Build completed unsuccessfully in 0:01:02
  local time: Tue Jun  2 20:47:20 UTC 2026
  network time: Tue, 02 Jun 2026 20:47:20 GMT
##[error]Process completed with exit code 1.
##[group]Run echo "disk usage:"

Variants::Empty | Variants::Multiple { .. } => return None,

// Fall through to go see further...
Variants::Single { .. } => {}
Copy link
Copy Markdown
Member

@bjorn3 bjorn3 Jun 2, 2026

Choose a reason for hiding this comment

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

This would also match enums where a single variant is inhabited. This should probably check that the type is actually a struct.

View changes since the review

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

Labels

A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. 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.

4 participants