diff --git a/crates/rune-macros/src/any.rs b/crates/rune-macros/src/any.rs index e20c8e219..41c76a46b 100644 --- a/crates/rune-macros/src/any.rs +++ b/crates/rune-macros/src/any.rs @@ -84,14 +84,22 @@ impl syn::parse::Parse for Derive { impl Derive { pub(super) fn into_any_builder(self, cx: &Context) -> Result, ()> { - let attr = cx.type_attrs(&self.input.attrs)?; - + let attr = cx.type_attrs(&self.input.attrs); let tokens = cx.tokens_with_module(attr.module.as_ref()); let mut installers = Vec::new(); expand_install_with(cx, &self.input, &tokens, &attr, &mut installers)?; + if matches!(&self.input.data, syn::Data::Enum(..)) { + if let Some(span) = attr.constructor { + cx.error(syn::Error::new( + span, + "#[rune(constructor)] is not supported on enums, only its variants", + )); + } + } + let name = match &attr.name { Some(name) => name, None => &self.input.ident, @@ -174,7 +182,7 @@ fn expand_struct_install_with( attr: &TypeAttr, ) -> Result<(), ()> { for (n, field) in st.fields.iter().enumerate() { - let attrs = cx.field_attrs(&field.attrs)?; + let attrs = cx.field_attrs(&field.attrs); let name; let index; @@ -224,6 +232,7 @@ fn expand_struct_install_with( syn::Fields::Named(fields) => { let constructor = attr .constructor + .is_some() .then(|| { let args = fields.named.iter().map(|f| { let ident = f.ident.as_ref().expect("named fields must have an Ident"); @@ -301,7 +310,7 @@ fn expand_enum_install_with( for (variant_index, variant) in en.variants.iter().enumerate() { let span = variant.fields.span(); - let variant_attr = cx.variant_attr(&variant.attrs)?; + let variant_attr = cx.variant_attr(&variant.attrs); let mut variant_docs = syn::ExprArray { attrs: Vec::new(), @@ -323,7 +332,7 @@ fn expand_enum_install_with( let mut field_names = Vec::new(); for f in &fields.named { - let attrs = cx.field_attrs(&f.attrs)?; + let attrs = cx.field_attrs(&f.attrs); let Some(f_ident) = &f.ident else { cx.error(syn::Error::new_spanned(f, "Missing field name")); @@ -358,7 +367,7 @@ fn expand_enum_install_with( for (n, field) in fields.unnamed.iter().enumerate() { let span = field.span(); - let attrs = cx.field_attrs(&field.attrs)?; + let attrs = cx.field_attrs(&field.attrs); if attrs.field { fields_len += 1; @@ -379,16 +388,14 @@ fn expand_enum_install_with( enum_.variant_mut(#variant_index)?.make_unnamed(#fields_len)?.static_docs(&#variant_docs)? }); - let constructor = if variant_attr.constructor { - if fields_len != fields.unnamed.len() { - cx.error(syn::Error::new_spanned(fields, "#[rune(constructor)] can only be used if all fields are marked with #[rune(get)")); - return Err(()); - } + if variant_attr.constructor.is_some() && fields_len != fields.unnamed.len() { + cx.error(syn::Error::new_spanned(fields, "#[rune(constructor)] can only be used if all fields are marked with #[rune(get)")); + } - Some(quote!(#ident #type_generics :: #variant_ident)) - } else { - None - }; + let constructor = variant_attr + .constructor + .is_some() + .then(|| quote!(#ident #type_generics :: #variant_ident)); variants.push((constructor, variant_attr)); } @@ -397,7 +404,7 @@ fn expand_enum_install_with( enum_.variant_mut(#variant_index)?.make_empty()?.static_docs(&#variant_docs)? }); - let constructor = if variant_attr.constructor { + let constructor = if variant_attr.constructor.is_some() { Some(quote!(|| #ident #type_generics :: #variant_ident)) } else { None diff --git a/crates/rune-macros/src/const_value.rs b/crates/rune-macros/src/const_value.rs index a1f95de63..ad842bb55 100644 --- a/crates/rune-macros/src/const_value.rs +++ b/crates/rune-macros/src/const_value.rs @@ -33,7 +33,7 @@ pub(super) struct ConstBuilder { impl Derive { pub(super) fn into_builder(self, cx: &Context) -> Result, ()> { - let attr = cx.const_value_type_attrs(&self.input.attrs)?; + let attr = cx.const_value_type_attrs(&self.input.attrs); let tokens = cx.tokens_with_module(attr.module.as_ref()); let body; @@ -57,7 +57,7 @@ impl Derive { let mut fields = Vec::new(); for (index, field) in data.fields.iter().enumerate() { - let attr = cx.const_value_field_attrs(&field.attrs)?; + let attr = cx.const_value_field_attrs(&field.attrs); let member = match &field.ident { Some(ident) => syn::Member::Named(ident.clone()), diff --git a/crates/rune-macros/src/context.rs b/crates/rune-macros/src/context.rs index cbcccec05..fb8915b0d 100644 --- a/crates/rune-macros/src/context.rs +++ b/crates/rune-macros/src/context.rs @@ -12,6 +12,7 @@ use syn::Token; /// Parsed `#[rune(..)]` field attributes. #[derive(Default)] +#[must_use = "Attributes must be used or explicitly ignored"] pub(crate) struct FieldAttrs { /// A field that is an identifier. Should use `Default::default` to be /// constructed and ignored during `ToTokens` and `Spanned`. @@ -46,6 +47,7 @@ impl FieldAttrs { /// Parsed #[const_value(..)] field attributes. #[derive(Default)] +#[must_use = "Attributes must be used or explicitly ignored"] pub(crate) struct ConstValueFieldAttrs { /// Define a custom parsing method. pub(crate) with: Option, @@ -68,6 +70,7 @@ impl Default for ParseKind { /// Parsed field attributes. #[derive(Default)] +#[must_use = "Attributes must be used or explicitly ignored"] pub(crate) struct TypeAttr { /// `#[rune(name = TypeName)]` to override the default type name. pub(crate) name: Option, @@ -80,7 +83,7 @@ pub(crate) struct TypeAttr { /// `#[rune(item = )]`. pub(crate) item: Option, /// `#[rune(constructor)]`. - pub(crate) constructor: bool, + pub(crate) constructor: Option, /// Parsed documentation. pub(crate) docs: Vec, /// Indicates that this is a builtin type, so don't generate an `Any` @@ -100,6 +103,7 @@ pub(crate) struct TypeAttr { /// Parsed #[const_value(..)] field attributes. #[derive(Default)] +#[must_use = "Attributes must be used or explicitly ignored"] pub(crate) struct ConstValueTypeAttr { /// `#[const_value(module = )]`. pub(crate) module: Option, @@ -107,9 +111,10 @@ pub(crate) struct ConstValueTypeAttr { /// Parsed variant attributes. #[derive(Default)] +#[must_use = "Attributes must be used or explicitly ignored"] pub(crate) struct VariantAttrs { /// `#[rune(constructor)]`. - pub(crate) constructor: bool, + pub(crate) constructor: Option, /// Discovered documentation. pub(crate) docs: Vec, } @@ -169,6 +174,47 @@ impl Context { } } + /// Helper to build using a function that takes a context. + pub(super) fn build(f: impl FnOnce(&Self) -> Result) -> TokenStream { + let cx = Self::new(); + cx.build_inner(f) + } + + /// Helper to build using a function that takes a context internally. + pub(super) fn build_with_crate( + f: impl FnOnce(&Self) -> Result, + ) -> TokenStream { + let cx = Self::with_crate(); + cx.build_inner(f) + } + + fn build_inner(self, f: impl FnOnce(&Self) -> Result) -> TokenStream { + fn to_compile_errors(errors: I) -> TokenStream + where + I: IntoIterator, + { + let mut stream = TokenStream::default(); + + for error in errors { + stream.extend(error.into_compile_error()); + } + + stream + } + + let Ok(builder) = f(&self) else { + return to_compile_errors(self.errors.into_inner()); + }; + + let errors = self.errors.into_inner(); + + if !errors.is_empty() { + return to_compile_errors(errors); + } + + builder + } + /// Register an error. pub(crate) fn error(&self, error: syn::Error) { self.errors.borrow_mut().push(error) @@ -192,11 +238,7 @@ impl Context { Ok(ident) } - pub(crate) fn const_value_field_attrs( - &self, - input: &[syn::Attribute], - ) -> Result { - let mut error = false; + pub(crate) fn const_value_field_attrs(&self, input: &[syn::Attribute]) -> ConstValueFieldAttrs { let mut attr = ConstValueFieldAttrs::default(); for a in input { @@ -218,20 +260,15 @@ impl Context { }); if let Err(e) = result { - error = true; self.error(e); }; } - if error { - return Err(()); - } - - Ok(attr) + attr } /// Parse field attributes. - pub(crate) fn field_attrs(&self, input: &[syn::Attribute]) -> Result { + pub(crate) fn field_attrs(&self, input: &[syn::Attribute]) -> FieldAttrs { macro_rules! generate_assign { ($proto:ident, $op:tt) => { |g| { @@ -277,7 +314,6 @@ impl Context { }; } - let mut error = false; let mut attr = FieldAttrs::default(); for a in input { @@ -457,23 +493,14 @@ impl Context { }); if let Err(e) = result { - error = true; self.error(e); } } - if error { - return Err(()); - } - - Ok(attr) + attr } - pub(crate) fn const_value_type_attrs( - &self, - input: &[syn::Attribute], - ) -> Result { - let mut error = false; + pub(crate) fn const_value_type_attrs(&self, input: &[syn::Attribute]) -> ConstValueTypeAttr { let mut attr = ConstValueTypeAttr::default(); for a in input { @@ -500,21 +527,15 @@ impl Context { }); if let Err(e) = result { - error = true; self.error(e); }; } - if error { - return Err(()); - } - - Ok(attr) + attr } /// Parse field attributes. - pub(crate) fn type_attrs(&self, input: &[syn::Attribute]) -> Result { - let mut error = false; + pub(crate) fn type_attrs(&self, input: &[syn::Attribute]) -> TypeAttr { let mut attr = TypeAttr::default(); for a in input { @@ -567,7 +588,14 @@ impl Context { meta.input.parse::()?; attr.install_with = Some(parse_path_compat(meta.input)?); } else if meta.path == CONSTRUCTOR { - attr.constructor = true; + if attr.constructor.is_some() { + return Err(syn::Error::new( + meta.path.span(), + "#[rune(constructor)] must only be used once", + )); + } + + attr.constructor = Some(meta.path.span()); } else if meta.path == BUILTIN { attr.builtin = Some(meta.path.span()); } else if meta.path == STATIC_TYPE { @@ -599,23 +627,17 @@ impl Context { }); if let Err(e) = result { - error = true; self.error(e); }; } } - if error { - return Err(()); - } - - Ok(attr) + attr } /// Parse and extract variant attributes. - pub(crate) fn variant_attr(&self, input: &[syn::Attribute]) -> Result { + pub(crate) fn variant_attr(&self, input: &[syn::Attribute]) -> VariantAttrs { let mut attr = VariantAttrs::default(); - let mut error = false; for a in input { if a.path().is_ident("doc") { @@ -629,14 +651,14 @@ impl Context { if a.path() == RUNE { let result = a.parse_nested_meta(|meta| { if meta.path == CONSTRUCTOR { - if attr.constructor { - return Err(syn::Error::new_spanned( - &meta.path, + if attr.constructor.is_some() { + return Err(syn::Error::new( + meta.path.span(), "#[rune(constructor)] must only be used once", )); } - attr.constructor = true; + attr.constructor = Some(meta.path.span()); } else { return Err(syn::Error::new_spanned(&meta.path, "Unsupported attribute")); } @@ -645,17 +667,12 @@ impl Context { }); if let Err(e) = result { - error = true; self.error(e); }; } } - if error { - return Err(()); - } - - Ok(attr) + attr } /// Parse path to custom field function. diff --git a/crates/rune-macros/src/from_value.rs b/crates/rune-macros/src/from_value.rs index 45a99fd2e..6bd5729bd 100644 --- a/crates/rune-macros/src/from_value.rs +++ b/crates/rune-macros/src/from_value.rs @@ -3,12 +3,12 @@ use proc_macro2::TokenStream; use quote::{quote, quote_spanned}; use syn::spanned::Spanned as _; -struct Expander { - cx: Context, +struct Expander<'cx> { + cx: &'cx Context, tokens: Tokens, } -impl Expander { +impl Expander<'_> { /// Expand on a struct. fn expand_struct( &mut self, @@ -209,7 +209,7 @@ impl Expander { } = &self.tokens; for (index, field) in unnamed.unnamed.iter().enumerate() { - let _ = self.cx.field_attrs(&field.attrs)?; + let _ = self.cx.field_attrs(&field.attrs); from_values.push(quote! { match tuple.get(#index) { @@ -233,7 +233,7 @@ impl Expander { for field in &named.named { let ident = self.field_ident(field)?; - let _ = self.cx.field_attrs(&field.attrs)?; + let _ = self.cx.field_attrs(&field.attrs); let name = &syn::LitStr::new(&ident.to_string(), ident.span()); @@ -260,35 +260,22 @@ impl Expander { } } -pub(super) fn expand(input: &syn::DeriveInput) -> Result> { - let cx = Context::new(); - - let Ok(attr) = cx.type_attrs(&input.attrs) else { - return Err(cx.errors.into_inner()); - }; - +pub(super) fn expand(cx: &Context, input: &syn::DeriveInput) -> Result { + let attr = cx.type_attrs(&input.attrs); let tokens = cx.tokens_with_module(attr.module.as_ref()); let mut expander = Expander { cx, tokens }; match &input.data { - syn::Data::Struct(st) => { - if let Ok(expanded) = expander.expand_struct(input, st) { - return Ok(expanded); - } - } - syn::Data::Enum(en) => { - if let Ok(expanded) = expander.expand_enum(input, en) { - return Ok(expanded); - } - } + syn::Data::Struct(st) => expander.expand_struct(input, st), + syn::Data::Enum(en) => expander.expand_enum(input, en), syn::Data::Union(un) => { expander.cx.error(syn::Error::new_spanned( un.union_token, "not supported on unions", )); + + Err(()) } } - - Err(expander.cx.errors.into_inner()) } diff --git a/crates/rune-macros/src/lib.rs b/crates/rune-macros/src/lib.rs index 6570d3842..aefe7b825 100644 --- a/crates/rune-macros/src/lib.rs +++ b/crates/rune-macros/src/lib.rs @@ -130,78 +130,59 @@ pub fn attribute_macro( #[doc(hidden)] pub fn to_tokens(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let derive = syn::parse_macro_input!(input as to_tokens::Derive); - derive.expand().unwrap_or_else(to_compile_errors).into() + Context::build(|cx| derive.expand(cx)).into() } #[proc_macro_derive(Parse, attributes(rune))] #[doc(hidden)] pub fn parse(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let derive = syn::parse_macro_input!(input as parse::Derive); - derive.expand().unwrap_or_else(to_compile_errors).into() + Context::build(|cx| derive.expand(cx)).into() } #[proc_macro_derive(Spanned, attributes(rune))] #[doc(hidden)] pub fn spanned(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let derive = syn::parse_macro_input!(input as spanned::Derive); - derive - .expand(false) - .unwrap_or_else(to_compile_errors) - .into() + Context::build(|cx| derive.expand(cx, false)).into() } #[proc_macro_derive(OptionSpanned, attributes(rune))] #[doc(hidden)] pub fn option_spanned(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let derive = syn::parse_macro_input!(input as spanned::Derive); - derive.expand(true).unwrap_or_else(to_compile_errors).into() + Context::build(|cx| derive.expand(cx, true)).into() } #[proc_macro_derive(Opaque, attributes(rune))] #[doc(hidden)] pub fn opaque(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let derive = syn::parse_macro_input!(input as opaque::Derive); - derive.expand().unwrap_or_else(to_compile_errors).into() + Context::build(|cx| derive.expand(cx)).into() } #[proc_macro_derive(FromValue, attributes(rune))] pub fn from_value(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input = syn::parse_macro_input!(input as syn::DeriveInput); - from_value::expand(&input) - .unwrap_or_else(to_compile_errors) - .into() + Context::build(|cx| from_value::expand(cx, &input)).into() } #[proc_macro_derive(ToValue, attributes(rune))] pub fn to_value(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input = syn::parse_macro_input!(input as syn::DeriveInput); - to_value::expand(&input) - .unwrap_or_else(to_compile_errors) - .into() + Context::build(|cx| to_value::expand(cx, &input)).into() } #[proc_macro_derive(Any, attributes(rune))] pub fn any(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let derive = syn::parse_macro_input!(input as any::Derive); - let cx = Context::new(); - - let Ok(builder) = derive.into_any_builder(&cx) else { - return to_compile_errors(cx.errors.into_inner()).into(); - }; - - builder.expand().into() + Context::build(|cx| Ok(derive.into_any_builder(cx)?.expand())).into() } #[proc_macro_derive(ToConstValue, attributes(const_value))] pub fn const_value(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let derive = syn::parse_macro_input!(input as const_value::Derive); - let cx = Context::new(); - - let Ok(builder) = derive.into_builder(&cx) else { - return to_compile_errors(cx.errors.into_inner()).into(); - }; - - builder.expand().into() + Context::build(|cx| Ok(derive.into_builder(cx)?.expand())).into() } /// Calculate a type hash at compile time. @@ -262,14 +243,8 @@ pub fn item(input: proc_macro::TokenStream) -> proc_macro::TokenStream { #[proc_macro] #[doc(hidden)] pub fn __internal_impl_any(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let internal_call = syn::parse_macro_input!(input as any::InternalCall); - let cx = Context::with_crate(); - - let Ok(builder) = internal_call.into_any_builder(&cx) else { - return to_compile_errors(cx.errors.into_inner()).into(); - }; - - builder.expand().into() + let derive = syn::parse_macro_input!(input as any::InternalCall); + Context::build_with_crate(|cx| Ok(derive.into_any_builder(cx)?.expand())).into() } /// Shim for an ignored `#[stable]` attribute. diff --git a/crates/rune-macros/src/opaque.rs b/crates/rune-macros/src/opaque.rs index e5d7769a7..8d78200a0 100644 --- a/crates/rune-macros/src/opaque.rs +++ b/crates/rune-macros/src/opaque.rs @@ -16,42 +16,39 @@ impl syn::parse::Parse for Derive { } impl Derive { - pub(super) fn expand(self) -> Result> { - let cx = Context::new(); - let tokens = cx.tokens_with_module(None); - + pub(super) fn expand(self, cx: &Context) -> Result { + let attr = cx.type_attrs(&self.input.attrs); + let tokens = cx.tokens_with_module(attr.module.as_ref()); let mut expander = Expander { cx, tokens }; match &self.input.data { - syn::Data::Struct(st) => { - if let Ok(stream) = expander.expand_struct(&self.input, st) { - return Ok(stream); - } - } + syn::Data::Struct(st) => Ok(expander.expand_struct(&self.input, st)?), syn::Data::Enum(en) => { expander.cx.error(syn::Error::new_spanned( en.enum_token, "not supported on enums", )); + + Err(()) } syn::Data::Union(un) => { expander.cx.error(syn::Error::new_spanned( un.union_token, "not supported on unions", )); + + Err(()) } } - - Err(expander.cx.errors.into_inner()) } } -struct Expander { - cx: Context, +struct Expander<'cx> { + cx: &'cx Context, tokens: Tokens, } -impl Expander { +impl Expander<'_> { /// Expand on a struct. fn expand_struct( &mut self, @@ -81,7 +78,7 @@ impl Expander { let mut field = None; for (n, f) in fields.iter().enumerate() { - let attrs = self.cx.field_attrs(&f.attrs)?; + let attrs = self.cx.field_attrs(&f.attrs); if attrs.id.is_some() { if field.is_some() { diff --git a/crates/rune-macros/src/parse.rs b/crates/rune-macros/src/parse.rs index 662f61f49..2fb6c77b8 100644 --- a/crates/rune-macros/src/parse.rs +++ b/crates/rune-macros/src/parse.rs @@ -20,42 +20,40 @@ impl syn::parse::Parse for Derive { } impl Derive { - pub(super) fn expand(self) -> Result> { - let cx = Context::new(); - let tokens = cx.tokens_with_module(None); + pub(super) fn expand(self, cx: &Context) -> Result { + let attr = cx.type_attrs(&self.input.attrs); + let tokens = cx.tokens_with_module(attr.module.as_ref()); let mut expander = Expander { cx, tokens }; match &self.input.data { - syn::Data::Struct(st) => { - if let Ok(stream) = expander.expand_struct(&self.input, st) { - return Ok(stream); - } - } + syn::Data::Struct(st) => expander.expand_struct(&self.input, st), syn::Data::Enum(en) => { expander.cx.error(syn::Error::new_spanned( en.enum_token, "not supported on enums", )); + + Err(()) } syn::Data::Union(un) => { expander.cx.error(syn::Error::new_spanned( un.union_token, "not supported on unions", )); + + Err(()) } } - - Err(expander.cx.errors.into_inner()) } } -struct Expander { - cx: Context, +struct Expander<'cx> { + cx: &'cx Context, tokens: Tokens, } -impl Expander { +impl Expander<'_> { /// Expand on a struct. fn expand_struct( &mut self, @@ -103,11 +101,11 @@ impl Expander { let mut meta_parse = Vec::new(); let mut meta_fields = Vec::new(); - let ty_attrs = self.cx.type_attrs(&input.attrs)?; + let ty_attrs = self.cx.type_attrs(&input.attrs); let mut skipped = 0; for (i, field) in named.named.iter().enumerate() { - let field_attrs = self.cx.field_attrs(&field.attrs)?; + let field_attrs = self.cx.field_attrs(&field.attrs); let ident = self.cx.field_ident(field)?; if field_attrs.id.is_some() { diff --git a/crates/rune-macros/src/spanned.rs b/crates/rune-macros/src/spanned.rs index 2fc51bf3a..e5cbfbb37 100644 --- a/crates/rune-macros/src/spanned.rs +++ b/crates/rune-macros/src/spanned.rs @@ -20,42 +20,26 @@ impl syn::parse::Parse for Derive { } impl Derive { - pub(super) fn expand(self, is_option_spanned: bool) -> Result> { - let cx = Context::new(); - let tokens = cx.tokens_with_module(None); + pub(super) fn expand(self, cx: &Context, is_option_spanned: bool) -> Result { + let attr = cx.type_attrs(&self.input.attrs); + let tokens = cx.tokens_with_module(attr.module.as_ref()); let mut expander = Expander { cx, tokens }; - if expander.cx.type_attrs(&self.input.attrs).is_err() { - return Err(expander.cx.errors.into_inner()); - } - let inner = match &self.input.data { - syn::Data::Struct(st) => { - let Ok(inner) = expander.expand_struct_fields( - &st.fields, - |member| quote!(&self.#member), - is_option_spanned, - ) else { - return Err(expander.cx.errors.into_inner()); - }; - - inner - } - syn::Data::Enum(enum_) => { - let Ok(inner) = expander.expand_enum(enum_, is_option_spanned) else { - return Err(expander.cx.errors.into_inner()); - }; - - inner - } + syn::Data::Struct(st) => expander.expand_struct_fields( + &st.fields, + |member| quote!(&self.#member), + is_option_spanned, + )?, + syn::Data::Enum(enum_) => expander.expand_enum(enum_, is_option_spanned)?, syn::Data::Union(un) => { expander.cx.error(syn::Error::new_spanned( un.union_token, "not supported on unions", )); - return Err(expander.cx.errors.into_inner()); + return Err(()); } }; @@ -114,12 +98,12 @@ impl Derive { } } -struct Expander { - cx: Context, +struct Expander<'cx> { + cx: &'cx Context, tokens: Tokens, } -impl Expander { +impl Expander<'_> { /// Expand on a struct. fn expand_enum( &mut self, @@ -213,7 +197,7 @@ impl Expander { let mut definite_span = false; for (index, field) in fields.iter().enumerate() { - let attr = self.cx.field_attrs(&field.attrs)?; + let attr = self.cx.field_attrs(&field.attrs); if attr.id.is_some() || attr.skip.is_some() { continue; diff --git a/crates/rune-macros/src/to_tokens.rs b/crates/rune-macros/src/to_tokens.rs index f3d276558..4b47a551a 100644 --- a/crates/rune-macros/src/to_tokens.rs +++ b/crates/rune-macros/src/to_tokens.rs @@ -18,8 +18,7 @@ impl syn::parse::Parse for Derive { } impl Derive { - pub(super) fn expand(self) -> Result> { - let cx = Context::new(); + pub(super) fn expand(self, cx: &Context) -> Result { let tokens = cx.tokens_with_module(None); let mut expander = Expander { cx, tokens }; @@ -43,23 +42,23 @@ impl Derive { } } - Err(expander.cx.errors.into_inner()) + Err(()) } } -struct Expander { - cx: Context, +struct Expander<'cx> { + cx: &'cx Context, tokens: Tokens, } -impl Expander { +impl Expander<'_> { /// Expand on a struct. fn expand_struct( &mut self, input: &syn::DeriveInput, st: &syn::DataStruct, ) -> Result { - let _ = self.cx.type_attrs(&input.attrs)?; + _ = self.cx.type_attrs(&input.attrs); self.expand_struct_fields(input, &st.fields) } @@ -69,7 +68,7 @@ impl Expander { input: &syn::DeriveInput, st: &syn::DataEnum, ) -> Result { - let _ = self.cx.type_attrs(&input.attrs)?; + _ = self.cx.type_attrs(&input.attrs); let mut impl_into_tokens = Vec::new(); @@ -163,7 +162,7 @@ impl Expander { for field in &named.named { let ident = self.cx.field_ident(field)?; - let attrs = self.cx.field_attrs(&field.attrs)?; + let attrs = self.cx.field_attrs(&field.attrs); if attrs.skip() { continue; @@ -208,7 +207,7 @@ impl Expander { for field in &named.named { let ident = self.cx.field_ident(field)?; - let attrs = self.cx.field_attrs(&field.attrs)?; + let attrs = self.cx.field_attrs(&field.attrs); idents.push(ident); if attrs.skip() { @@ -238,7 +237,7 @@ impl Expander { for (n, field) in named.unnamed.iter().enumerate() { let ident = syn::Ident::new(&format!("f{}", n), field.span()); - let attrs = self.cx.field_attrs(&field.attrs)?; + let attrs = self.cx.field_attrs(&field.attrs); idents.push(ident.clone()); diff --git a/crates/rune-macros/src/to_value.rs b/crates/rune-macros/src/to_value.rs index 0a25207c2..a010f8219 100644 --- a/crates/rune-macros/src/to_value.rs +++ b/crates/rune-macros/src/to_value.rs @@ -2,12 +2,12 @@ use crate::context::{Context, Tokens}; use proc_macro2::TokenStream; use quote::quote; -struct Expander { - cx: Context, +struct Expander<'cx> { + cx: &'cx Context, tokens: Tokens, } -impl Expander { +impl Expander<'_> { /// Expand on a struct. fn expand_struct( &mut self, @@ -66,7 +66,7 @@ impl Expander { } = &self.tokens; for (index, f) in unnamed.unnamed.iter().enumerate() { - let _ = self.cx.field_attrs(&f.attrs)?; + _ = self.cx.field_attrs(&f.attrs); let index = syn::Index::from(index); to_values.push(quote!(#vec::try_push(&mut tuple, #to_value::to_value(self.#index)?)?)); } @@ -97,7 +97,7 @@ impl Expander { for f in &named.named { let ident = self.cx.field_ident(f)?; - let _ = self.cx.field_attrs(&f.attrs)?; + _ = self.cx.field_attrs(&f.attrs); let name = &syn::LitStr::new(&ident.to_string(), ident.span()); @@ -114,19 +114,11 @@ impl Expander { } } -pub(super) fn expand(input: &syn::DeriveInput) -> Result> { - let cx = Context::new(); - - let Ok(attr) = cx.type_attrs(&input.attrs) else { - return Err(cx.errors.into_inner()); - }; - +pub(super) fn expand(cx: &Context, input: &syn::DeriveInput) -> Result { + let attr = cx.type_attrs(&input.attrs); let tokens = cx.tokens_with_module(attr.module.as_ref()); - let mut expander = Expander { - cx: Context::new(), - tokens, - }; + let mut expander = Expander { cx, tokens }; match &input.data { syn::Data::Struct(st) => { @@ -148,5 +140,5 @@ pub(super) fn expand(input: &syn::DeriveInput) -> Result