From b3d53d314a67607846a020fef7bf628311c849d1 Mon Sep 17 00:00:00 2001 From: SasakiSaki <192608617@qq.com> Date: Mon, 1 Apr 2024 03:46:12 +0800 Subject: [PATCH] feat(rust): allow generate unused records and variants (#913) * feat(rust): allow generate unused records and variants * fix: empty record * rename: allow_unused -> generate_unused_types * test(rust): make sure unused types are exported --- crates/guest-rust/macro/src/lib.rs | 9 +++++++++ crates/guest-rust/src/lib.rs | 5 +++++ crates/rust/src/interface.rs | 11 +++++----- crates/rust/src/lib.rs | 4 ++++ crates/rust/tests/codegen.rs | 32 ++++++++++++++++++++++++++++++ tests/codegen/allow-unused.wit | 18 +++++++++++++++++ 6 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 tests/codegen/allow-unused.wit diff --git a/crates/guest-rust/macro/src/lib.rs b/crates/guest-rust/macro/src/lib.rs index e7636a751..d8c3b6465 100644 --- a/crates/guest-rust/macro/src/lib.rs +++ b/crates/guest-rust/macro/src/lib.rs @@ -113,6 +113,9 @@ impl Parse for Config { Opt::PubExportMacro(enable) => { opts.pub_export_macro = enable.value(); } + Opt::GenerateUnusedTypes(enable) => { + opts.generate_unused_types = enable.value(); + } } } } else { @@ -231,6 +234,7 @@ mod kw { syn::custom_keyword!(default_bindings_module); syn::custom_keyword!(export_macro_name); syn::custom_keyword!(pub_export_macro); + syn::custom_keyword!(generate_unused_types); } #[derive(Clone)] @@ -280,6 +284,7 @@ enum Opt { DefaultBindingsModule(syn::LitStr), ExportMacroName(syn::LitStr), PubExportMacro(syn::LitBool), + GenerateUnusedTypes(syn::LitBool), } impl Parse for Opt { @@ -398,6 +403,10 @@ impl Parse for Opt { input.parse::()?; input.parse::()?; Ok(Opt::PubExportMacro(input.parse()?)) + } else if l.peek(kw::generate_unused_types) { + input.parse::()?; + input.parse::()?; + Ok(Opt::GenerateUnusedTypes(input.parse()?)) } else { Err(l.error()) } diff --git a/crates/guest-rust/src/lib.rs b/crates/guest-rust/src/lib.rs index 2091c857c..8704223b0 100644 --- a/crates/guest-rust/src/lib.rs +++ b/crates/guest-rust/src/lib.rs @@ -785,6 +785,11 @@ /// // Disable a workaround to force wasm constructors to be run only once /// // when exported functions are called. /// disable_run_ctors_once_workaround: false, +/// +/// // Whether to generate unused `record`, `enum`, `variant` types. +/// // By default, they will not be generated unless they are used as input +/// // or return value of a function. +/// generate_unused_types: false, /// }); /// ``` /// diff --git a/crates/rust/src/interface.rs b/crates/rust/src/interface.rs index cc67e26c2..14fa05a0e 100644 --- a/crates/rust/src/interface.rs +++ b/crates/rust/src/interface.rs @@ -1329,12 +1329,13 @@ macro_rules! {macro_name} {{ fn modes_of(&self, ty: TypeId) -> Vec<(String, TypeMode)> { let info = self.info(ty); - // If this type isn't actually used, no need to generate it. - if !info.owned && !info.borrowed { - return Vec::new(); - } let mut result = Vec::new(); - + if !self.gen.opts.generate_unused_types { + // If this type isn't actually used, no need to generate it. + if !info.owned && !info.borrowed { + return result; + } + } // Generate one mode for when the type is owned and another for when // it's borrowed. let a = self.type_mode_for_id(ty, TypeOwnershipStyle::Owned, "'a"); diff --git a/crates/rust/src/lib.rs b/crates/rust/src/lib.rs index cfebf82a1..6bc65d52c 100644 --- a/crates/rust/src/lib.rs +++ b/crates/rust/src/lib.rs @@ -182,6 +182,10 @@ pub struct Opts { /// candidate for being exported outside of the crate. #[cfg_attr(feature = "clap", arg(long))] pub pub_export_macro: bool, + + /// Whether to generate unused structures, not generated by default (false) + #[cfg_attr(feature = "clap", arg(long))] + pub generate_unused_types: bool, } impl Opts { diff --git a/crates/rust/tests/codegen.rs b/crates/rust/tests/codegen.rs index 220cb7c81..6fe5f3afd 100644 --- a/crates/rust/tests/codegen.rs +++ b/crates/rust/tests/codegen.rs @@ -340,6 +340,7 @@ mod custom_derives { use exports::my::inline::blah::Foo; struct Component; + impl exports::my::inline::blah::Guest for Component { fn bar(cool: Foo) { // Check that built in derives that I've added actually work by seeing that this hashes @@ -452,3 +453,34 @@ mod with_and_resources { }); } } + +#[allow(unused)] +mod generate_unused_types { + use exports::foo::bar::component::UnusedEnum; + use exports::foo::bar::component::UnusedRecord; + use exports::foo::bar::component::UnusedVariant; + + wit_bindgen::generate!({ + inline: " + package foo:bar; + + world bindings { + export component; + } + + interface component { + variant unused-variant { + %enum(unused-enum), + %record(unused-record) + } + enum unused-enum { + unused + } + record unused-record { + x: u32 + } + } + ", + generate_unused_types: true, + }); +} diff --git a/tests/codegen/allow-unused.wit b/tests/codegen/allow-unused.wit new file mode 100644 index 000000000..ebb7ac626 --- /dev/null +++ b/tests/codegen/allow-unused.wit @@ -0,0 +1,18 @@ +package foo:bar; + +world bindings { + export component; +} + +interface component { + variant unused-variant { + %enum(unused-enum), + %record(unused-record) + } + enum unused-enum { + unused + } + record unused-record { + x: u32 + } +}