syntax: unbox closures used in function arguments

This commit is contained in:
Jorge Aparicio 2014-12-30 18:39:20 -05:00
parent 371f04d433
commit 70ce68eed4
4 changed files with 36 additions and 32 deletions

View file

@ -618,34 +618,38 @@ pub fn compute_id_range_for_fn_body(fk: visit::FnKind,
id_visitor.operation.result
}
// FIXME(#19596) unbox `it`
pub fn walk_pat(pat: &Pat, it: |&Pat| -> bool) -> bool {
if !it(pat) {
return false;
pub fn walk_pat<F>(pat: &Pat, mut it: F) -> bool where F: FnMut(&Pat) -> bool {
// FIXME(#19596) this is a workaround, but there should be a better way
fn walk_pat_<G>(pat: &Pat, it: &mut G) -> bool where G: FnMut(&Pat) -> bool {
if !(*it)(pat) {
return false;
}
match pat.node {
PatIdent(_, _, Some(ref p)) => walk_pat_(&**p, it),
PatStruct(_, ref fields, _) => {
fields.iter().all(|field| walk_pat_(&*field.node.pat, it))
}
PatEnum(_, Some(ref s)) | PatTup(ref s) => {
s.iter().all(|p| walk_pat_(&**p, it))
}
PatBox(ref s) | PatRegion(ref s) => {
walk_pat_(&**s, it)
}
PatVec(ref before, ref slice, ref after) => {
before.iter().all(|p| walk_pat_(&**p, it)) &&
slice.iter().all(|p| walk_pat_(&**p, it)) &&
after.iter().all(|p| walk_pat_(&**p, it))
}
PatMac(_) => panic!("attempted to analyze unexpanded pattern"),
PatWild(_) | PatLit(_) | PatRange(_, _) | PatIdent(_, _, _) |
PatEnum(_, _) => {
true
}
}
}
match pat.node {
PatIdent(_, _, Some(ref p)) => walk_pat(&**p, it),
PatStruct(_, ref fields, _) => {
fields.iter().all(|field| walk_pat(&*field.node.pat, |p| it(p)))
}
PatEnum(_, Some(ref s)) | PatTup(ref s) => {
s.iter().all(|p| walk_pat(&**p, |p| it(p)))
}
PatBox(ref s) | PatRegion(ref s) => {
walk_pat(&**s, it)
}
PatVec(ref before, ref slice, ref after) => {
before.iter().all(|p| walk_pat(&**p, |p| it(p))) &&
slice.iter().all(|p| walk_pat(&**p, |p| it(p))) &&
after.iter().all(|p| walk_pat(&**p, |p| it(p)))
}
PatMac(_) => panic!("attempted to analyze unexpanded pattern"),
PatWild(_) | PatLit(_) | PatRange(_, _) | PatIdent(_, _, _) |
PatEnum(_, _) => {
true
}
}
walk_pat_(pat, &mut it)
}
pub trait EachViewItem {

View file

@ -47,18 +47,18 @@ pub trait ItemDecorator {
sp: Span,
meta_item: &ast::MetaItem,
item: &ast::Item,
push: |P<ast::Item>|);
push: Box<FnMut(P<ast::Item>)>);
}
impl<F> ItemDecorator for F
where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &ast::Item, |P<ast::Item>|)
where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &ast::Item, Box<FnMut(P<ast::Item>)>)
{
fn expand(&self,
ecx: &mut ExtCtxt,
sp: Span,
meta_item: &ast::MetaItem,
item: &ast::Item,
push: |P<ast::Item>|) {
push: Box<FnMut(P<ast::Item>)>) {
(*self)(ecx, sp, meta_item, item, push)
}
}

View file

@ -45,7 +45,7 @@ pub fn expand_meta_deriving(cx: &mut ExtCtxt,
_span: Span,
mitem: &MetaItem,
item: &Item,
push: |P<Item>|) {
mut push: Box<FnMut(P<Item>)>) {
match mitem.node {
MetaNameValue(_, ref l) => {
cx.span_err(l.span, "unexpected value in `deriving`");
@ -64,7 +64,7 @@ pub fn expand_meta_deriving(cx: &mut ExtCtxt,
MetaWord(ref tname) => {
macro_rules! expand(($func:path) => ($func(cx, titem.span,
&**titem, item,
|i| push(i))));
|i| push.call_mut((i,)))));
match tname.get() {
"Clone" => expand!(clone::expand_deriving_clone),

View file

@ -424,7 +424,7 @@ pub fn expand_item(it: P<ast::Item>, fld: &mut MacroExpander)
// but that double-mut-borrows fld
let mut items: SmallVector<P<ast::Item>> = SmallVector::zero();
dec.expand(fld.cx, attr.span, &*attr.node.value, &*it,
|item| items.push(item));
box |&mut : item| items.push(item));
decorator_items.extend(items.into_iter()
.flat_map(|item| expand_item(item, fld).into_iter()));