Skip to content

Commit

Permalink
Ensure that users cannot use generated arguments.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
davidtwco committed May 1, 2019
1 parent b05d5db commit f47735c
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 11 deletions.
23 changes: 13 additions & 10 deletions src/librustc_resolve/lib.rs
Expand Up @@ -4183,7 +4183,7 @@ impl<'a> Resolver<'a> {
let add_module_candidates = |module: Module<'_>, names: &mut Vec<TypoSuggestion>| {
for (&(ident, _), resolution) in module.resolutions.borrow().iter() {
if let Some(binding) = resolution.borrow().binding {
if filter_fn(binding.def()) {
if !ident.name.is_gensymed() && filter_fn(binding.def()) {
names.push(TypoSuggestion {
candidate: ident.name,
article: binding.def().article(),
Expand All @@ -4201,7 +4201,7 @@ impl<'a> Resolver<'a> {
for rib in self.ribs[ns].iter().rev() {
// Locals and type parameters
for (ident, def) in &rib.bindings {
if filter_fn(*def) {
if !ident.name.is_gensymed() && filter_fn(*def) {
names.push(TypoSuggestion {
candidate: ident.name,
article: def.article(),
Expand All @@ -4228,7 +4228,7 @@ impl<'a> Resolver<'a> {
index: CRATE_DEF_INDEX,
});

if filter_fn(crate_mod) {
if !ident.name.is_gensymed() && filter_fn(crate_mod) {
Some(TypoSuggestion {
candidate: ident.name,
article: "a",
Expand All @@ -4251,13 +4251,16 @@ impl<'a> Resolver<'a> {
// Add primitive types to the mix
if filter_fn(Def::PrimTy(Bool)) {
names.extend(
self.primitive_type_table.primitive_types.iter().map(|(name, _)| {
TypoSuggestion {
candidate: *name,
article: "a",
kind: "primitive type",
}
})
self.primitive_type_table.primitive_types
.iter()
.filter(|(name, _)| !name.is_gensymed())
.map(|(name, _)| {
TypoSuggestion {
candidate: *name,
article: "a",
kind: "primitive type",
}
})
)
}
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/parse/parser.rs
Expand Up @@ -8878,7 +8878,7 @@ impl<'a> Parser<'a> {

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

// Check if this is a ident pattern, if so, we can optimize and avoid adding a
// `let <pat> = __argN;` statement, instead just adding a `let <pat> = <pat>;`
Expand Down
11 changes: 11 additions & 0 deletions src/test/ui/async-await-drop-order-locals-are-hidden.rs
@@ -0,0 +1,11 @@
// edition:2018

#![allow(unused_variables)]
#![feature(async_await)]

async fn foobar_async(x: u32, (a, _, _c): (u32, u32, u32), _: u32, _y: u32) {
assert_eq!(__arg1, (1, 2, 3)); //~ ERROR cannot find value `__arg1` in this scope [E0425]
assert_eq!(__arg2, 4); //~ ERROR cannot find value `__arg2` in this scope [E0425]
}

fn main() {}
15 changes: 15 additions & 0 deletions src/test/ui/async-await-drop-order-locals-are-hidden.stderr
@@ -0,0 +1,15 @@
error[E0425]: cannot find value `__arg1` in this scope
--> $DIR/async-await-drop-order-locals-are-hidden.rs:7:16
|
LL | assert_eq!(__arg1, (1, 2, 3));
| ^^^^^^ not found in this scope

error[E0425]: cannot find value `__arg2` in this scope
--> $DIR/async-await-drop-order-locals-are-hidden.rs:8:16
|
LL | assert_eq!(__arg2, 4);
| ^^^^^^ not found in this scope

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0425`.
64 changes: 64 additions & 0 deletions src/test/ui/auxiliary/arc_wake.rs
@@ -0,0 +1,64 @@
// edition:2018

use std::sync::Arc;
use std::task::{
Waker, RawWaker, RawWakerVTable,
};

macro_rules! waker_vtable {
($ty:ident) => {
&RawWakerVTable::new(
clone_arc_raw::<$ty>,
wake_arc_raw::<$ty>,
wake_by_ref_arc_raw::<$ty>,
drop_arc_raw::<$ty>,
)
};
}

pub trait ArcWake {
fn wake(self: Arc<Self>);

fn wake_by_ref(arc_self: &Arc<Self>) {
arc_self.clone().wake()
}

fn into_waker(wake: Arc<Self>) -> Waker where Self: Sized
{
let ptr = Arc::into_raw(wake) as *const ();

unsafe {
Waker::from_raw(RawWaker::new(ptr, waker_vtable!(Self)))
}
}
}

unsafe fn increase_refcount<T: ArcWake>(data: *const ()) {
// Retain Arc by creating a copy
let arc: Arc<T> = Arc::from_raw(data as *const T);
let arc_clone = arc.clone();
// Forget the Arcs again, so that the refcount isn't decrased
let _ = Arc::into_raw(arc);
let _ = Arc::into_raw(arc_clone);
}

unsafe fn clone_arc_raw<T: ArcWake>(data: *const ()) -> RawWaker {
increase_refcount::<T>(data);
RawWaker::new(data, waker_vtable!(T))
}

unsafe fn drop_arc_raw<T: ArcWake>(data: *const ()) {
// Drop Arc
let _: Arc<T> = Arc::from_raw(data as *const T);
}

unsafe fn wake_arc_raw<T: ArcWake>(data: *const ()) {
let arc: Arc<T> = Arc::from_raw(data as *const T);
ArcWake::wake(arc);
}

unsafe fn wake_by_ref_arc_raw<T: ArcWake>(data: *const ()) {
let arc: Arc<T> = Arc::from_raw(data as *const T);
ArcWake::wake_by_ref(&arc);
let _ = Arc::into_raw(arc);
}

0 comments on commit f47735c

Please sign in to comment.