support enums with more than 256 variants in derive macro (#4370)
* support enums with more than 256 variants in derive macro This addresses #4361. Technically, we now support up to 2^32 variants, which is the maximum for the canonical ABI. In practice, though, the derived code for enums with even just 2^16 variants takes a prohibitively long time to compile. Signed-off-by: Joel Dice <joel.dice@fermyon.com> * simplify `LowerExpander::expand_variant` code Signed-off-by: Joel Dice <joel.dice@fermyon.com>
This commit is contained in:
15
crates/misc/component-macro-test/Cargo.toml
Normal file
15
crates/misc/component-macro-test/Cargo.toml
Normal file
@@ -0,0 +1,15 @@
|
||||
[package]
|
||||
name = "component-macro-test"
|
||||
authors = ["The Wasmtime Project Developers"]
|
||||
license = "Apache-2.0 WITH LLVM-exception"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1.0"
|
||||
quote = "1.0"
|
||||
syn = { version = "1.0", features = ["full"] }
|
||||
34
crates/misc/component-macro-test/src/lib.rs
Normal file
34
crates/misc/component-macro-test/src/lib.rs
Normal file
@@ -0,0 +1,34 @@
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::quote;
|
||||
use syn::parse_macro_input;
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn add_variants(
|
||||
attr: proc_macro::TokenStream,
|
||||
item: proc_macro::TokenStream,
|
||||
) -> proc_macro::TokenStream {
|
||||
expand_variants(
|
||||
&parse_macro_input!(attr as syn::LitInt),
|
||||
parse_macro_input!(item as syn::ItemEnum),
|
||||
)
|
||||
.unwrap_or_else(syn::Error::into_compile_error)
|
||||
.into()
|
||||
}
|
||||
|
||||
fn expand_variants(count: &syn::LitInt, mut ty: syn::ItemEnum) -> syn::Result<TokenStream> {
|
||||
let count = count
|
||||
.base10_digits()
|
||||
.parse::<usize>()
|
||||
.map_err(|_| syn::Error::new(count.span(), "expected unsigned integer"))?;
|
||||
|
||||
ty.variants = (0..count)
|
||||
.map(|index| syn::Variant {
|
||||
attrs: Vec::new(),
|
||||
ident: syn::Ident::new(&format!("V{}", index), Span::call_site()),
|
||||
fields: syn::Fields::Unit,
|
||||
discriminant: None,
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(quote!(#ty))
|
||||
}
|
||||
Reference in New Issue
Block a user