fix: disambiguate colliding WIT import names#1562
Draft
jsturtevant wants to merge 10 commits into
Draft
Conversation
Contributor
Author
|
This will be ontop of #1331 |
736b4f5 to
6ff506c
Compare
When multiple WIT packages export an interface with the same name (e.g. a:pkg/types and b:pkg/types), the generated Rust traits have duplicate associated types and getters, causing compilation to fail. Add collision detection that scans import declarations for duplicate interface names. When a collision is found, the full namespace path is prepended to produce unique names (e.g. APkgTypes vs BPkgTypes). Apply this to host, guest, and runtime type generation, and extend it to handle versioned import name collisions where two versioned imports share the same namespace path. Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
Add deps/a-pkg/types.wit and deps/b-pkg/types.wit to the bindgen-test-cases WIT fixture. Both define an interface named "types", creating a name collision that exercises the disambiguation logic added in the previous commit. Extend the world to import both packages and add collision host tests to the existing bindgen_test_cases test module, covering: - distinct generated record types (collision_types_are_distinct) - separate host trait impl per colliding interface (collision_host_impl_compiles) Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
When two WIT packages differ only at the colon/slash boundary and both
components contain hyphens (e.g. a:b-c vs a-b:c), flat-joining the
namespace array with '-' produces the same string ('a-b-c') for both,
and thus the same disambiguated Rust type name.
Fix this by introducing component_first_camel(), which capitalizes only
the first letter of each namespace component (removing internal hyphens
without capitalizing sub-words). Concatenating per-component results
preserves boundary info: ['a', 'b-c'] -> 'ABcTypes' is distinct from
['a-b', 'c'] -> 'AbCTypes'. Getter names are unchanged.
Add a unit test covering the pathological case.
Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
8541352 to
277b64c
Compare
Extends the bindgen-test-cases WIT fixture with four additional imports
to cover edge cases identified in code review:
- a:b-c/types and a-b:c/types (hyphenated namespace components): verify
that packages whose namespace paths differ only by hyphen placement
produce distinct Rust names. Flat-joining both with '-' gives the
same 'a-b-c' string; the per-component strip-and-join approach
produces 'ABcTypes'/'a_bc_types' vs 'AbCTypes'/'ab_c_types'.
- c:pkg/types@1.0.0 and c:pkg/types@2.0.0 (versioned): verify that
two versions of the same package interface are disambiguated by
appending the version: CPkgTypesV100 and CPkgTypesV200.
Also fixes the getter-name collision for hyphenated namespace components.
Previously the getter prefix was built with wn.namespaces.join("-"),
which is not injective: ["a", "b-c"] and ["a-b", "c"] both flatten to
"a-b-c" -> "a_b_c_types". The fix strips internal hyphens within each
component and joins at colon/slash boundaries with "_", giving
"a_bc_types" vs "ab_c_types".
New dep WIT packages:
deps/a-bc/types.wit (a:b-c)
deps/ab-c/types.wit (a-b:c)
deps/c-pkg-v1/types.wit (c:pkg@1.0.0)
deps/c-pkg-v2/types.wit (c:pkg@2.0.0)
New integration tests in bindgen_test_cases module:
versioned_collision_types_are_distinct
hyphenated_namespace_collision_types_are_distinct
Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
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.
Stacks on #1331.
When two WIT packages export an interface with the same short name, the generated Rust trait has duplicate members and fails to compile. For example:
After this fix, the full namespace is prepended per component to produce unique names:
Two imports from the same package at different versions — the version is appended:
Also fixes a secondary collision where namespace components themselves contain hyphens (e.g.
a:b-c/typesvsa-b:c/types). Flat-joining with-collapsed both toABCTypes; per-component first-letter capitalisation now givesABcTypesvsAbCTypes.