diff --git a/crates/guest-rust/macro/src/lib.rs b/crates/guest-rust/macro/src/lib.rs index 472cfb3e5..adba0a9f5 100644 --- a/crates/guest-rust/macro/src/lib.rs +++ b/crates/guest-rust/macro/src/lib.rs @@ -116,6 +116,9 @@ impl Parse for Config { Opt::PubExportMacro(enable) => { opts.pub_export_macro = enable.value(); } + Opt::GenerateUnusedTypes(enable) => { + opts.generate_unused_types = enable.value(); + } } } } else { @@ -235,6 +238,7 @@ mod kw { syn::custom_keyword!(export_macro_name); syn::custom_keyword!(pub_export_macro); syn::custom_keyword!(wasm64); + syn::custom_keyword!(generate_unused_types); } #[derive(Clone)] @@ -285,6 +289,7 @@ enum Opt { ExportMacroName(syn::LitStr), PubExportMacro(syn::LitBool), Wasm64, + GenerateUnusedTypes(syn::LitBool), } impl Parse for Opt { @@ -406,6 +411,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 13ca4522c..39b60dc96 100644 --- a/crates/rust/src/interface.rs +++ b/crates/rust/src/interface.rs @@ -1354,12 +1354,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 8caf4a967..635cd51dd 100644 --- a/crates/rust/src/lib.rs +++ b/crates/rust/src/lib.rs @@ -186,6 +186,10 @@ pub struct Opts { /// Generate code for 64bit wasm #[cfg_attr(feature = "clap", arg(long))] pub wasm64: 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 + } +}