Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rust: Revert back to historical way of exporting functions (bytecodea…
…lliance#871) * rust: Revert back to historical way of exporting functions This commit is unfortunately a bit of whiplash for Rust users as it transitions the `wit_bindgen::generate!` macro to what it was a few months ago in terms of how exports work. Before describing that, though, let's first motivate this commit. Today exports are not easy to work with in the Rust generator. To be clear this is no one's fault (either that or it's mostly mine), it's just the best we could think of at the time to get resources working. Whenever the `generate!` macro is invoked it's required to specify all exports to the macro via an `exports: { ... }` map. This is required for exported resources so generated bindings know what types to refer to. The problems with this approach are: * You can't generate bindings ahead-of-time, bindings can only be generated when everything is "done". This means crates like `wasi` have to do weird things to bind exports and it wouldn't even work if there were exported resource types. * There's a circular nature between user code and generated code. Generated code uses user types, but user types also use generated code. While this can work it has a very high risk of generating confusing error messages that are difficult to debug. The upside of today's `exports` approach is that it works! These downsides were well-known before they were implemented, but at the time we couldn't think of anything better. Yesterday, however, I had an epiphany that I think we can do better. This PR removes all the `exports: { ... }` bits entirely. Instead a completely different system is now in place for managing the exports of a crate. This system is basically the same as what everything was before `exports: { ... }` with a few cosmetic tweaks: 1. The `generate!` macro generates everything but does not export anything. This means that from a build process perspective `generate!` should be a noop. (e.g. it can be gc'd away) 2. The `generate!` macro does not refer to any user-defined types, so it should be a little silo which is much nicer from a composability point of view. 3. Resource exports still have concrete types generated. Generated bindings look very similar to before. The main difference is that instead of `OwnT` for `own<T>` exports and `&MyT` for `borrow<T>` exports they generate `T` and `TBorrow<'_>` where both of those types are bindings-generated. 4. The `generate!` macro itself generates a macro: `export_{name}!`. Here `{name}` is based on the world being bound. This macro is what actually exports an implementation and generates `#[no_mangle]` functions. Overall this is basically what we had before (if I'm remembering correctly). The cosmetic tweaks come in the implementation. For example the `export_*!` macro has two forms instead of one: export_foo!(MyWorldImplementation); // .. is the same as ... export_foo!(MyWorldImplementation with_types_in self); Here the second form solves the problem where `export_foo!` doesn't know the crate path back to itself, so it's optionally specified after `with_types_in`. By default this is `self` meaning that it's expected that `export_foo!` is located adjacent to the call to `generate!`. This can be configured though with a new Rust macro option `default_bindings_module: "..."`. Additionally the `export_foo!` macro is not exported from the crate by default, but that can also be configured with `pub_export_macros: true` now. Included in this commit are other changes such as: * Improved documentation for `generate!`, including documenting the state of the world after this commit. * A new test for cross-crate behavior of the `generate!` macro. * The Rust macro `export` option and `--export` CLI flag are both removed. * Generated bindings for exported resource types are different and require manual method calls like `.get()` with an annotation of what the destination type is. * Guests may need to implement more traits now as an `interface` with `resource`s but no functions must be implemented to configured resource types as associated types. * The `WasmResource` trait, `Resource<T>` type, and `RustResource` trait are all now purely internal to the bindings and shouldn't show up in the public API. * A new `default_bindings_module` option configures the default location to find where bindings are generated in the `export_*!` macro. * A new `pub_export_macros` option configures whether macros are exported out of the current crate. And finally, a good way to see the impact of this change is to browse the changes in the `tests/runtime/*` directory to all the `wasm.rs` files. * Flag new crate as not-published * Apply `#[doc(hidden)]` to internal methods * Add more documentation for the `wit-bindgen` Rust crate * Add a README * Add documentation to get rendered on docs.rs with pre-expanded versions of WIT documents. * Change the default export macro * Name it `export!` instead of `export_{name}!` * Add an option to configure the name. * Try to fix tests * Fix example build * Fix typo * Add some resources to the xcrate-test
- Loading branch information