From 080f62916e7ea015f6e4d6c6cede3345b0c1eead Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Thu, 8 Aug 2019 14:04:27 +0200 Subject: [PATCH] macro: errors shouldn't discard the code Otherwise we'll get even more errors. Consider this example: #[api(...)] struct Foo { ... } impl MyTrait for Foo { ... } If the #[api] macro fails and does not at least produce the `struct Foo{}` along with its `compile_error!()` output, then in addition to our macro errors, we'll see errors about trying to implement `MyTrait` for an unknown thing called `Foo`. Signed-off-by: Wolfgang Bumiller --- proxmox-api-macro/src/lib.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/proxmox-api-macro/src/lib.rs b/proxmox-api-macro/src/lib.rs index 88f97239..679827c5 100644 --- a/proxmox-api-macro/src/lib.rs +++ b/proxmox-api-macro/src/lib.rs @@ -15,9 +15,13 @@ mod types; mod api_macro; mod router_macro; -fn handle_error(kind: &'static str, err: failure::Error) -> TokenStream { +fn handle_error(mut item: proc_macro2::TokenStream, kind: &'static str, err: failure::Error) -> TokenStream { match err.downcast::() { - Ok(err) => err.to_compile_error().into(), + Ok(err) => { + let err: proc_macro2::TokenStream = err.to_compile_error().into(); + item.extend(err); + item.into() + } Err(err) => panic!("error in {}: {}", kind, err), } } @@ -52,9 +56,10 @@ fn handle_error(kind: &'static str, err: failure::Error) -> TokenStream { /// ``` #[proc_macro_attribute] pub fn api(attr: TokenStream, item: TokenStream) -> TokenStream { - match api_macro::api_macro(attr.into(), item.into()) { + let item: proc_macro2::TokenStream = item.into(); + match api_macro::api_macro(attr.into(), item.clone()) { Ok(output) => output.into(), - Err(err) => handle_error("api definition", err), + Err(err) => handle_error(item, "api definition", err), } } @@ -143,8 +148,9 @@ pub fn api(attr: TokenStream, item: TokenStream) -> TokenStream { #[proc_macro] pub fn router(input: TokenStream) -> TokenStream { // TODO... - match router_macro::router_macro(input.into()) { + let input: proc_macro2::TokenStream = input.into(); + match router_macro::router_macro(input.clone()) { Ok(output) => output.into(), - Err(err) => handle_error("router", err), + Err(err) => handle_error(input, "router", err), } }