Skip to content

merge: wit-bindgen 0.59#1409

Draft
rvolosatovs wants to merge 14 commits into
mainfrom
merge/wit-bindgen-0.59
Draft

merge: wit-bindgen 0.59#1409
rvolosatovs wants to merge 14 commits into
mainfrom
merge/wit-bindgen-0.59

Conversation

@rvolosatovs

@rvolosatovs rvolosatovs commented Jul 20, 2026

Copy link
Copy Markdown
Member

Merge upstream wit-bindgen 0.59.0 into the vendored bindgen subtree.

  • Bump wit-bindgen-core 0.58 -> 0.59, wit-parser 0.251 -> 0.253 and
    wit-component 0.252 -> 0.253.
  • API churn carried into the vendored generators:
  • Carry the new codegen input (single-version-package); it generates without
    changes.

Non-carries (not applicable to wRPC):

  • The resource-machinery changes in crates/rust/src/interface.rs
    (resource_into_raw_/resource_from_raw_, the ResourceRep/Resource
    runtime bounds, {camel}Borrow provenance fixes) and the bindgen.rs
    FunctionBindgen::lift provenance fix target upstream's canonical-ABI guest
    resource lowering; wRPC generates transport stubs and vendors none of that
    machinery.
  • Rust: merge structurally equal types in bindgen wit-bindgen#1468 merge_structurally_equal_types (macro/generator option and its
    codegen test) is a deferred feature; wRPC's Rust generator has no such option.
  • The Go changes target the rebooted Go generator (crates/go, dropped);
    wRPC's wit-bindgen-go is the independent pre-reboot fork.
  • The new tests/runtime cases (future/stream cancellation, yield loops,
    block-on, cross-task wakeup, ...) exercise the guest canonical-ABI async
    runtime, which wRPC does not implement (async is over the transport).

rust codegen and go codegen tests pass (864 codegen, 89 components, 42 runtime);
cargo clippy --workspace (and --features serde) and cargo doc --workspace
are clean; the Go integration suite passes and all examples build.

Assisted-by: claude:claude-opus-4-8
Upstream diff: bytecodealliance/wit-bindgen@v0.58.0...v0.59.0

scothis and others added 14 commits June 9, 2026 13:59
The generate! macro now exposes `merge_structurally_equal_types`. This
functionality was previously only available via the
`--merge-structurally-equal-types` CLI flag.

The underlying functionality is unchanged.

Signed-off-by: Scott Andrews <scott@andrews.me>
…ion (#1625)

* Resource allocation override option

* custom resource allocation

* cut the dirty tricks out of the arena

* hide that it is an Option (typedef), put underscore to the end

* Some review comments of mine and refactorings

* Fix doc example

---------

Co-authored-by: Alex Crichton <alex@alexcrichton.com>
…1635)

Port the `pkg_has_multiple_versions` guard from the C generator
(crates/c/src/lib.rs, `interface_identifier`) to the C# backend.

Previously the C# generator unconditionally appended a version segment
to the namespace of every versioned package (e.g. `my.dep.v0_1_0`).
Now the segment is emitted only when the same package namespace+name
appears at more than one version in the Resolve — i.e. when
omitting it would cause a name collision.

The guard logic is identical to the C backend's. The mangling format
intentionally differs: C# emits `v{major}_{minor}_{patch}.` while C
uses a trailing-underscore snake-case segment.

Tests:
- Unit tests on `interface_name` assert the namespace directly: the
  segment is dropped for a single-version package and kept when two
  versions coexist (verified to fail if the guard is reverted).
- A `tests/codegen/single-version-package` fixture (one versioned
  import, single version) builds the drop path across all backends,
  alongside the existing `multiversion` fixture (two versions).

Closes #1078

Co-authored-by: sanosuguru <sa.50.00.no.riku@gmail.com>
…ancelling (#1638)

`cancel_inter_task_stream_read` issued a synchronous `stream.cancel-read` on
the inter-task wakeup stream while that stream was still a member of the task's
waitable set, only calling `remove_waitable` afterwards.

Per the Component Model (component-model#647), a synchronous
`{stream,future}.cancel-{read,write}` traps if the waitable is still in a
waitable set, for the same reason synchronous reads/writes do. Runtimes that
enforce this trap (e.g. recent Wasmtime) therefore fault here during ordinary
async operation.

Reorder so the stream leaves the waitable set before the synchronous cancel,
matching the unregister-then-cancel ordering already used by the general
`WaitableOperation::cancel` path. The cancel result is discarded as before, so
behavior is otherwise unchanged.
* Evolve the wasip3 async C ABI for tasks

This commit is an evolution of the C ABI used to managed task-related
infrastructure in WASIp3 with the goal of solving #1618. The basic
problem of #1618 is that waitables in Rust aren't guaranteed to be
polled within the context of the original task. For example by mixing an
`async` Rust export and `block_on` it's possible to "cross the wires"
and poll in one context while dropping/completing in another context.
This can lead to buggy situations where a waitable is left in a set, not
added to an appropriate set, or generally mis-managed.

The solution here is to enhance the current C ABI of task management
with clone/drop operations. Notably this enables waitables to retain a
strong reference to the task state as opposed to always consulting what
the current task in. This fixes a few situations such as:

* When dropping a half-finished waitable it no longer needs to be
  dropped in the context of the original task. Dropping will unregister
  the waitable from a task that it was originally registered with.
* When a waitable is moved from one task to another it needs to
  implicitly de-register with the previous task, and this was not
  previously done. Now with a retained strong reference it's able to
  clear out previous state upon re-registering with a new task.

This change requires some finesse as this needs to be ABI-stable to work
with previous versions of the `wit-bindgen` crate. The runtime support
additionally can't assume that the new ABI bits are available and
instead needs to handle the previous ABI as well. Not too too bad, in
the end, though.

This additionally did some refactoring of the state associated with
async tasks to juggle things around and better represent the raw
pointers/`Arc`/etc from before.

Closes #1618

* Document the C ABI

* Fix disabled compile

* Just one version marker
* feat(cpp): add map type support

* fix(cpp): add operator< to wit::string for std::map key support and fix rustfmt

wit::string lacked comparison operators, causing compilation failures
when used as a std::map key. Also fixes rustfmt formatting issues.

* fix(cpp): const_cast map keys during lowering for ownership transfer

std::map keys are const, but the ABI lowering needs to call leak() on
string keys to transfer ownership to the flat buffer. Use const_cast
since the map is consumed during the lowering operation.

* fix(cpp): copy map keys by value instead of const_cast during lowering

const_cast fails when the map key type differs between contexts (e.g.
std::string_view in imports vs wit::string in exports). Copying by
value works universally and is safe since the map is consumed.

* fix(cpp): remove map runtime test until wasi-sdk supports map types

wasm-component-ld bundled with wasi-sdk 30 doesn't support the map
type encoding (0x63) in the component model binary format. The C++
map codegen is still validated by the codegen test. The runtime test
can be re-added when wasi-sdk ships a compatible wasm-component-ld.

* refactor(cpp): use wit::map instead of std::map for map types

std::map requires per-entry rb-tree allocation during lift; wit::map
mirrors the canonical ABI layout (flat pair array) so lift is a single
allocation, matching the existing wit::vector / wit::string pattern.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>

* refactor(cpp): drop redundant size_t cast in MapLower

wit::map::size() and std::span::size() already return size_t, so the
C-style cast was a no-op.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>

* refactor(cpp): skip guest-dealloc loop when body is empty

Avoids an unused `base` local and the `(void) base;` suppression when
the element has no nested heap-owned fields (e.g. list<u32>, map<char, u32>).

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>

* refactor(cpp): use static_cast for MapLower realloc result

The cast converts void* (from cabi_realloc) to uint8_t*, which is a
well-defined static_cast and doesn't need a C-style cast.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>

* fix(cpp): zero length when moving wit::map

Leaves the moved-from map in a fully consistent state so any later
inspection of size()/empty() reflects the empty invariant, not just
the destructor's short-circuit on a null data_ pointer.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>

* style(cpp): break long single-line methods in wit::map

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>

* refactor(cpp): drop wit::map operator[]

Index-based subscript on a map is a footgun: integral keys would
silently compile while doing positional access. Iteration via
range-for and pointer access via data() are sufficient for codegen
and don't carry the same expectation mismatch.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>

* refactor(cpp): drop std::span accessors from wit::map

A span of pairs is a vector-shaped view that doesn't fit a map
abstraction; codegen sites that need a flat pair span build it
explicitly from data() and size() at the call site.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>

* feat(cpp): introduce wit::map_view for borrowed map arguments

Borrowed map arguments were surfacing as std::span<std::pair<K,V> const>,
which carries vector-shaped affordances (positional indexing, span
conversions) on what is conceptually a map. wit::map_view is a borrow-
only counterpart to wit::map that mimics map semantics rather than
vector semantics.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>

* refactor(cpp): rename wit::map to wit::unordered_map

Component-model map<K,V> carries no ordering or hashing guarantee, and
the type's API surface deliberately mirrors std::unordered_map (size,
empty, begin/end) plus bindings-construction primitives, so the name
should reflect the unordered semantics rather than std::map's ordered
ones. Companion borrow type renamed to wit::unordered_map_view.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>

* fix(cpp): align map iteration variable with renamed _base

Adjacent block bodies (string/list/option dealloc) now reference _base
after main's rename, so MapLower / MapLift / GuestDeallocateMap must
declare the per-entry pointer under the same name to compile. Adds the
matching (void) _base; suppression so loops still compile when the
inner body doesn't reference it.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>

* refactor(cpp): remove unordered_map_view and update map handling

The `unordered_map_view` class has been removed to streamline the API, as it was a borrow-only handle that mimicked map semantics. The code now directly utilizes `std::span` for borrowed map arguments, ensuring a clearer distinction between map and vector semantics. Additionally, the handling of dependencies has been updated to include `<span>` where necessary.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>

---------

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
* Fix exception safety violation in AbiBuffer::advance

* Add more explanation
Signed-off-by: Andrew Steurer <94206073+asteurer@users.noreply.github.com>
* Move all async tests to general folder

WASIp3 and component-model-async have shipped and are stable, so these
are no longer expected to fail.

* Try to fix CI failure

* Try to fix Go in CI

* Fix codegen test expectation

* Another round of attempting ignores

* Disable broken tests

I'm tired of trying to work around them, just disable them.

* Tweak CI configuration
* Update wasm-tools dependencies

Additionally update C intrinsics for threading as they've been renamed
slightly.

* Remove unused import
[automatically-tag-and-release-this-commit]

Co-authored-by: Auto Release Process <auto-release-process@users.noreply.github.com>
Merge upstream wit-bindgen 0.59.0 into the vendored bindgen subtree.

- Bump wit-bindgen-core 0.58 -> 0.59, wit-parser 0.251 -> 0.253 and
  wit-component 0.252 -> 0.253.
- API churn carried into the vendored generators:
  - `WorldGenerator::preprocess` now returns `Result<()>` (upstream
    bytecodealliance/wit-bindgen#1648); update the Rust and Go generator impls.
  - wit-parser 0.253 replaces `Resolve::push_group(UnresolvedPackageGroup::parse(..))`
    with `Resolve::push_str(..)` in the Rust `generate!` macro
    (bytecodealliance/wit-bindgen#1654).
- Carry the new codegen input (single-version-package); it generates without
  changes.
- Carry upstream's move of the Go `strings` runtime test into `disabled/`.

Non-carries (not applicable to wRPC, resolved as delete/ours during the merge):
- The resource-machinery changes in `crates/rust/src/interface.rs`
  (`resource_into_raw_`/`resource_from_raw_`, the `ResourceRep`/`Resource`
  runtime bounds and the new `guest-rust/src/resource.rs` module,
  `{camel}Borrow` provenance) and the `bindgen.rs` `FunctionBindgen::lift`
  provenance fix target upstream's canonical-ABI guest resource lowering; wRPC
  generates transport stubs and vendors none of that machinery.
- bytecodealliance/wit-bindgen#1468 `merge_structurally_equal_types` (macro/generator option and its
  codegen test) is a deferred feature; wRPC's Rust generator has no such option.
- The rebooted Go generator (`crates/go`) and the other guest backends
  (`crates/{c,cpp,csharp,markdown,moonbit}`, `crates/guest-rust` runtime) stay
  dropped; wRPC's `wit-bindgen-go` is the independent pre-reboot fork and
  `wit-bindgen-core` is consumed as a published crate.
- The new/relocated `tests/runtime` and `tests/threading` cases (future/stream
  cancellation, yield loops, block-on, cross-task wakeup, arena-allocated
  resources, threading builtins, ...) exercise the guest canonical-ABI async
  runtime, which wRPC does not implement (async is over the transport).

rust codegen and go codegen tests pass (864 codegen, 87 components, 41 runtime);
`cargo clippy --workspace` (and `--features serde`) and `cargo doc --workspace`
are clean; the Go integration suite passes and all examples build.

Assisted-by: claude:claude-opus-4-8
Upstream diff: bytecodealliance/wit-bindgen@v0.58.0...v0.59.0
@rvolosatovs
rvolosatovs force-pushed the merge/wit-bindgen-0.59 branch from facd7b1 to ab1bbd0 Compare July 20, 2026 16:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants