From 053ae970d86ae0acf64bfe38325c83abfc928563 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Mon, 9 Feb 2026 18:51:25 -0500 Subject: [PATCH] fix(rust): dealias stream/future types 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>). Fixes #1523 Resolves #1432 --- crates/rust/src/interface.rs | 11 ++++++++++- crates/rust/tests/codegen.rs | 1 + tests/codegen/import-export-future.wit | 15 +++++++++++++++ tests/codegen/import-export-stream.wit | 15 +++++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/crates/rust/src/interface.rs b/crates/rust/src/interface.rs index 3e2412e90..11142d84b 100644 --- a/crates/rust/src/interface.rs +++ b/crates/rust/src/interface.rs @@ -1753,7 +1753,16 @@ unsafe fn call_import(&mut self, _params: Self::ParamsLower, _results: *mut u8) } match ty { - Type::Id(t) => self.print_tyid(*t, mode), + Type::Id(t) => { + // When generating names for stream/future payload types, dealias + // all inner type references so that `use`d type aliases from + // different interfaces resolve to the same canonical type + let t = match self.identifier { + Identifier::StreamOrFuturePayload => dealias(self.resolve, *t), + _ => *t, + }; + self.print_tyid(t, mode) + } Type::Bool => self.push_str("bool"), Type::U8 => self.push_str("u8"), Type::U16 => self.push_str("u16"), diff --git a/crates/rust/tests/codegen.rs b/crates/rust/tests/codegen.rs index 44ddf31d8..06cfafe53 100644 --- a/crates/rust/tests/codegen.rs +++ b/crates/rust/tests/codegen.rs @@ -172,3 +172,4 @@ mod retyped_list { } }); } + diff --git a/tests/codegen/import-export-future.wit b/tests/codegen/import-export-future.wit index 0f84e77af..22a8e25d3 100644 --- a/tests/codegen/import-export-future.wit +++ b/tests/codegen/import-export-future.wit @@ -5,6 +5,8 @@ package a:b; world w { import i; export i; + import j; + import k; } interface i { @@ -12,6 +14,19 @@ interface i { f: func(p: future); } +// Multiple interfaces `use`-ing the same type from a shared interface +// and wrapping it in an anonymous type (result<_, r>) ensures that +// dealiasing resolves inner types, not just top-level payload types. +interface j { + use t.{r}; + f: func() -> future>; +} + +interface k { + use t.{r}; + f: func() -> future>; +} + interface t { record r { x: u32, diff --git a/tests/codegen/import-export-stream.wit b/tests/codegen/import-export-stream.wit index ee45bfdb1..d6a52da65 100644 --- a/tests/codegen/import-export-stream.wit +++ b/tests/codegen/import-export-stream.wit @@ -5,6 +5,8 @@ package a:b; world w { import i; export i; + import j; + import k; } interface i { @@ -12,6 +14,19 @@ interface i { f: func(p: stream); } +// Multiple interfaces `use`-ing the same type from a shared interface +// and wrapping it in an anonymous type (result<_, r>) ensures that +// dealiasing resolves inner types, not just top-level payload types. +interface j { + use t.{r}; + f: func() -> stream>; +} + +interface k { + use t.{r}; + f: func() -> stream>; +} + interface t { record r { x: u32,