]> git.proxmox.com Git - proxmox.git/commitdiff
macro: errors shouldn't discard the code
authorWolfgang Bumiller <w.bumiller@proxmox.com>
Thu, 8 Aug 2019 12:04:27 +0000 (14:04 +0200)
committerWolfgang Bumiller <w.bumiller@proxmox.com>
Thu, 8 Aug 2019 12:04:28 +0000 (14:04 +0200)
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 <w.bumiller@proxmox.com>
proxmox-api-macro/src/lib.rs

index 88f97239eac6edb50f3a82285efcb7d37304a9e7..679827c5d537e5b235ed7add607e0f16281f8834 100644 (file)
@@ -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::<syn::Error>() {
-        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),
     }
 }