Skip to content

Commit f47735c

Browse files
committed
Ensure that users cannot use generated arguments.
This commit gensyms the generated ident for replacement arguments so that users cannot refer to them. It also ensures that levenshtein distance suggestions do not suggest gensymed identifiers.
1 parent b05d5db commit f47735c

File tree

5 files changed

+104
-11
lines changed

5 files changed

+104
-11
lines changed

src/librustc_resolve/lib.rs

+13-10
Original file line numberDiff line numberDiff line change
@@ -4183,7 +4183,7 @@ impl<'a> Resolver<'a> {
41834183
let add_module_candidates = |module: Module<'_>, names: &mut Vec<TypoSuggestion>| {
41844184
for (&(ident, _), resolution) in module.resolutions.borrow().iter() {
41854185
if let Some(binding) = resolution.borrow().binding {
4186-
if filter_fn(binding.def()) {
4186+
if !ident.name.is_gensymed() && filter_fn(binding.def()) {
41874187
names.push(TypoSuggestion {
41884188
candidate: ident.name,
41894189
article: binding.def().article(),
@@ -4201,7 +4201,7 @@ impl<'a> Resolver<'a> {
42014201
for rib in self.ribs[ns].iter().rev() {
42024202
// Locals and type parameters
42034203
for (ident, def) in &rib.bindings {
4204-
if filter_fn(*def) {
4204+
if !ident.name.is_gensymed() && filter_fn(*def) {
42054205
names.push(TypoSuggestion {
42064206
candidate: ident.name,
42074207
article: def.article(),
@@ -4228,7 +4228,7 @@ impl<'a> Resolver<'a> {
42284228
index: CRATE_DEF_INDEX,
42294229
});
42304230

4231-
if filter_fn(crate_mod) {
4231+
if !ident.name.is_gensymed() && filter_fn(crate_mod) {
42324232
Some(TypoSuggestion {
42334233
candidate: ident.name,
42344234
article: "a",
@@ -4251,13 +4251,16 @@ impl<'a> Resolver<'a> {
42514251
// Add primitive types to the mix
42524252
if filter_fn(Def::PrimTy(Bool)) {
42534253
names.extend(
4254-
self.primitive_type_table.primitive_types.iter().map(|(name, _)| {
4255-
TypoSuggestion {
4256-
candidate: *name,
4257-
article: "a",
4258-
kind: "primitive type",
4259-
}
4260-
})
4254+
self.primitive_type_table.primitive_types
4255+
.iter()
4256+
.filter(|(name, _)| !name.is_gensymed())
4257+
.map(|(name, _)| {
4258+
TypoSuggestion {
4259+
candidate: *name,
4260+
article: "a",
4261+
kind: "primitive type",
4262+
}
4263+
})
42614264
)
42624265
}
42634266
} else {

src/libsyntax/parse/parser.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8878,7 +8878,7 @@ impl<'a> Parser<'a> {
88788878

88798879
// Construct a name for our temporary argument.
88808880
let name = format!("__arg{}", index);
8881-
let ident = Ident::from_str(&name);
8881+
let ident = Ident::from_str(&name).gensym();
88828882

88838883
// Check if this is a ident pattern, if so, we can optimize and avoid adding a
88848884
// `let <pat> = __argN;` statement, instead just adding a `let <pat> = <pat>;`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// edition:2018
2+
3+
#![allow(unused_variables)]
4+
#![feature(async_await)]
5+
6+
async fn foobar_async(x: u32, (a, _, _c): (u32, u32, u32), _: u32, _y: u32) {
7+
assert_eq!(__arg1, (1, 2, 3)); //~ ERROR cannot find value `__arg1` in this scope [E0425]
8+
assert_eq!(__arg2, 4); //~ ERROR cannot find value `__arg2` in this scope [E0425]
9+
}
10+
11+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0425]: cannot find value `__arg1` in this scope
2+
--> $DIR/async-await-drop-order-locals-are-hidden.rs:7:16
3+
|
4+
LL | assert_eq!(__arg1, (1, 2, 3));
5+
| ^^^^^^ not found in this scope
6+
7+
error[E0425]: cannot find value `__arg2` in this scope
8+
--> $DIR/async-await-drop-order-locals-are-hidden.rs:8:16
9+
|
10+
LL | assert_eq!(__arg2, 4);
11+
| ^^^^^^ not found in this scope
12+
13+
error: aborting due to 2 previous errors
14+
15+
For more information about this error, try `rustc --explain E0425`.

src/test/ui/auxiliary/arc_wake.rs

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// edition:2018
2+
3+
use std::sync::Arc;
4+
use std::task::{
5+
Waker, RawWaker, RawWakerVTable,
6+
};
7+
8+
macro_rules! waker_vtable {
9+
($ty:ident) => {
10+
&RawWakerVTable::new(
11+
clone_arc_raw::<$ty>,
12+
wake_arc_raw::<$ty>,
13+
wake_by_ref_arc_raw::<$ty>,
14+
drop_arc_raw::<$ty>,
15+
)
16+
};
17+
}
18+
19+
pub trait ArcWake {
20+
fn wake(self: Arc<Self>);
21+
22+
fn wake_by_ref(arc_self: &Arc<Self>) {
23+
arc_self.clone().wake()
24+
}
25+
26+
fn into_waker(wake: Arc<Self>) -> Waker where Self: Sized
27+
{
28+
let ptr = Arc::into_raw(wake) as *const ();
29+
30+
unsafe {
31+
Waker::from_raw(RawWaker::new(ptr, waker_vtable!(Self)))
32+
}
33+
}
34+
}
35+
36+
unsafe fn increase_refcount<T: ArcWake>(data: *const ()) {
37+
// Retain Arc by creating a copy
38+
let arc: Arc<T> = Arc::from_raw(data as *const T);
39+
let arc_clone = arc.clone();
40+
// Forget the Arcs again, so that the refcount isn't decrased
41+
let _ = Arc::into_raw(arc);
42+
let _ = Arc::into_raw(arc_clone);
43+
}
44+
45+
unsafe fn clone_arc_raw<T: ArcWake>(data: *const ()) -> RawWaker {
46+
increase_refcount::<T>(data);
47+
RawWaker::new(data, waker_vtable!(T))
48+
}
49+
50+
unsafe fn drop_arc_raw<T: ArcWake>(data: *const ()) {
51+
// Drop Arc
52+
let _: Arc<T> = Arc::from_raw(data as *const T);
53+
}
54+
55+
unsafe fn wake_arc_raw<T: ArcWake>(data: *const ()) {
56+
let arc: Arc<T> = Arc::from_raw(data as *const T);
57+
ArcWake::wake(arc);
58+
}
59+
60+
unsafe fn wake_by_ref_arc_raw<T: ArcWake>(data: *const ()) {
61+
let arc: Arc<T> = Arc::from_raw(data as *const T);
62+
ArcWake::wake_by_ref(&arc);
63+
let _ = Arc::into_raw(arc);
64+
}

0 commit comments

Comments
 (0)