Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracking Issue for perma-unstable wasm-c-abi flag #122532

Open
1 of 2 tasks
daxpedda opened this issue Mar 15, 2024 · 59 comments · May be fixed by #133952
Open
1 of 2 tasks

Tracking Issue for perma-unstable wasm-c-abi flag #122532

daxpedda opened this issue Mar 15, 2024 · 59 comments · May be fixed by #133952
Labels
C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC

Comments

@daxpedda
Copy link
Contributor

daxpedda commented Mar 15, 2024

This is a tracking issue for the MCP "perma-unstable wasm-c-abi flag" (rust-lang/compiler-team#703).

For background, see rust-lang/compiler-team#703. The short summary is that the ABI rustc uses for extern "C" on wasm32-unknown-unknown is not spec-compliant and exposes various unstable implementation details of rustc and LLVM. We plan to transition to the official "C" ABI for this target. This will change how non-scalar arguments are passed across this ABI boundary, so if you have code running that is built for wasm32-unknown-unknown and called directly by JavaScript, it may have to be adjusted to follow the new ABI rules. Options for how to manage the transition are still being considered; see #138762 for further guidance.

The -Zwasm-c-abi flag lets you test your code with the new ABI.

About tracking issues

Tracking issues are used to record the overall progress of implementation.
They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions.
A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature.
Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.

Steps

Implementation history

Related issues

@daxpedda daxpedda added the C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC label Mar 15, 2024
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this issue Apr 18, 2024
Introduce perma-unstable `wasm-c-abi` flag

Now that `wasm-bindgen` v0.2.88 supports the spec-compliant C ABI, the idea is to switch to that in a future version of Rust. In the meantime it would be good to let people test and play around with it.

This PR introduces a new perma-unstable `-Zwasm-c-abi` compiler flag, which switches to the new spec-compliant C ABI when targeting `wasm32-unknown-unknown`.

Alternatively, we could also stabilize this and then deprecate it when we switch. I will leave this to the Rust maintainers to decide.

This is a companion PR to rust-lang#117918, but they could be merged independently.
MCP: rust-lang/compiler-team#703
Tracking issue: rust-lang#122532
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this issue Apr 18, 2024
Introduce perma-unstable `wasm-c-abi` flag

Now that `wasm-bindgen` v0.2.88 supports the spec-compliant C ABI, the idea is to switch to that in a future version of Rust. In the meantime it would be good to let people test and play around with it.

This PR introduces a new perma-unstable `-Zwasm-c-abi` compiler flag, which switches to the new spec-compliant C ABI when targeting `wasm32-unknown-unknown`.

Alternatively, we could also stabilize this and then deprecate it when we switch. I will leave this to the Rust maintainers to decide.

This is a companion PR to rust-lang#117918, but they could be merged independently.
MCP: rust-lang/compiler-team#703
Tracking issue: rust-lang#122532
workingjubilee added a commit to workingjubilee/rustc that referenced this issue Apr 18, 2024
Introduce perma-unstable `wasm-c-abi` flag

Now that `wasm-bindgen` v0.2.88 supports the spec-compliant C ABI, the idea is to switch to that in a future version of Rust. In the meantime it would be good to let people test and play around with it.

This PR introduces a new perma-unstable `-Zwasm-c-abi` compiler flag, which switches to the new spec-compliant C ABI when targeting `wasm32-unknown-unknown`.

Alternatively, we could also stabilize this and then deprecate it when we switch. I will leave this to the Rust maintainers to decide.

This is a companion PR to rust-lang#117918, but they could be merged independently.
MCP: rust-lang/compiler-team#703
Tracking issue: rust-lang#122532
workingjubilee added a commit to workingjubilee/rustc that referenced this issue Apr 18, 2024
Introduce perma-unstable `wasm-c-abi` flag

Now that `wasm-bindgen` v0.2.88 supports the spec-compliant C ABI, the idea is to switch to that in a future version of Rust. In the meantime it would be good to let people test and play around with it.

This PR introduces a new perma-unstable `-Zwasm-c-abi` compiler flag, which switches to the new spec-compliant C ABI when targeting `wasm32-unknown-unknown`.

Alternatively, we could also stabilize this and then deprecate it when we switch. I will leave this to the Rust maintainers to decide.

This is a companion PR to rust-lang#117918, but they could be merged independently.
MCP: rust-lang/compiler-team#703
Tracking issue: rust-lang#122532
bors added a commit to rust-lang-ci/rust that referenced this issue Apr 19, 2024
Introduce perma-unstable `wasm-c-abi` flag

Now that `wasm-bindgen` v0.2.88 supports the spec-compliant C ABI, the idea is to switch to that in a future version of Rust. In the meantime it would be good to let people test and play around with it.

This PR introduces a new perma-unstable `-Zwasm-c-abi` compiler flag, which switches to the new spec-compliant C ABI when targeting `wasm32-unknown-unknown`.

Alternatively, we could also stabilize this and then deprecate it when we switch. I will leave this to the Rust maintainers to decide.

This is a companion PR to rust-lang#117918, but they could be merged independently.
MCP: rust-lang/compiler-team#703
Tracking issue: rust-lang#122532
github-actions bot pushed a commit to rust-lang/miri that referenced this issue Apr 20, 2024
Introduce perma-unstable `wasm-c-abi` flag

Now that `wasm-bindgen` v0.2.88 supports the spec-compliant C ABI, the idea is to switch to that in a future version of Rust. In the meantime it would be good to let people test and play around with it.

This PR introduces a new perma-unstable `-Zwasm-c-abi` compiler flag, which switches to the new spec-compliant C ABI when targeting `wasm32-unknown-unknown`.

Alternatively, we could also stabilize this and then deprecate it when we switch. I will leave this to the Rust maintainers to decide.

This is a companion PR to #117918, but they could be merged independently.
MCP: rust-lang/compiler-team#703
Tracking issue: rust-lang/rust#122532
RalfJung pushed a commit to RalfJung/rust-analyzer that referenced this issue Apr 20, 2024
Introduce perma-unstable `wasm-c-abi` flag

Now that `wasm-bindgen` v0.2.88 supports the spec-compliant C ABI, the idea is to switch to that in a future version of Rust. In the meantime it would be good to let people test and play around with it.

This PR introduces a new perma-unstable `-Zwasm-c-abi` compiler flag, which switches to the new spec-compliant C ABI when targeting `wasm32-unknown-unknown`.

Alternatively, we could also stabilize this and then deprecate it when we switch. I will leave this to the Rust maintainers to decide.

This is a companion PR to #117918, but they could be merged independently.
MCP: rust-lang/compiler-team#703
Tracking issue: rust-lang/rust#122532
RalfJung pushed a commit to RalfJung/rust-analyzer that referenced this issue Apr 27, 2024
Introduce perma-unstable `wasm-c-abi` flag

Now that `wasm-bindgen` v0.2.88 supports the spec-compliant C ABI, the idea is to switch to that in a future version of Rust. In the meantime it would be good to let people test and play around with it.

This PR introduces a new perma-unstable `-Zwasm-c-abi` compiler flag, which switches to the new spec-compliant C ABI when targeting `wasm32-unknown-unknown`.

Alternatively, we could also stabilize this and then deprecate it when we switch. I will leave this to the Rust maintainers to decide.

This is a companion PR to #117918, but they could be merged independently.
MCP: rust-lang/compiler-team#703
Tracking issue: rust-lang/rust#122532
GuillaumeGomez pushed a commit to GuillaumeGomez/rustc_codegen_gcc that referenced this issue May 21, 2024
Introduce perma-unstable `wasm-c-abi` flag

Now that `wasm-bindgen` v0.2.88 supports the spec-compliant C ABI, the idea is to switch to that in a future version of Rust. In the meantime it would be good to let people test and play around with it.

This PR introduces a new perma-unstable `-Zwasm-c-abi` compiler flag, which switches to the new spec-compliant C ABI when targeting `wasm32-unknown-unknown`.

Alternatively, we could also stabilize this and then deprecate it when we switch. I will leave this to the Rust maintainers to decide.

This is a companion PR to #117918, but they could be merged independently.
MCP: rust-lang/compiler-team#703
Tracking issue: rust-lang/rust#122532
@workingjubilee
Copy link
Member

Since 1.78 a future-compat-warning for using too-old versions of wasm-bindgen has been in place, and now 75% of the ecosystem's downloads of crates are wasm-bindgen 0.2.89 or higher. I have opened #129534 as a discussion point for whether we should move the warning to a deny.

newpavlov pushed a commit to rust-random/getrandom that referenced this issue Aug 26, 2024
wasm-bindgen 0.2.62 is not compatible with a wasm ABI change that rustc
wishes to enable by default for wasm32-unknown-unknown, currently gated
behind passing the -Zwasm-c-abi flag to rustc.

wasm-bindgen 0.2.89 should exhibit seamless behavior before and after
the ABI change to match the C ABI, so depend on that.

For more information, see
- rust-lang/rust#115666
- rust-lang/rust#117918
- rust-lang/rust#122532
@lcnr

This comment has been minimized.

@bjorn3 bjorn3 linked a pull request Dec 6, 2024 that will close this issue
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jan 25, 2025
… r=workingjubilee

Make the wasm_c_abi future compat warning a hard error

This is the next step in getting rid of the broken C abi for wasm32-unknown-unknown.

The lint was made deny-by-default in rust-lang#129534 3 months ago. This still keeps the `-Zwasm-c-abi` flag set to `legacy` by default. It will be flipped in a future PR.

cc rust-lang#122532
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jan 26, 2025
… r=workingjubilee

Make the wasm_c_abi future compat warning a hard error

This is the next step in getting rid of the broken C abi for wasm32-unknown-unknown.

The lint was made deny-by-default in rust-lang#129534 3 months ago. This still keeps the `-Zwasm-c-abi` flag set to `legacy` by default. It will be flipped in a future PR.

cc rust-lang#122532
jhpratt added a commit to jhpratt/rust that referenced this issue Jan 26, 2025
… r=workingjubilee

Make the wasm_c_abi future compat warning a hard error

This is the next step in getting rid of the broken C abi for wasm32-unknown-unknown.

The lint was made deny-by-default in rust-lang#129534 3 months ago. This still keeps the `-Zwasm-c-abi` flag set to `legacy` by default. It will be flipped in a future PR.

cc rust-lang#122532
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Jan 26, 2025
Rollup merge of rust-lang#133951 - bjorn3:wasm_c_abi_lint_hard_error, r=workingjubilee

Make the wasm_c_abi future compat warning a hard error

This is the next step in getting rid of the broken C abi for wasm32-unknown-unknown.

The lint was made deny-by-default in rust-lang#129534 3 months ago. This still keeps the `-Zwasm-c-abi` flag set to `legacy` by default. It will be flipped in a future PR.

cc rust-lang#122532
@Manishearth
Copy link
Member

Hi! I was recently informed that there are plans to switch the default soon.

I work on Diplomat, a tool that generates multi-language bindings (including JS-wasm), used by ICU4X,

My expectation here was that there would be a period of time where both compilation modes are available on stable before things are switched over, as is the norm for almost all breaking changes in Rust. I have been waiting for that period of time to migrate Diplomat, so that Diplomat (and ICU4X) users will have an "apply RUSTFLAGS=foo" path available to them to deal with this across supported Rust versions.

I'm rather surprised to hear that it's just going to be a simple switchover. It's not a huge deal for Diplomat-WASM to require nightly for working around this, but it's a bit messy, and like I said it is surprising. (I'm also surprised that the extent of future-incompat work was to ensure people use the latest wasm-bindgen: wasm-bindgen isn't the only tool around, and there are people who work directly with WASM with no generated bindings!)

@Manishearth
Copy link
Member

I assumed wasm would work roughly like the other architectures, in particular meaning there are well-defined ABI rules and people wouldn't think that reverse engineering the undocumented details of register-level argument passing is somehow normal.

Yeah, it's too new, and the primary compiler used for wasm is .... rustc, so.......

@RalfJung
Copy link
Member

RalfJung commented Mar 17, 2025 via email

@RalfJung
Copy link
Member

#138601 implements the suggested lint.

n.b. my current hope is to just ride it out for diplomat with explicit instructions for users to set appropriate flags, so I hope this FCW doesn't become an actual error; I do wish to have the ability to pass aggregates over wasm ffi in the long run.

I'm fine with just removing the FCW in the same PR that also does the ABI switch (without ever having it be an actual error), if that works for you.

@RalfJung
Copy link
Member

RalfJung commented Mar 17, 2025

My understanding is that someone didn't realize they have to add some code in rustc's ABI handling whenever a new architecture is being added, and so the ABI is some undocumented artifact of what LLVM happens to do.

That doesn't seem to be entirely true, this was at least partially intentionally:

/// The purpose of this ABI is for matching the WebAssembly standard. This
/// intentionally diverges from the C ABI and is specifically crafted to take
/// advantage of LLVM's support of multiple returns in WebAssembly.

However, whoever wrote this apparently did not consider that the way rustc translates Rust types to LLVM types is not stable so we can't ever just use the "bare" LLVM ABI in this way.

Anyway at this point that is only of historical interest.

@hanna-kruppe
Copy link
Contributor

This comment from the comes from the introduction of extern "wasm" (#83763), which was much later. That ABI was intended to be stable eventually, not necessarily identical to the "legacy" accident, and defined in terms of wasm concepts. So presumably if it had become stable then it would have had an LLVM-independent definition, with more deliberate lowering to LLVM IR added as necessary.

@alexcrichton
Copy link
Member

This has gotten to be quite a long thread but I can try to comment on at least some parts from a wasm target maintainer perspective. IMO the main thing here is that the ABI was "broken" from the get-go (my mistake) and then by the time we discovered it (years later) I had run out of steam and couldn't champion the change to wasm-bindgen. This then started a multi-year process (5+ I think?) to change the ABI where no one person was ever solely dedicated to completing the migration. Naturally thoughout this time people have come and gone and progress has been made but it's inevitable that with such a large cast of characters and such a large amount of time that things fall through the cracks. When this started (which I think was 2020 or pre-2020, I forget), I'm relatively certain wasm-bindgen was the only thing in play, and I think that mentality stuck by default despite that not being true years later.

Regardless of this past though it seems like we're all aligned on (a) everyone here's operating in good-faith (yay!) and (b) the goal is to change the ABI still. I definitely agree the ABI should still change here myself, and on the topic of changing from a "good ABI" to a "not as good ABI" in terms of what the actual ABI is, this is another long-running issue on the wasm side and I think that discussion should happen on tool-conventions (I can point to issues if desired) rather than here. The goal here is to align with Clang and stop implicitly relying on Rust compiler internals.

Personally I'd think it best if we could get away with FCW + blog. Question for you though @Manishearth as that has pretty serious implications for Diplomat, are you ok with these? (sorry if this was already discussed)

  • Users of rustc stable and Diplomat would receive warnings that cannot be addressed without switching to a nightly toolchain and passing -Zwasm-c-abi=spec.
  • Users that switch from stable to nightly will be guaranteed to break again in the future due to -Zwasm-c-abi eventually going to get removed.
  • Users that decide to pin to a rustc stable version instead of updating might be stuck for on the order of 3-6 months.

If you're ok with that, that seems like a reasonable plan to move forward to me, with a possible schedule looking like:

  1. Land FCW + write blog post.
  2. Wait for FCW to hit stable
  3. Change -Zwasm-c-abi default in nightly once FCW is on stable
  4. Wait for new default to hit stable
  5. Remove FCW + -Zwasm-c-abi

That's going to be probably a longer transition period than envisioned (I think?). (1) here can happen here-and-now, but (3) is ~12 weeks out and (5) is probably minimum 24 weeks out, possibly more.

@RalfJung
Copy link
Member

FWIW I was thinking we'd remove the FCW the moment we change the default. In fact the current implementation does this already -- the lint only fires when tcx.wasm_c_abi_opt() is legacy.

@Manishearth
Copy link
Member

Manishearth commented Mar 17, 2025

That seems good. The schedule is a bit fast according to ICU4X standards (we change MSRV slowly), but if the FCW has helpful advice for people in this situation, and is framed less like an FCW and more like "this is compiler-version dependent, take care, here's a link for how to fix", and the lint goes away with explicit wasm-c-abi, then that shouldn't matter much.

I will discuss this with other ICU4X and Diplomat team members to ensure everyone is on the same page and fine with this path.

@workingjubilee
Copy link
Member

So far in my experience, wasm being new meant everything was extremely well-done as they learned from all the past mistakes. There's even a formal language spec :)

But I have only been following from afar.

They only learned from things people wrote down and made public.

The horrors of the hard lessons learned in, say, the evolution of the x86 Microsoft C++ ABI, seem to have been buried in Redmond.

@alexcrichton
Copy link
Member

I was thinking we'd remove the FCW the moment we change the default.

To me this depends on the transition plan. It sounds like Diplomat's plan is something along the lines of:

  1. Rely on the legacy ABI for the time being.
  2. Get current users to pin their toolchain or switch to Nightly with -Zwasm-c-abi=legacy
  3. Eventually Rust switches the default where -Zwasm-c-abi=spec is the new default
  4. Eventually this change reaches stable
  5. Then Diplomat changes internal JS code and such to only work with this new stable compiler, updating MSRV.
  • Users pinned to old toolchains "just update" now
  • Users using nightly with -Zwasm-c-abi=legacy will probably see corruption/crashes if they update Diplomat without removing the legacy flag, but the fix would then be to remove the legacy flag.

If the FCW is removed when the default is changed (which I take to also remove -Zwasm-c-abi) then there's a period of time between (3) and (4) where Diplomat is unsupported on all of stable/beta/nightly. Whether or not that's ok for Diplomat I'm not sure, but by delaying the removal of the FCW + -Zwasm-c-abi it provides a bit of a grace period for Diplomat to still be supported on one of stable/beta/nightly.

I should definitely clarify though that to me I'm considering two knobs: one is the change of the default value of -Zwasm-c-abi and another is the removal of all support for the legacy abi. Removal of the FCW I would bundle with the removal of the legacy ABI.

The schedule is a bit fast according to ICU4X standards

Oh I'm just throwing out ideas. I'm not actually in charge of timelines or anything. Personally I think it's valuable for everything to have a bounded amount of time, but extending a release or two is probably fine.

the lint goes away with explicit wasm-c-abi

To clarify, and to be double-sure: this is not possible with a stable or beta compiler, only a nightly compiler. My thinking is there is no plan to move -Zwasm-c-abi to -C. It stays in the perma-unstable category of -Z meaning the only way to silence the warning (and insulate a project from future breakage) will be (a) pinning rustc to an older version or (b) switch to Nightly + -Zwasm-c-abi=legacy.

I want to be extra careful to clarify this since most projects in the past I know of are hesitant to do both, but if that's ok for Diplomat it definitely makes the compiler's life easier

@RalfJung
Copy link
Member

RalfJung commented Mar 17, 2025

If the FCW is removed when the default is changed (which I take to also remove -Zwasm-c-abi)

No, the flag can stay around a bit longer once the default is changed. Just the FCW is gone then. (Or, impossible to hit on stable. It might still exist and trigger for people that set -Zwasm-c-abi=legacy I guess 🤷 .)

@alexcrichton
Copy link
Member

Ah ok, I think you and I are thinking the same thing then, so sounds good!

In some sense the FCW "will break" warning is correct with -Zwasm-c-abi=legacy because the plan is to remove the flag entirely which would break builds using that. Anyway I digress...

@Manishearth
Copy link
Member

To clarify, and to be double-sure: this is not possible with a stable or beta compiler, only a nightly compiler

Yep. But one way to deal with the transition is, during it, to explicitly pass a wasm-c-abi flag on nightly. It's not great to have to use nightly for this, but for building .wasm files it's fine.

@alexcrichton
Copy link
Member

Up above @RalfJung added I-compiler-nominated, so in an effort to expedite team discussion of this I'm going to try to summarize the current status with respect to the compiler team. The main points are:

  • Today wasm32-unknown-unknown still has a broken non-spec-conforming definition of the C ABI (this has been true for a long time)
  • The ABI can be fixed by passing -Zwasm-c-abi=spec (and the broken ABI is -Zwasm-c-abi=legacy)
  • One major known user this would break is wasm-bindgen. Through a series of PRs over the years this is now "done" and is ready for the the ABI to change at any time.
  • @Manishearth has brought up in this thread that another user, Diplomat, was not ready for this change and would be broken from the removal of -Zwasm-c-abi=legacy (which I believe was planned to happen "soon" but there's no current PR for this)
  • Thus the current proposal of how to move forward and reach the end state of removing -Zwasm-c-abi=legacy
    • Add a future-compat warning on usage of -Zwasm-c-abi=legacy where the meaning is changing. This should not warn on wasm-bindgen for example, only on ABI signatures whose definition is going to change when -Zwasm-c-abi=spec becomes the default.
    • When that change lands publish a blog post about -Zwasm-c-abi and explain what's going on. The "fix" is (a) stop using aggregates in your ABI, (b) use a nightly compiler and pass -Zwasm-c-abi=spec, or (c) pin to an older rustc for awhile
    • After the future-compat warning change bakes for a bit, change the default on Nightly from -Zwasm-c-abi=legacy to -Zwasm-c-abi=spec.
    • After the changed default bakes for awhile, remove -Zwasm-c-abi entirely and all support for legacy, including the future-compat warning.

My understanding is that this plan works for Diplomat and the hope is that this works for other users as well if they come out of the woodwork. Also this is my best understanding of the conclusions of this thread, if I got something wrong here someone please let me know.

@Manishearth
Copy link
Member

Manishearth commented Mar 17, 2025

The current plan that Diplomat and ICU4X are coalescing around is:

  • We shall land a patch in Diplomat around the time the default switches over. Until then, we basically ignore the FCW.
  • ICU4X 2.0, and whatever Diplomat version comes with that, will have legacy bindings. Unfortunate but fine. We hope for a release in the next few weeks. Users who need to use this on wasm may need to use an older stable compiler, or a nightly with the legacy flag.
  • We may have some kind of check that ensures the correct ABI was used, loudly erroring if you attempt to run the wasm bindings with a spec ABI .wasm file
  • ICU4X 2.1, and a semver incompatible Diplomat version, will have spec bindings. Users who need to use this on wasm should use newer compilers, or older nightlies with the spec flag. We may still have a legacy check if needed.

This means that the plan for an FCW and eventual switchover in the near future is probably acceptable to us. Will keep you posted if other needs come up.

@RalfJung
Copy link
Member

RalfJung commented Mar 17, 2025

@alexcrichton

The "fix" is (a) stop using aggregates in your ABI, (b) use a nightly compiler and pass -Zwasm-c-abi=spec, or (c) pin to an older rustc for awhile

-Zwasm-c-abi=spec is a "fix" but does opt-in to the ABI change, so the moment you do that you have to update the other side of this ABI as well.

So another "fix" is to set -Zwasm-c-abi=legacy, to silence the lint. That gives you control over when the switch is performed -- it's when you toggle that to spec. We should give a timeline for when we expect the -Z flag to be retired.

The timeline you had above would be

  • add FCW in Rust 1.87 (i.e., current nightly); we have 11 days to catch that train
  • switch default for Rust 1.89 (or should we wait until 1.90 just to be safe?)
  • remove -Z flag and finally remove the legacy wasm implementation for Rust 1.91

@Manishearth

ICU4X 2.1, and a semver incompatible Diplomat version, will have spec bindings. Users who need to use this on wasm should use older compilers, or nightlies with the spec flag. We may still have a legacy check if needed.

I am confused here, how would an older compiler help when using spec ABI bindinings?

@Manishearth
Copy link
Member

typo, sorry!

@Manishearth
Copy link
Member

  • remove -Z flag and finally remove the legacy wasm implementation for Rust 1.91

Might be nice to keep the -Zwasm-c-abi=spec as a no-longer-necessary flag that does nothing for a while after, just so that people using this flag don't have to do rust version detection. Not necessary, but nice to have.

@RalfJung
Copy link
Member

RalfJung commented Mar 17, 2025

Might be nice to keep the -Zwasm-c-abi=spec as a no-longer-necessary flag that does nothing for a while after, just so that people using this flag don't have to do rust version detection. Not necessary, but nice to have.

As a nightly-only flag I assume people using it would anyway track latest nightly fairly closely?

But yeah we can keep that flag around a bit longer, forget about it, and remove it in 5 years when someone finally notices. ;) Once the legacy ABI is finally gone from rustc, this transition is done as far as I am concerned.

@Manishearth
Copy link
Member

As a nightly-only flag I assume people using it would anyway track latest nightly fairly closely?

There can be other constraints on the nightly version you use. Not relevant for this particular thing, but e.g. ICU4X pins some nightlies in its tests so that we can track cross-language LTO codesize.

@Manishearth
Copy link
Member

Manishearth commented Mar 18, 2025

In this case, it is worth highlighting that the standard doesn't really connect up the ABI to what actually happens at the JS level, and while you can look at other standards for this, it's rather unclear exactly what's going on. It talks about stacks and then immediately starts talking about direct and indirect passing and function parameters. There really isn't any good documentation with that use case in mind: this is like if figuring out how to call Rust from C required you to understand register-passing first.

Just to give another example of this: The multivalue extension has been talked about for ages. It is implemented everywhere1. Yet, nowhere, do I see any mention of what this means in JS (which has no native concept of returning multiple values). I had to reverse engineer it, turns out that it returns an array of the scalars splatted out, which is reasonable, but it's really hard to find any docs that tell you how this work. Not just official docs, any docs whatsoever. You can figure it out from the wasm-js interface spec and the multivalue spec if you want to.

An observation about the wasm ecosystem from a relative outsider: Wasm was initially marketed as this thing for running fast native code from JS, but the focus has overall shifted to a more general usage as a way to safely embed native code in many kinds of applications that have nothing to do with JS. It feels like this has ended up with the JS-wasm use case getting less attention over time, leading to an overall lack of docs. I think things like this issue are also a knock on effect: where folks were trying to fix the C interop problem but did not really consider there to be any users of JS-wasm outside of wasm-bindgen, despite JS-wasm being the original primary purpose of wasm. I had to struggle to convince people that it was possible to use the current ABI because people were convinced it was unusably broken (it was broken, just not unusably so for JS-wasm).

Footnotes

  1. For some reason I couldn't convince rustc to emit it, I was using RUSTFLAGS="-C target-feature=+multivalue -Zwasm-c-abi=spec" cargo +nightly rustc -Zbuild-std=panic_abort,std --target wasm32-unknown-unknown --crate-type cdylib --release, but everything else points to it being supported, and I'm probably just doing something incorrect here.

@apiraino
Copy link
Contributor

T-compiler visited this issue during the triage meeting (on Zulip#t-compiler/meetings > [wekly] 2025-03-20 @ 💬).

First of all thanks @RalfJung and @alexcrichton for the great effort to summarize the main points. We basically have nothing to add and find the plan sound (although understandadly a bit of a burden for the parties involved).

We take from this comment an actionable for us to be more transparent and document better stability promises (or lack thereof).

@rustbot label -I-compiler-nominated

@rustbot rustbot removed the I-compiler-nominated Nominated for discussion during a compiler team meeting. label Mar 20, 2025
@alexcrichton
Copy link
Member

If no one else wants to volunteer to write a blog post I'm happy to draft that up in the next few days with a plan to merge the blog post around the time #138601 lands.

@Manishearth
Copy link
Member

@alexcrichton I can't take point on this but I can probably help review it and write a paragraph or two if you share a hackmd with me when you start.

@alexcrichton
Copy link
Member

I've written up an initial draft

tgross35 added a commit to tgross35/rust that referenced this issue Mar 22, 2025
add FCW to warn about wasm ABI transition

See rust-lang#122532 for context: the "C" ABI on wasm32-unk-unk will change. The goal of this lint is to warn about any function definition and calls whose behavior will be affected by the change. My understanding is the following:
- scalar arguments are fine
  - including 128 bit types, they get passed as two `i64` arguments in both ABIs
- `repr(C)` structs (recursively) wrapping a single scalar argument are fine (unless they have extra padding due to over-alignment attributes)
- all return values are fine

`@bjorn3` `@alexcrichton` `@Manishearth` is that correct?

I am making this a "show up in future compat reports" lint to maximize the chances people become aware of this. OTOH this likely means warnings for most users of Diplomat so maybe we shouldn't do this?

IIUC, wasm-bindgen should be unaffected by this lint as they only pass scalar types as arguments.

Tracking issue: rust-lang#138762
Transition plan blog post: rust-lang/blog.rust-lang.org#1531
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC
Projects
None yet
Development

Successfully merging a pull request may close this issue.