Skip to content

Commit

Permalink
Simplify proc-macro
Browse files Browse the repository at this point in the history
There's no need to inspect the test case so deeply; all this macro wants
to do is insert a prelude - so do that and expand the rest as-is.

This removes the inner function `test_impl`, which is the suspected
cause of d-e-s-o#28.

Closes d-e-s-o#28.
  • Loading branch information
tamird committed Oct 5, 2023
1 parent f79755c commit ce87de0
Showing 1 changed file with 9 additions and 45 deletions.
54 changes: 9 additions & 45 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,10 @@ use quote::quote;

use syn::parse_macro_input;
use syn::parse_quote;
use syn::punctuated::Punctuated;
use syn::AttributeArgs;
use syn::FnArg;
use syn::ItemFn;
use syn::Meta;
use syn::NestedMeta;
use syn::ReturnType;
use syn::Token;

/// A procedural macro for the `test` attribute.
///
Expand Down Expand Up @@ -149,55 +145,22 @@ fn expand_tracing_init() -> Tokens {
quote! {}
}

/// Extract the argument names from the inputs of a function signature.
fn extract_args(inputs: &Punctuated<FnArg, Token![,]>) -> Punctuated<Tokens, Token![,]> {
inputs
.iter()
.map(|arg| match arg {
FnArg::Receiver(receiver) => {
let slf = receiver.self_token;
quote! { #slf }
}
FnArg::Typed(typed) => {
let pat = &typed.pat;
quote! { #pat }
}
})
.collect()
}

/// Emit code for a wrapper function around a test function.
fn expand_wrapper(inner_test: &Tokens, wrappee: &ItemFn) -> TokenStream {
let attrs = &wrappee.attrs;
let async_ = &wrappee.sig.asyncness;
let await_ = if async_.is_some() {
quote! {.await}
} else {
quote! {}
};
let body = &wrappee.block;
let test_name = &wrappee.sig.ident;
let inputs = &wrappee.sig.inputs;
let args = extract_args(inputs);

// Note that Rust does not allow us to have a test function with
// #[should_panic] that has a non-unit return value.
let ret = match &wrappee.sig.output {
ReturnType::Default => quote! {},
ReturnType::Type(_, type_) => quote! {-> #type_},
};
let ItemFn {
attrs,
vis,
sig,
block,
} = wrappee;

let logging_init = expand_logging_init();
let tracing_init = expand_tracing_init();

let result = quote! {
#[#inner_test]
#(#attrs)*
#async_ fn #test_name(#inputs) #ret {
#async_ fn test_impl(#inputs) #ret {
#body
}

#vis #sig {
// We put all initialization code into a separate module here in
// order to prevent potential ambiguities that could result in
// compilation errors. E.g., client code could use traits that
Expand All @@ -216,7 +179,8 @@ fn expand_wrapper(inner_test: &Tokens, wrappee: &ItemFn) -> TokenStream {
}

init::init();
test_impl(#args)#await_

#block
}
};
result.into()
Expand Down

0 comments on commit ce87de0

Please sign in to comment.