bytecodealliance / bytecodealliance/wit-bindgen
[Rust] Generated `variant` types are not scoped when generated under `mod wit_stream`
- Dominant language
- Rust
- Stars
- 1.5k
- Forks
- 286
- Avg merge
- 6h 32m
- Merged PRs (30d)
- 19
Description
When using a `variant` as the specified type for a `stream`, the type name is not scoped under the `wit_stream` mod. This causes error messages like:
```rust
Compiling witbindgen-demo v0.1.0 (C:\Users\dweller\source\repos\witbindgen-demo)
error[E0412]: cannot find type `ControlMessage` in this scope
--> C:\Users\user\source\repos\witbindgen-demo\target\debug\build\wit-bindgen-rust-macro-98169ddaab8381ff\out\module0.rs:160:41
|
160 | unsafe fn lift(ptr: *mut u8) -> ControlMessage {
| ^^^^^^^^^^^^^^ not found in this scope
|
help: consider importing this enum
|
114 + use crate::ControlMessage;
|
error[E0433]: failed to resolve: use of undeclared type `ControlMessage`
--> C:\Users\user\source\repos\witbindgen-demo\target\debug\build\wit-bindgen-rust-macro-98169ddaab8381ff\out\module0.rs:214:25
|
214 | ControlMessage::MethodCall(e13)
| ^^^^^^^^^^^^^^ use of undeclared type `ControlMessage`
|
help: consider importing this enum
|
114 + use crate::ControlMessage;
|
error[E0433]: failed to resolve: use of undeclared type `ControlMessage`
--> C:\Users\user\source\repos\witbindgen-demo\target\debug\build\wit-bindgen-rust-macro-98169ddaab8381ff\out\module0.rs:232:25
|
232 | ControlMessage::ModuleMessage(e13)
| ^^^^^^^^^^^^^^ use of undeclared type `ControlMessage`
|
help: consider importing this enum
|
114 + use crate::ControlMessage;
```
Example `wit` file:
```wit
package demo:module@1.0.0;
world module {
include wasi:io/imports@0.2.6;
variant control-message {
method-call(tuple>),
module-message(list),
}
export run: async func(control-stream: stream);
}
```
Generated with:
```rust
wit_bindgen::generate!({
world: "module",
path: r#"wit"#,
with: {
"wasi:io/streams@0.2.6": wasi::io::streams,
"wasi:io/error@0.2.6": wasi::io::error,
"wasi:io/poll@0.2.6": wasi::io::poll,
},
debug: true,
});
```
Cargo.toml:
```toml
[package]
name = "witbindgen-demo"
version = "0.1.0"
edition = "2024"
[dependencies]
wasi = "0.14.7"
wit-bindgen = "0.49.0"
```
I was able to fix it by prepending `crate::` where the variant name is being generated. It works for my use case, but it's not robust (it breaks when defining the `variant` inside an `interface` for example).
```diff
diff --git a/crates/rust/src/bindgen.rs b/crates/rust/src/bindgen.rs
index df362347..eeda6565 100644
--- a/crates/rust/src/bindgen.rs
+++ b/crates/rust/src/bindgen.rs
@@ -527,7 +527,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
self.push_str(&format!("match {op0} {{\n"));
for (case, block) in variant.cases.iter().zip(blocks) {
let case_name = case.name.to_upper_camel_case();
- self.push_str(&format!("{name}::{case_name}"));
+ self.push_str(&format!("crate::{name}::{case_name}"));
if case.ty.is_some() {
self.push_str(&format!("(e) => {block},\n"));
} else {
@@ -569,10 +569,10 @@ impl Bindgen for FunctionBindgen<'_, '_> {
}
let case_name = case.name.to_upper_camel_case();
if case.ty.is_none() {
- uwriteln!(self.src, "{name}::{case_name}");
+ uwriteln!(self.src, "crate::{name}::{case_name}");
} else {
uwriteln!(self.src, "let e{tmp} = {block};");
- uwriteln!(self.src, "{name}::{case_name}(e{tmp})");
+ uwriteln!(self.src, "crate::{name}::{case_name}(e{tmp})");
}
uwriteln!(self.src, "}}");
}
diff --git a/crates/rust/src/interface.rs b/crates/rust/src/interface.rs
index c9a55eb1..e89cad02 100644
--- a/crates/rust/src/interface.rs
+++ b/crates/rust/src/interface.rs
@@ -583,8 +583,8 @@ macro_rules! {macro_name} {{
PayloadFor::Future => "",
PayloadFor::Stream => ", _: usize",
};
- let mut lift_fn = format!("unsafe fn lift(ptr: *mut u8) -> {name} {{ {lift} }}");
- let mut lower_fn = format!("unsafe fn lower(value: {name}, ptr: *mut u8) {{ {lower} }}");
+ let mut lift_fn = format!("unsafe fn lift(ptr: *mut u8) -> crate::{name} {{ {lift} }}");
+ let mut lower_fn = format!("unsafe fn lower(value: crate::{name}, ptr: *mut u8) {{ {lower} }}");
let mut dealloc_lists_fn =
format!("unsafe fn dealloc_lists(ptr: *mut u8) {{ {dealloc_lists} }}");
let mut lift_arg = "lift";
@@ -655,7 +655,7 @@ pub mod vtable{ordinal} {{
{lower_fn}
{dealloc_lists_fn}
- pub static VTABLE: {async_support}::{camel}Vtable<{name}> = {async_support}::{camel}Vtable::<{name}> {{
+ pub static VTABLE: {async_support}::{camel}Vtable = {async_support}::{camel}Vtable:: {{
cancel_write,
cancel_read,
drop_writable,
@@ -671,7 +671,7 @@ pub mod vtable{ordinal} {{
start_write,
}};
- impl super::{camel}Payload for {name} {{
+ impl super::{camel}Payload for crate::{name} {{
const VTABLE: &'static {async_support}::{camel}Vtable = &VTABLE;
}}
}}
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.