Skip to content

Commit 105bf6c

Browse files
wit-bindgen: Prevent conflicting StreamPayload/FuturePayload implementations (#1482)
WIT 'use' statements are represented as Type::Id(_) Types in this codebase, and get translated to Rust type aliases in the generated Rust bindings. Since these aliases may be located at different module paths, creating a StreamPayload or FuturePayload implementation for more than one of these paths will cause the Rust compiler to complain about conflicting trait implementations for the same type. This commit solves this issue by dealiasing payload types of the form Type::Id(_) when generating a key for the future_payloads and stream_payloads maps. This means each alias set will have at most one implementation of these traits. Fixes issue 1432
1 parent 76e9f08 commit 105bf6c

File tree

6 files changed

+74
-18
lines changed

6 files changed

+74
-18
lines changed

crates/rust/src/bindgen.rs

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -427,13 +427,19 @@ impl Bindgen for FunctionBindgen<'_, '_> {
427427
Instruction::FutureLift { payload, .. } => {
428428
let async_support = self.r#gen.r#gen.async_support_path();
429429
let op = &operands[0];
430-
let name = payload
431-
.as_ref()
432-
.map(|ty| {
433-
self.r#gen
434-
.type_name_owned_with_id(ty, Identifier::StreamOrFuturePayload)
435-
})
436-
.unwrap_or_else(|| "()".into());
430+
let name = match payload {
431+
Some(Type::Id(type_id)) => {
432+
let dealiased_id = dealias(resolve, *type_id);
433+
self.r#gen.type_name_owned_with_id(
434+
&Type::Id(dealiased_id),
435+
Identifier::StreamOrFuturePayload,
436+
)
437+
}
438+
Some(ty) => self
439+
.r#gen
440+
.type_name_owned_with_id(ty, Identifier::StreamOrFuturePayload),
441+
None => "()".into(),
442+
};
437443
let ordinal = self
438444
.r#gen
439445
.r#gen
@@ -455,13 +461,19 @@ impl Bindgen for FunctionBindgen<'_, '_> {
455461
Instruction::StreamLift { payload, .. } => {
456462
let async_support = self.r#gen.r#gen.async_support_path();
457463
let op = &operands[0];
458-
let name = payload
459-
.as_ref()
460-
.map(|ty| {
461-
self.r#gen
462-
.type_name_owned_with_id(ty, Identifier::StreamOrFuturePayload)
463-
})
464-
.unwrap_or_else(|| "()".into());
464+
let name = match payload {
465+
Some(Type::Id(type_id)) => {
466+
let dealiased_id = dealias(resolve, *type_id);
467+
self.r#gen.type_name_owned_with_id(
468+
&Type::Id(dealiased_id),
469+
Identifier::StreamOrFuturePayload,
470+
)
471+
}
472+
Some(ty) => self
473+
.r#gen
474+
.type_name_owned_with_id(ty, Identifier::StreamOrFuturePayload),
475+
None => "()".into(),
476+
};
465477
let ordinal = self
466478
.r#gen
467479
.r#gen

crates/rust/src/interface.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -523,10 +523,13 @@ macro_rules! {macro_name} {{
523523
func_name: &str,
524524
payload_type: Option<&Type>,
525525
) {
526-
let name = if let Some(payload_type) = payload_type {
527-
self.type_name_owned(payload_type)
528-
} else {
529-
"()".into()
526+
let name = match payload_type {
527+
Some(Type::Id(type_id)) => {
528+
let dealiased_id = dealias(self.resolve, *type_id);
529+
self.type_name_owned(&Type::Id(dealiased_id))
530+
}
531+
Some(payload_type) => self.type_name_owned(payload_type),
532+
None => "()".into(),
530533
};
531534
let map = match payload_for {
532535
PayloadFor::Future => &mut self.r#gen.future_payloads,

crates/test/src/cpp.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ impl LanguageMethods for Cpp {
4949
"async-trait-function.wit"
5050
| "error-context.wit"
5151
| "futures.wit"
52+
| "import-export-future.wit"
53+
| "import-export-stream.wit"
5254
| "resources-with-futures.wit"
5355
| "resources-with-streams.wit"
5456
| "streams.wit"

crates/test/src/csharp.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ impl LanguageMethods for Csharp {
4848
| "error-context.wit"
4949
| "resource-fallible-constructor.wit"
5050
| "async-resource-func.wit"
51+
| "import-export-stream.wit"
5152
)
5253
}
5354

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//@ async = true
2+
3+
package a:b;
4+
5+
world w {
6+
import i;
7+
export i;
8+
}
9+
10+
interface i {
11+
use t.{r};
12+
f: func(p: future<r>);
13+
}
14+
15+
interface t {
16+
record r {
17+
x: u32,
18+
}
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//@ async = true
2+
3+
package a:b;
4+
5+
world w {
6+
import i;
7+
export i;
8+
}
9+
10+
interface i {
11+
use t.{r};
12+
f: func(p: stream<r>);
13+
}
14+
15+
interface t {
16+
record r {
17+
x: u32,
18+
}
19+
}

0 commit comments

Comments
 (0)