jrandolf opened PR #14870 from jrandolf:typed-map-support to bytecodealliance:main:
This makes the typed API and
bindgen!more flexible about which Rust type amap<K, V>maps to, and fixes the handle leak from duplicate keys. One commit each:
More map types.
ComponentType/Lift/Lowerare now implemented for:
BTreeMap<K, V>, which works withoutstdand lowers entries in sorted order. That gives embedders who care about deterministic execution a deterministic lowering order, unlikeHashMap.HashMap<K, V, S>with any hasher (lifting needsS: BuildHasher + Default).- A new
MapEntries<K, V>, a newtype aroundVec<(K, V)>that keeps entries in order, including duplicate keys.All of these share one lift and one lower helper, which validate the pointer and length before allocating, as #14835 does for
HashMap.
bindgen!map_typeoption. It picks the Rust type used for WIT maps, e.g.map_type: std::collections::BTreeMapormap_type: wasmtime::component::MapEntries. This mirrors the guest-side wit-bindgen option. WithBTreeMap,additional_derives: [Hash, Ord, ...]also works for records containing maps.- Duplicate keys with handles (#14812). Lifting a map whose values contain handles into a type that keeps one value per key (
HashMap,BTreeMap) is now an error if any key repeats, and the error points toMapEntries. The keys can't contain handles themselves, so they're all lifted and checked before any values, which means no handle has been transferred by the time the error happens. Maps whose values don't contain handles keep the last-value-wins behaviour. Whether the value type contains handles is computed once when the map type is built.Some questions I'd appreciate input on:
- Is
MapEntriesthe right shape (a public tuple field, noDeref)? Or would something like a lazyWasmMapview fit better? I didn't go with that, because re-reading a value would transferownhandles again.- Erroring on duplicates is a deliberate departure from the spec's "may dedupe" for maps holding handles. Does that seem OK? It also errors for values with only
borrowhandles, which don't actually leak, because the existing handle tracking doesn't tellownandborrowapart.- Should
hashbrown::HashMapalso get an impl whenstdis enabled? Today it only has one in no_std builds.This overlaps with #14835 (the refactored lift already validates before allocating), and with #14837 and #14838 in the
bindgen!map type formatting. I'll rebase on whichever lands first.Closes #14832
Closes #14812
Last updated: Oct 31 2026 at 23:03 UTC