diff --git a/Cargo.lock b/Cargo.lock index 1c635f94d..b2cb1db08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3260,8 +3260,8 @@ name = "test-helpers" version = "0.0.0" dependencies = [ "codegen-macro", - "wit-bindgen-core 0.44.0", - "wit-parser 0.236.1", + "wit-bindgen-core 0.45.1", + "wit-parser 0.238.1", ] [[package]] @@ -4190,17 +4190,6 @@ dependencies = [ "thiserror 2.0.18", ] -[[package]] -name = "wasmparser" -version = "0.236.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9b1e81f3eb254cf7404a82cee6926a4a3ccc5aad80cc3d43608a070c67aa1d7" -dependencies = [ - "bitflags", - "indexmap", - "semver", -] - [[package]] name = "wasmparser" version = "0.238.1" @@ -4980,17 +4969,6 @@ version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" -[[package]] -name = "wit-bindgen-core" -version = "0.44.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4103c7a3e178b75cd8b0b574fa199ed015e8399c9859b003865cc28834b474b" -dependencies = [ - "anyhow", - "heck", - "wit-parser 0.236.1", -] - [[package]] name = "wit-bindgen-core" version = "0.45.1" @@ -5098,7 +5076,7 @@ dependencies = [ "anyhow", "clap", "heck", - "wit-bindgen-core 0.44.0", + "wit-bindgen-core 0.45.1", "wrpc-introspect", ] @@ -5116,7 +5094,7 @@ dependencies = [ "serde_json", "syn", "tokio", - "wit-bindgen-core 0.44.0", + "wit-bindgen-core 0.45.1", "wit-bindgen-wrpc", "wrpc-introspect", "wrpc-transport", @@ -5131,7 +5109,7 @@ dependencies = [ "proc-macro2", "quote", "syn", - "wit-bindgen-core 0.44.0", + "wit-bindgen-core 0.45.1", "wit-bindgen-wrpc-rust", ] @@ -5147,7 +5125,7 @@ dependencies = [ "serde", "serde_json", "toml 0.8.23", - "wit-parser 0.236.1", + "wit-parser 0.238.1", ] [[package]] @@ -5207,24 +5185,6 @@ dependencies = [ "wit-parser 0.252.0", ] -[[package]] -name = "wit-parser" -version = "0.236.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16e4833a20cd6e85d6abfea0e63a399472d6f88c6262957c17f546879a80ba15" -dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser 0.236.1", -] - [[package]] name = "wit-parser" version = "0.238.1" @@ -5322,7 +5282,7 @@ dependencies = [ "wasmtime", "wasmtime-cli-flags", "wasmtime-wasi", - "wit-bindgen-core 0.44.0", + "wit-bindgen-core 0.45.1", "wit-bindgen-wrpc", "wit-bindgen-wrpc-go", "wit-bindgen-wrpc-rust", @@ -5348,7 +5308,7 @@ dependencies = [ name = "wrpc-introspect" version = "0.7.0" dependencies = [ - "wit-parser 0.236.1", + "wit-parser 0.238.1", ] [[package]] @@ -5459,7 +5419,7 @@ dependencies = [ "wasm-tokio", "wasmtime", "wasmtime-wasi", - "wit-parser 0.236.1", + "wit-parser 0.238.1", "wrpc-introspect", "wrpc-transport", ] diff --git a/Cargo.toml b/Cargo.toml index 07acb575b..c6fc547c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -179,14 +179,14 @@ wasmtime-cli-flags = { version = "45", default-features = false } wasmtime-wasi = { version = "45", default-features = false } wasmtime-wasi-http = { version = "45", default-features = false } wit-bindgen = { version = "0.45", default-features = false } -wit-bindgen-core = { version = "0.44", default-features = false } +wit-bindgen-core = { version = "0.45", default-features = false } wit-bindgen-wrpc = { version = "0.11", default-features = false, path = "./crates/wit-bindgen" } wit-bindgen-wrpc-go = { version = "0.13", default-features = false, path = "./crates/wit-bindgen-go" } wit-bindgen-wrpc-rust = { version = "0.11", default-features = false, path = "./crates/wit-bindgen-rust" } wit-bindgen-wrpc-rust-macro = { version = "0.11", default-features = false, path = "./crates/wit-bindgen-rust-macro" } wit-bindgen-wrpc-test = { version = "0.1", default-features = false, path = "./crates/wit-bindgen-test" } wit-component = { version = "0.252", default-features = false } -wit-parser = { version = "0.236", default-features = false } +wit-parser = { version = "0.238", default-features = false } wrpc-cli = { version = "0.8", path = "./crates/cli", default-features = false } wrpc-introspect = { version = "0.7", default-features = false, path = "./crates/introspect" } wrpc-pack = { version = "0.4", path = "./crates/pack", default-features = false } diff --git a/crates/test-helpers/src/lib.rs b/crates/test-helpers/src/lib.rs index d48f6cd0d..55794ed27 100644 --- a/crates/test-helpers/src/lib.rs +++ b/crates/test-helpers/src/lib.rs @@ -90,9 +90,9 @@ pub fn run_world_codegen_test( fn parse_wit(path: &Path) -> (Resolve, WorldId) { let mut resolve = Resolve::default(); let (pkg, _files) = resolve.push_path(path).unwrap(); - let world = resolve.select_world(pkg, None).unwrap_or_else(|_| { + let world = resolve.select_world(&[pkg], None).unwrap_or_else(|_| { // note: if there are multiples worlds in the wit package, we assume the "imports" world - resolve.select_world(pkg, Some("imports")).unwrap() + resolve.select_world(&[pkg], Some("imports")).unwrap() }); (resolve, world) } diff --git a/crates/wit-bindgen-rust-macro/src/lib.rs b/crates/wit-bindgen-rust-macro/src/lib.rs index a6cea4878..e711b8fac 100644 --- a/crates/wit-bindgen-rust-macro/src/lib.rs +++ b/crates/wit-bindgen-rust-macro/src/lib.rs @@ -177,7 +177,7 @@ fn select_world( world: Option<&str>, ) -> anyhow::Result { if pkgs.len() == 1 { - resolve.select_world(pkgs[0], world) + resolve.select_world(pkgs, world) } else { assert!(!pkgs.is_empty()); if let Some(name) = world { @@ -190,11 +190,11 @@ fn select_world( // This will ignore the package argument due to the fully // qualified name being used. - resolve.select_world(pkgs[0], world) + resolve.select_world(pkgs, world) } else { let worlds = pkgs .iter() - .filter_map(|p| resolve.select_world(*p, None).ok()) + .filter_map(|p| resolve.select_world(&[*p], None).ok()) .collect::>(); match &worlds[..] { [] => anyhow::bail!("no packages have a world"), diff --git a/crates/wit-bindgen-rust/src/lib.rs b/crates/wit-bindgen-rust/src/lib.rs index 910871e82..341fab7ae 100644 --- a/crates/wit-bindgen-rust/src/lib.rs +++ b/crates/wit-bindgen-rust/src/lib.rs @@ -137,7 +137,8 @@ pub struct Opts { #[cfg_attr(feature = "clap", arg(long, value_name = "NAME"))] pub additional_derive_ignore: Vec, - /// Remapping of interface names to rust module names. + /// Remapping of wit import interface and type names to Rust module names + /// and types. /// /// Argument must be of the form `k=v` and this option can be passed /// multiple times or one option can be comma separated, for example @@ -352,17 +353,28 @@ impl RustWrpc { is_export: bool, ) -> Result { let with_name = resolve.name_world_key(name); - let Some(remapping) = self.with.get(&with_name) else { - bail!("no remapping found for {with_name:?} - use the `generate!` macro's `with` option to force the interface to be generated or specify where it is already defined: + // `with` remappings only apply to imports; exports are always generated + // since their types are defined by the implementation. + let remapping = if is_export { + &TypeGeneration::Generate + } else { + let Some(remapping) = self.with.get(&with_name) else { + bail!("no remapping found for {with_name:?} - use the `generate!` macro's `with` option to force the interface to be generated or specify where it is already defined: ``` with: {{\n\t{with_name:?}: generate\n}} ```") + }; + remapping }; self.generated_types.insert(with_name); let entry = match remapping { TypeGeneration::Remap(remapped_path) => { let name = format!("__with_name{}", self.with_name_counter); self.with_name_counter += 1; + uwriteln!( + self.src, + "#[allow(unfulfilled_lint_expectations, unused_imports)]" + ); uwriteln!(self.src, "use {remapped_path} as {name};"); InterfaceName { remapped: true, @@ -511,7 +523,7 @@ impl WorldGenerator for RustWrpc { let world = &resolve.worlds[world]; // Specify that all imports local to the world's package should be generated - for (key, item) in world.imports.iter().chain(world.exports.iter()) { + for (key, item) in world.imports.iter() { if let WorldItem::Interface { id, .. } = item && resolve.interfaces[*id].package == world.package { @@ -615,14 +627,8 @@ impl WorldGenerator for RustWrpc { let mut to_define = Vec::new(); for (name, ty_id) in resolve.interfaces[id].types.iter() { let full_name = full_wit_type_name(resolve, *ty_id); - if let Some(type_gen) = self.with.get(&full_name) { - // skip type definition generation for remapped types - if type_gen.generated() { - to_define.push((name, ty_id)); - } - } else { - to_define.push((name, ty_id)); - } + // `with` remappings only apply to imports; exported types are always generated. + to_define.push((name, ty_id)); self.generated_types.insert(full_name); } diff --git a/crates/wit-bindgen-rust/tests/codegen.rs b/crates/wit-bindgen-rust/tests/codegen.rs new file mode 100644 index 000000000..84d9df93b --- /dev/null +++ b/crates/wit-bindgen-rust/tests/codegen.rs @@ -0,0 +1,33 @@ +#![allow(unused_macros)] +#![allow(dead_code, unused_variables)] + +#[allow(unused)] +mod multiple_paths { + wit_bindgen_wrpc::generate!({ + inline: r#" + package test:paths; + + world test { + import paths:path1/test; + export paths:path2/test; + } + "#, + path: ["tests/wit/path1", "tests/wit/path2"], + generate_all, + }); +} + +#[allow(unused)] +mod inline_and_path { + wit_bindgen_wrpc::generate!({ + inline: r#" + package test:paths; + + world test { + import test:inline-and-path/bar; + } + "#, + path: ["tests/wit/path3"], + generate_all, + }); +} diff --git a/crates/wit-bindgen-rust/tests/wit/path3/package.wit b/crates/wit-bindgen-rust/tests/wit/path3/package.wit new file mode 100644 index 000000000..0dea03e4f --- /dev/null +++ b/crates/wit-bindgen-rust/tests/wit/path3/package.wit @@ -0,0 +1,3 @@ +package test:inline-and-path; + +interface bar {} diff --git a/crates/wit-bindgen-test/src/lib.rs b/crates/wit-bindgen-test/src/lib.rs index 5e60feb51..33108aea1 100644 --- a/crates/wit-bindgen-test/src/lib.rs +++ b/crates/wit-bindgen-test/src/lib.rs @@ -304,12 +304,12 @@ impl Runner<'_> { ), }; resolve - .select_world(pkg, Some(runner_world.as_str())) + .select_world(&[pkg], Some(runner_world.as_str())) .with_context(|| { format!("failed to find expected `{runner_world}` world to generate bindings") })?; resolve - .select_world(pkg, Some(test_world.as_str())) + .select_world(&[pkg], Some(test_world.as_str())) .with_context(|| { format!("failed to find expected `{test_world}` world to generate bindings") })?; @@ -521,8 +521,12 @@ impl Runner<'_> { let mut resolve = wit_parser::Resolve::default(); let (pkg, _) = resolve.push_path(test).context("failed to load WIT")?; let world = resolve - .select_world(pkg, None) - .or_else(|err| resolve.select_world(pkg, Some("imports")).map_err(|_| err)) + .select_world(&[pkg], None) + .or_else(|err| { + resolve + .select_world(&[pkg], Some("imports")) + .map_err(|_| err) + }) .context("failed to select a world for bindings generation")?; let world = resolve.worlds[world].name.clone(); diff --git a/src/bin/wit-bindgen-wrpc.rs b/src/bin/wit-bindgen-wrpc.rs index 388115343..c4a5ab61a 100644 --- a/src/bin/wit-bindgen-wrpc.rs +++ b/src/bin/wit-bindgen-wrpc.rs @@ -167,7 +167,7 @@ fn gen_world( } } let (pkg, _files) = resolve.push_path(&opts.wit)?; - let world = resolve.select_world(pkg, opts.world.as_deref())?; + let world = resolve.select_world(&[pkg], opts.world.as_deref())?; generator.generate(&resolve, world, files)?; Ok(()) diff --git a/tests/codegen/resource-fallible-constructor.wit b/tests/codegen/resource-fallible-constructor.wit new file mode 100644 index 000000000..865350569 --- /dev/null +++ b/tests/codegen/resource-fallible-constructor.wit @@ -0,0 +1,12 @@ +package my:resources; + +interface fallible-constructor { + resource x { + constructor(s: string) -> result; + } +} + +world resources { + import fallible-constructor; + export fallible-constructor; +}