macros: improve diagnostics on type mismatch (#3766)

This commit is contained in:
Taiki Endo
2021-05-09 18:58:05 +09:00
committed by GitHub
parent 05c3cf3a0a
commit f9ce18a524
8 changed files with 149 additions and 7 deletions
+26 -5
View File
@@ -1,6 +1,6 @@
use proc_macro::TokenStream;
use proc_macro2::Span;
use quote::quote;
use quote::{quote, quote_spanned, ToTokens};
#[derive(Clone, Copy, PartialEq)]
enum RuntimeFlavor {
@@ -278,11 +278,29 @@ fn parse_knobs(
let config = config.build()?;
// If type mismatch occurs, the current rustc points to the last statement.
let (last_stmt_start_span, last_stmt_end_span) = {
let mut last_stmt = input
.block
.stmts
.last()
.map(ToTokens::into_token_stream)
.unwrap_or_default()
.into_iter();
// `Span` on stable Rust has a limitation that only points to the first
// token, not the whole tokens. We can work around this limitation by
// using the first/last span of the tokens like
// `syn::Error::new_spanned` does.
let start = last_stmt.next().map_or_else(Span::call_site, |t| t.span());
let end = last_stmt.last().map_or(start, |t| t.span());
(start, end)
};
let mut rt = match config.flavor {
RuntimeFlavor::CurrentThread => quote! {
RuntimeFlavor::CurrentThread => quote_spanned! {last_stmt_start_span=>
tokio::runtime::Builder::new_current_thread()
},
RuntimeFlavor::Threaded => quote! {
RuntimeFlavor::Threaded => quote_spanned! {last_stmt_start_span=>
tokio::runtime::Builder::new_multi_thread()
},
};
@@ -302,7 +320,8 @@ fn parse_knobs(
};
let body = &input.block;
input.block = syn::parse_quote! {
let brace_token = input.block.brace_token;
input.block = syn::parse2(quote_spanned! {last_stmt_end_span=>
{
#rt
.enable_all()
@@ -310,7 +329,9 @@ fn parse_knobs(
.unwrap()
.block_on(async #body)
}
};
})
.unwrap();
input.block.brace_token = brace_token;
let result = quote! {
#header