fix(rust): dealias stream/future types#1524
Closed
ricochet wants to merge 1 commit intobytecodealliance:mainfrom
Closed
fix(rust): dealias stream/future types#1524ricochet wants to merge 1 commit intobytecodealliance:mainfrom
ricochet wants to merge 1 commit intobytecodealliance:mainfrom
Conversation
This change dealiases inside print_ty during recursion, so it catches aliases at every nesting depth. PR bytecodealliance#1482 only dealiases the top-level payload type. That works when the payload itself is an alias (e.g., future<error-code>), but not when the payload is an anonymous type that contains aliases (e.g., future<result<_, error-code>>). Fixes bytecodealliance#1523 Resolves bytecodealliance#1432
Member
|
Thanks! This is something I've long wanted to improve the internals of (managing payloads/etc). I'm hoping to use bytecodealliance/wasm-tools#2447 to make some deeper refactors in wit-bindgen and get things fixed to ensure this issue doesn't crop up again. I'll be working tomorrow on threading that through, and if it takes too long I'll review this a bit closer. |
alexcrichton
added a commit
to alexcrichton/wit-bindgen
that referenced
this pull request
Feb 10, 2026
Previously stream/future payload were generated by collecting the set of types used in `future` and `stream` types in a WIT, rendering them to a string, deduplicating based on this string representation, and then generating various impls-with-vtables. This stringification strategy unfortunately falls down in a few situations such as: * Type aliases in WIT render as two names in Rust, but they're using the same Rust type. * Types with the same definition, but in multiple modules, will have two different paths in Rust but alias the same type. * Primitives may be used directly in streams/futures but then additionally used as a WIT type alias. In all of these situations it's effectively exposing how Rust requires at most one-impl-per-type-definition but the stringification/deduping was just a proxy for implementing this restriction and not a precise calculation. Using the work from bytecodealliance/wasm-tools#2447 as well as bytecodealliance#1468 it's possible to do all of this without stringifying. Specifically bytecodealliance#1468, transitively enabled by bytecodealliance/wasm-tools#2447, enables building a set of equal types that the Rust generator knows will all alias the same type definition. Using this it's possible to translate a payload to its "canonical payload" representation ID-wise and perform hashing/deduplication based on that. This in turn solves all of the issues above as well as previous issues such as bytecodealliance#1432 and bytecodealliance#1433 without requiring the workaround in bytecodealliance#1482. The end result is that all of these various bugs should be fixed and the Rust generator should be much more reliable about when exactly a trait impl is emitted vs not. Closes bytecodealliance#1523 Closes bytecodealliance#1524
Member
|
Ok I think I've got everything working now and this is finalized as #1528. A much more invasive fix than this, but also a more complete one in that it handles a few more cases this doesn't and is knocks down a few barriers I've wanted to handle for quite some time now. |
Contributor
Author
|
Closing in favor of #1528 |
alexcrichton
added a commit
to alexcrichton/wit-bindgen
that referenced
this pull request
Feb 10, 2026
Previously stream/future payload were generated by collecting the set of types used in `future` and `stream` types in a WIT, rendering them to a string, deduplicating based on this string representation, and then generating various impls-with-vtables. This stringification strategy unfortunately falls down in a few situations such as: * Type aliases in WIT render as two names in Rust, but they're using the same Rust type. * Types with the same definition, but in multiple modules, will have two different paths in Rust but alias the same type. * Primitives may be used directly in streams/futures but then additionally used as a WIT type alias. In all of these situations it's effectively exposing how Rust requires at most one-impl-per-type-definition but the stringification/deduping was just a proxy for implementing this restriction and not a precise calculation. Using the work from bytecodealliance/wasm-tools#2447 as well as bytecodealliance#1468 it's possible to do all of this without stringifying. Specifically bytecodealliance#1468, transitively enabled by bytecodealliance/wasm-tools#2447, enables building a set of equal types that the Rust generator knows will all alias the same type definition. Using this it's possible to translate a payload to its "canonical payload" representation ID-wise and perform hashing/deduplication based on that. This in turn solves all of the issues above as well as previous issues such as bytecodealliance#1432 and bytecodealliance#1433 without requiring the workaround in bytecodealliance#1482. The end result is that all of these various bugs should be fixed and the Rust generator should be much more reliable about when exactly a trait impl is emitted vs not. Closes bytecodealliance#1523 Closes bytecodealliance#1524
github-merge-queue bot
pushed a commit
that referenced
this pull request
Feb 12, 2026
* rust: Reimplement how stream/future payloads work Previously stream/future payload were generated by collecting the set of types used in `future` and `stream` types in a WIT, rendering them to a string, deduplicating based on this string representation, and then generating various impls-with-vtables. This stringification strategy unfortunately falls down in a few situations such as: * Type aliases in WIT render as two names in Rust, but they're using the same Rust type. * Types with the same definition, but in multiple modules, will have two different paths in Rust but alias the same type. * Primitives may be used directly in streams/futures but then additionally used as a WIT type alias. In all of these situations it's effectively exposing how Rust requires at most one-impl-per-type-definition but the stringification/deduping was just a proxy for implementing this restriction and not a precise calculation. Using the work from bytecodealliance/wasm-tools#2447 as well as #1468 it's possible to do all of this without stringifying. Specifically #1468, transitively enabled by bytecodealliance/wasm-tools#2447, enables building a set of equal types that the Rust generator knows will all alias the same type definition. Using this it's possible to translate a payload to its "canonical payload" representation ID-wise and perform hashing/deduplication based on that. This in turn solves all of the issues above as well as previous issues such as #1432 and #1433 without requiring the workaround in #1482. The end result is that all of these various bugs should be fixed and the Rust generator should be much more reliable about when exactly a trait impl is emitted vs not. Closes #1523 Closes #1524 * Try fixing CI * Fix typo * Fix rust CI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This change dealiases inside print_ty during recursion, so it catches
aliases at every nesting depth.
PR #1482 only dealiases the top-level payload type.
That works when the payload itself is an alias
(e.g., future), but not when the payload is an anonymous
type that contains aliases (e.g., future<result<_, error-code>>).
Fixes #1523
Resolves #1432