Skip to content

Commit f7b7fef

Browse files
authored
Merge pull request #202 from dtolnay/positionalarg
Prevent positional args from being named inside function body
2 parents e378bac + 44bf865 commit f7b7fef

File tree

4 files changed

+36
-3
lines changed

4 files changed

+36
-3
lines changed

build.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ fn main() {
88
None => return,
99
};
1010

11+
if compiler < 45 {
12+
println!("cargo:rustc-cfg=no_span_mixed_site");
13+
}
14+
1115
if compiler < 47 {
1216
println!("cargo:rustc-cfg=self_span_hack");
1317
}

src/expand.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::lifetime::{AddLifetimeToImplTrait, CollectLifetimes};
22
use crate::parse::Item;
33
use crate::receiver::{has_self_in_block, has_self_in_sig, mut_pat, ReplaceSelf};
4-
use proc_macro2::TokenStream;
4+
use proc_macro2::{Span, TokenStream};
55
use quote::{format_ident, quote, quote_spanned, ToTokens};
66
use std::collections::BTreeSet as Set;
77
use std::mem;
@@ -399,8 +399,10 @@ fn transform_block(context: Context, sig: &mut Signature, block: &mut Block) {
399399
}
400400

401401
fn positional_arg(i: usize, pat: &Pat) -> Ident {
402-
use syn::spanned::Spanned;
403-
format_ident!("__arg{}", i, span = pat.span())
402+
let span: Span = syn::spanned::Spanned::span(pat);
403+
#[cfg(not(no_span_mixed_site))]
404+
let span = span.resolved_at(Span::mixed_site());
405+
format_ident!("__arg{}", i, span = span)
404406
}
405407

406408
fn has_bound(supertraits: &Supertraits, marker: &Ident) -> bool {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use async_trait::async_trait;
2+
3+
pub struct Struct;
4+
5+
#[async_trait]
6+
pub trait Trait {
7+
async fn f((_a, _b): (Struct, Struct)) {
8+
// Expands to something like:
9+
//
10+
// fn f(__arg0: (Struct, Struct)) -> … {
11+
// Box::pin(async move {
12+
// let (_a, _b) = __arg0;
13+
// …
14+
// })
15+
// }
16+
//
17+
// but user's code must not be allowed to name that temporary argument:
18+
let _ = __arg0;
19+
}
20+
}
21+
22+
fn main() {}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
error[E0425]: cannot find value `__arg0` in this scope
2+
--> tests/ui/arg-implementation-detail.rs:18:17
3+
|
4+
18 | let _ = __arg0;
5+
| ^^^^^^ not found in this scope

0 commit comments

Comments
 (0)