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 <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2019-08-08 14:04:27 +02:00
parent cad8f2f1c3
commit 080f62916e

View 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),
}
}