From f57dbf1bd0303cf03ebabe8ea104bdc41888cc57 Mon Sep 17 00:00:00 2001 From: Daiki Mizukami Date: Sun, 8 Sep 2024 08:57:35 +0900 Subject: [PATCH] derive: Refactor to use `syn::Error::to_compile_error` --- oauth1-request-derive/src/ctxt.rs | 35 ++++++++++++++++--------------- oauth1-request-derive/src/lib.rs | 17 +++++++++------ oauth1-request-derive/src/meta.rs | 4 ++-- oauth1-request-derive/src/util.rs | 8 +------ 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/oauth1-request-derive/src/ctxt.rs b/oauth1-request-derive/src/ctxt.rs index 20bc547..b164722 100644 --- a/oauth1-request-derive/src/ctxt.rs +++ b/oauth1-request-derive/src/ctxt.rs @@ -1,40 +1,41 @@ +use core::fmt::Display; use std::mem; -use proc_macro2::{Span, TokenStream}; -use quote::ToTokens; - -use crate::util::error; +use proc_macro2::Span; +use syn::Error; pub struct Ctxt { - errors: Option, + error: Option, } impl Ctxt { pub fn new() -> Self { - Self { - errors: Some(TokenStream::new()), + Self { error: None } + } + + pub fn add_error(&mut self, error: Error) { + if let Some(ref mut e) = self.error { + e.combine(error); + } else { + self.error = Some(error); } } - pub fn error(&mut self, msg: &str, span: Span) { - error(msg, span).to_tokens(self.errors.as_mut().unwrap()); + pub fn add_error_message(&mut self, span: Span, msg: T) { + self.add_error(Error::new(span, msg)); } - pub fn emit_errors(mut self) -> Option { - let errors = self.errors.take().unwrap(); + pub fn take_error(mut self) -> Option { + let error = self.error.take(); mem::forget(self); - if errors.is_empty() { - None - } else { - Some(errors) - } + error } } impl Drop for Ctxt { fn drop(&mut self) { if !std::thread::panicking() { - panic!("must call `Ctxt::emit_errors`"); + panic!("must call `Ctxt::take_error`"); } } } diff --git a/oauth1-request-derive/src/lib.rs b/oauth1-request-derive/src/lib.rs index 0aca96b..50e4d65 100644 --- a/oauth1-request-derive/src/lib.rs +++ b/oauth1-request-derive/src/lib.rs @@ -28,7 +28,6 @@ mod util; use proc_macro2::{Span, TokenStream}; use proc_macro_crate::FoundCrate; use quote::{quote, quote_spanned}; -use syn::spanned::Spanned; use syn::{ parse_macro_input, parse_quote, Data, DataStruct, DeriveInput, Fields, GenericParam, Generics, Ident, @@ -38,7 +37,6 @@ use self::container::ContainerMeta; use self::ctxt::Ctxt; use self::field::Field; use self::method_body::MethodBody; -use self::util::error; /// A derive macro for [`oauth1_request::Request`][Request] trait. /// @@ -59,7 +57,10 @@ fn expand_derive_oauth1_authorize(input: DeriveInput) -> TokenStream { fields: Fields::Named(fields), .. }) => fields, - _ => return error("expected a struct with named fields", input.span()), + _ => { + return syn::Error::new_spanned(input, "expected a struct with named fields") + .into_compile_error() + } }; let mut cx = Ctxt::new(); @@ -81,7 +82,7 @@ fn expand_derive_oauth1_authorize(input: DeriveInput) -> TokenStream { let name = f.name(); let (name, span) = (name.string_value(), name.span()); if name == prev_name { - cx.error(&format!("duplicate parameter \"{}\"", name), span); + cx.add_error_message(span, format!("duplicate parameter \"{}\"", name)); } name }); @@ -105,7 +106,10 @@ fn expand_derive_oauth1_authorize(input: DeriveInput) -> TokenStream { &*krate } Err(proc_macro_crate::Error::CargoManifestDirNotSet) => "oauth1_request", - Err(e) => panic!("{:?}", e), + Err(e) => { + cx.add_error_message(Span::call_site(), e); + "oauth1_request" + } }; let krate = Ident::new(krate, Span::call_site()); quote! { @@ -116,7 +120,8 @@ fn expand_derive_oauth1_authorize(input: DeriveInput) -> TokenStream { add_trait_bounds(&mut generics); let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); - if let Some(mut tokens) = cx.emit_errors() { + if let Some(e) = cx.take_error() { + let mut tokens = e.into_compile_error(); tokens.extend(quote! { const _: () = { #use_oauth1_request diff --git a/oauth1-request-derive/src/meta.rs b/oauth1-request-derive/src/meta.rs index 53d5460..6bb3fb6 100644 --- a/oauth1-request-derive/src/meta.rs +++ b/oauth1-request-derive/src/meta.rs @@ -31,14 +31,14 @@ macro_rules! def_meta { let meta_list = match attr.parse_args_with(parser) { Ok(list) => list, Err(e) => { - cx.error(&e.to_string(), e.span()); + cx.add_error(e); continue; } }; for meta in meta_list { if let Err(e) = ret.add_meta(meta) { - cx.error(&e.to_string(), e.span()); + cx.add_error(e); } } } diff --git a/oauth1-request-derive/src/util.rs b/oauth1-request-derive/src/util.rs index 7da771d..d46b4c2 100644 --- a/oauth1-request-derive/src/util.rs +++ b/oauth1-request-derive/src/util.rs @@ -3,7 +3,7 @@ mod oauth_parameter; pub use oauth_parameter::OAuthParameter; use proc_macro2::{Ident, Span, TokenStream, TokenTree}; -use quote::{quote_spanned, ToTokens}; +use quote::ToTokens; impl OAuthParameter { fn serialize_method_name(self) -> Option<&'static str> { @@ -30,9 +30,3 @@ impl ToTokens for OAuthParameter { tokens.extend(::core::iter::once(TokenTree::Ident(ident))); } } - -pub fn error(msg: &str, span: Span) -> TokenStream { - quote_spanned!(span=> - compile_error!(#msg); - ) -}