wit-bindgen
wit-bindgen copied to clipboard
Confusing error for Rust-exported items
When generating a rust-compiled-to-wasm module and you want to export things with the witx macro, it's possible to get a pretty confusing error. This Rust code:
witx_bindgen_rust::export!("w1.witx");
use w1::*;
struct Wasm;
impl w1::W1 for Wasm {
fn doubles(i: i32) -> i32 {
return i * 2;
}
}
with this *.witx
:
doubles: function(i: s32) -> s32
yields this error:
$ cargo test
Compiling witx-bindgen-rust v0.1.0 (/home/acrichto/code/witx-bindgen/crates/rust-wasm)
error[E0038]: the trait `w1::W1` cannot be made into an object
--> crates/rust-wasm/tests/wat.rs:1:1
|
1 | witx_bindgen_rust::export!("w1.witx");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `w1::W1` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> crates/rust-wasm/tests/wat.rs:1:1
|
1 | witx_bindgen_rust::export!("w1.witx");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| this trait cannot be made into an object...
| ...because associated function `doubles` has no `self` parameter
= note: this error originates in the macro `witx_bindgen_rust::export` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider turning `doubles` into a method by giving it a `&self` argument
|
1 | witx_bindgen_rust::export!(&self, "w1.witx");
| ^^^^^^
help: alternatively, consider constraining `doubles` so it does not apply to trait objects
|
1 | witx_bindgen_rust::export!("w1.witx"); where Self: Sized
| ^^^^^^^^^^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0038`.
error: could not compile `witx-bindgen-rust`
To learn more, run the command again with --verbose.
The problem is that the generated code expects a W1
struct to be defined in the parent namespace but it's not. Instead W1
is defined as the trait itself (via the use
-glob) which causes a bad error.
Should we also file an issue against rustc for the erroneous "help" of modifying the proc macro invocation site?
Perhaps? That's a pretty systemic problems where errors in macros just in general have pretty awful compiler diagnostics. I've always assumed it's a known issue that doesn't have a great solution, but I could be wrong!
I ran into this problem, and fixed it by changing from struct Wasm
/impl w1::W1 for Wasm
to struct W1
/impl w1::W1 for W1
. With that said, aside from the comment that:
The problem is that the generated code expects a W1 struct to be defined in the parent namespace but it's not. Instead W1 is defined as the trait itself (via the use-glob) which causes a bad error.*
... I don't really understand why that's a problem in the first place and would love it if someone could enlighten me!
I'm confused, do we still have a macro with witx
in the name? I thought that had all been changed in favor of wit
.
What if we made bindgen an attribute macro so that you could do something like this?
#[wit-bindgen]
#[export("w1.witx")]
struct Wasm;
Then the attribute macro could use whatever type name you attach it to instead of having to use a predetermined one. This could also be done for the wit-bindgen macro as well.
This would also create more consistency for where the macro goes in the file.
This may also be related to https://github.com/bytecodealliance/wit-bindgen/issues/243 where in general I think attribute macros or derives would be a better idea than the current "pray the type exists at this place" logic.
It'd also be great if somewhere along the way these attributes could pass more configuration to the code generators so users can do things like add more derives to generated types.
I think that this has been fixed with the export_*!(...)
macro nowadays, so closing.