From 0fbc25b399824c934b044a0fbf61df9152b6e48c Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 1 Jun 2026 16:01:31 -0700 Subject: [PATCH] c: Fix type name collisions with anonymous types Classify fewer types as "primitive" to help get the names to line up. Closes #1621 --- crates/c/src/lib.rs | 11 +++++++++++ tests/codegen/issue-1621.wit | 16 ++++++++++++++++ tests/runtime/flavorful/runner.c | 2 +- tests/runtime/flavorful/test.c | 2 +- 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 tests/codegen/issue-1621.wit diff --git a/crates/c/src/lib.rs b/crates/c/src/lib.rs index 96345c210..b44848d51 100644 --- a/crates/c/src/lib.rs +++ b/crates/c/src/lib.rs @@ -1068,6 +1068,17 @@ fn is_prim_type(resolve: &Resolve, ty: &Type) -> bool { } fn is_prim_type_id(resolve: &Resolve, id: TypeId) -> bool { + // A named type contributes its (interface-local) name to the generated + // type name rather than its structure, so even when its underlying + // representation is primitive it must not be treated as a world-shareable + // "primitive" type. Otherwise two interfaces that each define a + // differently-typed but identically-named type (e.g. `field-value` in two + // versions of `wasi:http/types`) collapse onto the same anonymous type + // name, producing structs with incompatible element pointer types. + // See https://github.com/bytecodealliance/wit-bindgen/issues/1621. + if resolve.types[id].name.is_some() { + return false; + } match &resolve.types[id].kind { TypeDefKind::List(elem) => is_prim_type(resolve, elem), diff --git a/tests/codegen/issue-1621.wit b/tests/codegen/issue-1621.wit new file mode 100644 index 000000000..05ad6edee --- /dev/null +++ b/tests/codegen/issue-1621.wit @@ -0,0 +1,16 @@ +package my:test; + +interface a { + type t = list; + f: func() -> list; +} + +interface b { + type t = list; + g: func() -> list; +} + +world w { + import a; + import b; +} diff --git a/tests/runtime/flavorful/runner.c b/tests/runtime/flavorful/runner.c index 57b2017f6..c86eb4c27 100644 --- a/tests/runtime/flavorful/runner.c +++ b/tests/runtime/flavorful/runner.c @@ -79,7 +79,7 @@ void exports_runner_run() { test_list_typedef3_t b; b.ptr = &b_str; b.len = 1; - runner_tuple2_list_typedef2_list_typedef3_t ret; + test_tuple2_list_typedef2_list_typedef3_t ret; test_list_typedefs(&a, &b, &ret); assert(memcmp(ret.f0.ptr, "typedef3", ret.f0.len) == 0); diff --git a/tests/runtime/flavorful/test.c b/tests/runtime/flavorful/test.c index 8fb6e6dc6..c200b0fd8 100644 --- a/tests/runtime/flavorful/test.c +++ b/tests/runtime/flavorful/test.c @@ -65,7 +65,7 @@ bool exports_test_errno_result(exports_test_my_errno_t *err) { void exports_test_list_typedefs( exports_test_list_typedef_t *a, exports_test_list_typedef3_t *c, - test_tuple2_list_typedef2_list_typedef3_t *ret) { + exports_test_tuple2_list_typedef2_list_typedef3_t *ret) { assert(memcmp(a->ptr, "typedef1", a->len) == 0); exports_test_list_typedef_free(a);