diff --git a/build.rs b/build.rs index a2b0833..fa2fe1c 100644 --- a/build.rs +++ b/build.rs @@ -8,6 +8,10 @@ fn main() { None => return, }; + if compiler < 45 { + println!("cargo:rustc-cfg=no_span_mixed_site"); + } + if compiler < 47 { println!("cargo:rustc-cfg=self_span_hack"); } diff --git a/src/expand.rs b/src/expand.rs index fbbac5d..e190831 100644 --- a/src/expand.rs +++ b/src/expand.rs @@ -1,7 +1,7 @@ use crate::lifetime::{AddLifetimeToImplTrait, CollectLifetimes}; use crate::parse::Item; use crate::receiver::{has_self_in_block, has_self_in_sig, mut_pat, ReplaceSelf}; -use proc_macro2::TokenStream; +use proc_macro2::{Span, TokenStream}; use quote::{format_ident, quote, quote_spanned, ToTokens}; use std::collections::BTreeSet as Set; use std::mem; @@ -399,8 +399,10 @@ fn transform_block(context: Context, sig: &mut Signature, block: &mut Block) { } fn positional_arg(i: usize, pat: &Pat) -> Ident { - use syn::spanned::Spanned; - format_ident!("__arg{}", i, span = pat.span()) + let span: Span = syn::spanned::Spanned::span(pat); + #[cfg(not(no_span_mixed_site))] + let span = span.resolved_at(Span::mixed_site()); + format_ident!("__arg{}", i, span = span) } fn has_bound(supertraits: &Supertraits, marker: &Ident) -> bool { diff --git a/tests/ui/arg-implementation-detail.rs b/tests/ui/arg-implementation-detail.rs new file mode 100644 index 0000000..b83aa72 --- /dev/null +++ b/tests/ui/arg-implementation-detail.rs @@ -0,0 +1,22 @@ +use async_trait::async_trait; + +pub struct Struct; + +#[async_trait] +pub trait Trait { + async fn f((_a, _b): (Struct, Struct)) { + // Expands to something like: + // + // fn f(__arg0: (Struct, Struct)) -> … { + // Box::pin(async move { + // let (_a, _b) = __arg0; + // … + // }) + // } + // + // but user's code must not be allowed to name that temporary argument: + let _ = __arg0; + } +} + +fn main() {} diff --git a/tests/ui/arg-implementation-detail.stderr b/tests/ui/arg-implementation-detail.stderr new file mode 100644 index 0000000..e742688 --- /dev/null +++ b/tests/ui/arg-implementation-detail.stderr @@ -0,0 +1,5 @@ +error[E0425]: cannot find value `__arg0` in this scope + --> tests/ui/arg-implementation-detail.rs:18:17 + | +18 | let _ = __arg0; + | ^^^^^^ not found in this scope