wit-bindgen icon indicating copy to clipboard operation
wit-bindgen copied to clipboard

No longer able to generate bindings in submodule

Open rylev opened this issue 1 year ago • 3 comments

The following works in the latest release but not on main:

package my-ns:my-package;

interface my-interface {
  my-func: func();
}

world my-world {
  import my-interface;
  export my-interface;
}
mod bindings {
    wit_bindgen::generate!({
        path: "wit",
    });
}

use bindings::exports::my_ns::my_package::my_interface::Guest;

bindings::export!(Impl);

struct Impl;

impl Guest for Impl {
    fn my_func() {}
}

On the main, the following error shows:

error[E0433]: failed to resolve: could not find `export` in the crate root
  --> src/lib.rs:3:5
   |
3  | /     wit_bindgen::generate!({
4  | |         path: "wit",
5  | |     });
   | |______^ could not find `export` in the crate root
...
10 |   bindings::export!(Impl);
   |   ----------------------- in this macro invocation

Seems we're now assuming something lives at the crate root which we did not assume before.

rylev avatar Jun 12 '24 15:06 rylev

Locally this example gets the same error on 0.20-0.26 (latest is 0.26), so I think this has been an error for quite some time? Things changed in the 0.19->0.20 transition but not in a way that had this working before.

Regardless though the fix is to use the default_bindings_module option here specified as "crate::bindings"

alexcrichton avatar Jun 12 '24 17:06 alexcrichton

Confirmed this is an issue in 0.26 - not sure why I thought it was working in 0.26 previously... I normally use a submodule for bindings, and I'm pretty sure I haven't been stuck only on old versions of wit-bindgen. Strange.

The fix is obviously not very discoverable. I'm guessing going back to the previous behavior of everything just working™ is not a possibility as otherwise default_bindings_module wouldn't have been introduced.

Any thoughts on how we can make this more straight forward?

Edit: I believe what tripped me up was that wastime::component::bindgen! doesn't have this limitation.

rylev avatar Jun 13 '24 08:06 rylev

I've attempted to cover this in the documentation and I agree it's unfortunate. That being said I don't know of a better solution. It's a problem where a macro invocation in Rust doesn't know the path to itself, which is what's needed here, because the generate! macro is generating an export! macro and export! needs to refer to the other generated items, and there's no hygiene in Rust to enable that. Fundamentally export! has to know where it's located in the crate.

I'd love to do better here of course though, but I don't know what to do other than document it and perhaps provide an example (which doesn't currently exist but would be good to have)

alexcrichton avatar Jun 13 '24 15:06 alexcrichton