diff options
| author | bors <bors@rust-lang.org> | 2014-12-13 22:57:21 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-12-13 22:57:21 +0000 |
| commit | 444fa1b7cffcd99ca5b8abb51acf979f06a25899 (patch) | |
| tree | 51a8beea4fd983ce8cb46879a2fdbaf72916c13e /src/libsyntax/ext | |
| parent | 567b90ff095076054c98fa2f08d6c552ae60968d (diff) | |
| parent | b8e0b81dd57621af28d7b2b5551a3217f7bd4cec (diff) | |
| download | rust-444fa1b7cffcd99ca5b8abb51acf979f06a25899.tar.gz rust-444fa1b7cffcd99ca5b8abb51acf979f06a25899.zip | |
auto merge of #19467 : japaric/rust/uc, r=alexcrichton
This PR moves almost all our current uses of closures, both in public API and internal uses, to the new "unboxed" closures system.
In most cases, downstream code that *only uses* closures will continue to work as it is. The reason is that the `|| {}` syntax can be inferred either as a boxed or an "unboxed" closure according to the context. For example the following code will continue to work:
``` rust
some_option.map(|x| x.transform_with(upvar))
```
And will get silently upgraded to an "unboxed" closure.
In some other cases, it may be necessary to "annotate" which `Fn*` trait the closure implements:
```
// Change this
|x| { /* body */}
// to either of these
|: x| { /* body */} // closure implements the FnOnce trait
|&mut : x| { /* body */} // FnMut
|&: x| { /* body */} // Fn
```
This mainly occurs when the closure is assigned to a variable first, and then passed to a function/method.
``` rust
let closure = |: x| x.transform_with(upvar);
some.option.map(closure)
```
(It's very likely that in the future, an improved inference engine will make this annotation unnecessary)
Other cases that require annotation are closures that implement some trait via a blanket `impl`, for example:
- `std::finally::Finally`
- `regex::Replacer`
- `std::str::CharEq`
``` rust
string.trim_left_chars(|c: char| c.is_whitespace())
//~^ ERROR: the trait `Fn<(char,), bool>` is not implemented for the type `|char| -> bool`
string.trim_left_chars(|&: c: char| c.is_whitespace()) // OK
```
Finally, all implementations of traits that contain boxed closures in the arguments of their methods are now broken. And will need to be updated to use unboxed closures. These are the main affected traits:
- `serialize::Decoder`
- `serialize::DecoderHelpers`
- `serialize::Encoder`
- `serialize::EncoderHelpers`
- `rustrt::ToCStr`
For example, change this:
``` rust
// libserialize/json.rs
impl<'a> Encoder<io::IoError> for Encoder<'a> {
fn emit_enum(&mut self,
_name: &str,
f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
f(self)
}
}
```
to:
``` rust
// libserialize/json.rs
impl<'a> Encoder<io::IoError> for Encoder<'a> {
fn emit_enum<F>(&mut self, _name: &str, f: F) -> EncodeResult where
F: FnOnce(&mut Encoder<'a>) -> EncodeResult
{
f(self)
}
}
```
[breaking-change]
---
### How the `Fn*` bound has been selected
I've chosen the bounds to make the functions/structs as "generic as possible", i.e. to let them allow the maximum amount of input.
- An `F: FnOnce` bound accepts the three kinds of closures: `|:|`, `|&mut:|` and `|&:|`.
- An `F: FnMut` bound only accepts "non-consuming" closures: `|&mut:|` and `|&:|`.
- An `F: Fn` bound only accept the "immutable environment" closures: `|&:|`.
This means that whenever possible the `FnOnce` bound has been used, if the `FnOnce` bound couldn't be used, then the `FnMut` was used. The `Fn` bound was never used in the whole repository.
The `FnMut` bound was the most used, because it resembles the semantics of the current boxed closures: the closure can modify its environment, and the closure may be called several times.
The `FnOnce` bound allows new semantics: you can move out the upvars when the closure is called. This can be effectively paired with the `move || {}` syntax to transfer ownership from the environment to the closure caller.
In the case of trait methods, is hard to select the "right" bound since we can't control how the trait may be implemented by downstream users. In these cases, I have selected the bound based on how we use these traits in the repository. For this reason the selected bounds may not be ideal, and may require tweaking before stabilization.
r? @aturon
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/deriving/bounds.rs | 13 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/clone.rs | 14 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/cmp/eq.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/cmp/ord.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/cmp/totaleq.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/cmp/totalord.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/decodable.rs | 26 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/default.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/encodable.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic/mod.rs | 62 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/hash.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/primitive.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/rand.rs | 28 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/show.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/zero.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/ext/mtwt.rs | 12 |
17 files changed, 166 insertions, 121 deletions
diff --git a/src/libsyntax/ext/deriving/bounds.rs b/src/libsyntax/ext/deriving/bounds.rs index 0595b0bc7f4..3145b3bb1a4 100644 --- a/src/libsyntax/ext/deriving/bounds.rs +++ b/src/libsyntax/ext/deriving/bounds.rs @@ -15,12 +15,13 @@ use ext::deriving::generic::*; use ext::deriving::generic::ty::*; use ptr::P; -pub fn expand_deriving_bound(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { - +pub fn expand_deriving_bound<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ let name = match mitem.node { MetaWord(ref tname) => { match tname.get() { diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs index fccc67bf220..a34764221b3 100644 --- a/src/libsyntax/ext/deriving/clone.rs +++ b/src/libsyntax/ext/deriving/clone.rs @@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_clone(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_clone<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ let inline = cx.meta_word(span, InternedString::new("inline")); let attrs = vec!(cx.attribute(span, inline)); let trait_def = TraitDef { @@ -60,7 +62,7 @@ fn cs_clone( cx.ident_of("Clone"), cx.ident_of("clone"), ]; - let subcall = |field: &FieldInfo| { + let subcall = |&: field: &FieldInfo| { let args = vec![cx.expr_addr_of(field.span, field.self_.clone())]; cx.expr_call_global(field.span, fn_path.clone(), args) diff --git a/src/libsyntax/ext/deriving/cmp/eq.rs b/src/libsyntax/ext/deriving/cmp/eq.rs index 7727bb824db..c8bf5ec326c 100644 --- a/src/libsyntax/ext/deriving/cmp/eq.rs +++ b/src/libsyntax/ext/deriving/cmp/eq.rs @@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_eq(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_eq<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ // structures are equal if all fields are equal, and non equal, if // any fields are not equal or if the enum variants are different fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> { diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs index 1bd55b5d504..bd1962de56e 100644 --- a/src/libsyntax/ext/deriving/cmp/ord.rs +++ b/src/libsyntax/ext/deriving/cmp/ord.rs @@ -20,11 +20,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_ord(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_ord<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ macro_rules! md ( ($name:expr, $op:expr, $equal:expr) => { { let inline = cx.meta_word(span, InternedString::new("inline")); diff --git a/src/libsyntax/ext/deriving/cmp/totaleq.rs b/src/libsyntax/ext/deriving/cmp/totaleq.rs index ecee2008254..2b986bea122 100644 --- a/src/libsyntax/ext/deriving/cmp/totaleq.rs +++ b/src/libsyntax/ext/deriving/cmp/totaleq.rs @@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_totaleq(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_totaleq<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> { cs_same_method(|cx, span, exprs| { // create `a.<method>(); b.<method>(); c.<method>(); ...` diff --git a/src/libsyntax/ext/deriving/cmp/totalord.rs b/src/libsyntax/ext/deriving/cmp/totalord.rs index 6900773f44d..a2bf46f41fc 100644 --- a/src/libsyntax/ext/deriving/cmp/totalord.rs +++ b/src/libsyntax/ext/deriving/cmp/totalord.rs @@ -18,11 +18,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_totalord(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_totalord<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ let inline = cx.meta_word(span, InternedString::new("inline")); let attrs = vec!(cx.attribute(span, inline)); let trait_def = TraitDef { diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs index e3cf2b68752..0a8d59da896 100644 --- a/src/libsyntax/ext/deriving/decodable.rs +++ b/src/libsyntax/ext/deriving/decodable.rs @@ -21,11 +21,13 @@ use parse::token::InternedString; use parse::token; use ptr::P; -pub fn expand_deriving_decodable(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_decodable<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ let trait_def = TraitDef { span: span, attributes: Vec::new(), @@ -155,12 +157,14 @@ fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span, /// Create a decoder for a single enum variant/struct: /// - `outer_pat_path` is the path to this enum variant/struct /// - `getarg` should retrieve the `uint`-th field with name `@str`. -fn decode_static_fields(cx: &mut ExtCtxt, - trait_span: Span, - outer_pat_path: ast::Path, - fields: &StaticFields, - getarg: |&mut ExtCtxt, Span, InternedString, uint| -> P<Expr>) - -> P<Expr> { +fn decode_static_fields<F>(cx: &mut ExtCtxt, + trait_span: Span, + outer_pat_path: ast::Path, + fields: &StaticFields, + mut getarg: F) + -> P<Expr> where + F: FnMut(&mut ExtCtxt, Span, InternedString, uint) -> P<Expr>, +{ match *fields { Unnamed(ref fields) => { let path_expr = cx.expr_path(outer_pat_path); diff --git a/src/libsyntax/ext/deriving/default.rs b/src/libsyntax/ext/deriving/default.rs index f4a66414d89..b3621490ce3 100644 --- a/src/libsyntax/ext/deriving/default.rs +++ b/src/libsyntax/ext/deriving/default.rs @@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_default(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_default<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ let inline = cx.meta_word(span, InternedString::new("inline")); let attrs = vec!(cx.attribute(span, inline)); let trait_def = TraitDef { diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs index 62f3b5d01b4..30851ebeaae 100644 --- a/src/libsyntax/ext/deriving/encodable.rs +++ b/src/libsyntax/ext/deriving/encodable.rs @@ -97,11 +97,13 @@ use ext::deriving::generic::ty::*; use parse::token; use ptr::P; -pub fn expand_deriving_encodable(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_encodable<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ let trait_def = TraitDef { span: span, attributes: Vec::new(), diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index cf3b3ad9051..a75be40604e 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -333,11 +333,13 @@ pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>) impl<'a> TraitDef<'a> { - pub fn expand(&self, - cx: &mut ExtCtxt, - mitem: &ast::MetaItem, - item: &ast::Item, - push: |P<ast::Item>|) { + pub fn expand<F>(&self, + cx: &mut ExtCtxt, + mitem: &ast::MetaItem, + item: &ast::Item, + push: F) where + F: FnOnce(P<ast::Item>), + { let newitem = match item.node { ast::ItemStruct(ref struct_def, ref generics) => { self.expand_struct_def(cx, @@ -1309,14 +1311,16 @@ impl<'a> TraitDef<'a> { /// Fold the fields. `use_foldl` controls whether this is done /// left-to-right (`true`) or right-to-left (`false`). -pub fn cs_fold(use_foldl: bool, - f: |&mut ExtCtxt, Span, P<Expr>, P<Expr>, &[P<Expr>]| -> P<Expr>, - base: P<Expr>, - enum_nonmatch_f: EnumNonMatchCollapsedFunc, - cx: &mut ExtCtxt, - trait_span: Span, - substructure: &Substructure) - -> P<Expr> { +pub fn cs_fold<F>(use_foldl: bool, + mut f: F, + base: P<Expr>, + enum_nonmatch_f: EnumNonMatchCollapsedFunc, + cx: &mut ExtCtxt, + trait_span: Span, + substructure: &Substructure) + -> P<Expr> where + F: FnMut(&mut ExtCtxt, Span, P<Expr>, P<Expr>, &[P<Expr>]) -> P<Expr>, +{ match *substructure.fields { EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => { if use_foldl { @@ -1355,12 +1359,14 @@ pub fn cs_fold(use_foldl: bool, /// self_2.method(__arg_1_2, __arg_2_2)]) /// ``` #[inline] -pub fn cs_same_method(f: |&mut ExtCtxt, Span, Vec<P<Expr>>| -> P<Expr>, - enum_nonmatch_f: EnumNonMatchCollapsedFunc, - cx: &mut ExtCtxt, - trait_span: Span, - substructure: &Substructure) - -> P<Expr> { +pub fn cs_same_method<F>(f: F, + enum_nonmatch_f: EnumNonMatchCollapsedFunc, + cx: &mut ExtCtxt, + trait_span: Span, + substructure: &Substructure) + -> P<Expr> where + F: FnOnce(&mut ExtCtxt, Span, Vec<P<Expr>>) -> P<Expr>, +{ match *substructure.fields { EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => { // call self_n.method(other_1_n, other_2_n, ...) @@ -1388,14 +1394,16 @@ pub fn cs_same_method(f: |&mut ExtCtxt, Span, Vec<P<Expr>>| -> P<Expr>, /// fields. `use_foldl` controls whether this is done left-to-right /// (`true`) or right-to-left (`false`). #[inline] -pub fn cs_same_method_fold(use_foldl: bool, - f: |&mut ExtCtxt, Span, P<Expr>, P<Expr>| -> P<Expr>, - base: P<Expr>, - enum_nonmatch_f: EnumNonMatchCollapsedFunc, - cx: &mut ExtCtxt, - trait_span: Span, - substructure: &Substructure) - -> P<Expr> { +pub fn cs_same_method_fold<F>(use_foldl: bool, + mut f: F, + base: P<Expr>, + enum_nonmatch_f: EnumNonMatchCollapsedFunc, + cx: &mut ExtCtxt, + trait_span: Span, + substructure: &Substructure) + -> P<Expr> where + F: FnMut(&mut ExtCtxt, Span, P<Expr>, P<Expr>) -> P<Expr>, +{ cs_same_method( |cx, span, vals| { if use_foldl { diff --git a/src/libsyntax/ext/deriving/hash.rs b/src/libsyntax/ext/deriving/hash.rs index b7f11c25825..4e59124a129 100644 --- a/src/libsyntax/ext/deriving/hash.rs +++ b/src/libsyntax/ext/deriving/hash.rs @@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_hash(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_hash<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ let (path, generics, args) = if cx.ecfg.deriving_hash_type_parameter { (Path::new_(vec!("std", "hash", "Hash"), None, diff --git a/src/libsyntax/ext/deriving/primitive.rs b/src/libsyntax/ext/deriving/primitive.rs index cd2d98b70f1..8abd846373a 100644 --- a/src/libsyntax/ext/deriving/primitive.rs +++ b/src/libsyntax/ext/deriving/primitive.rs @@ -18,11 +18,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_from_primitive<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ let inline = cx.meta_word(span, InternedString::new("inline")); let attrs = vec!(cx.attribute(span, inline)); let trait_def = TraitDef { diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs index c4e64d58c29..4f6e4d1fb3c 100644 --- a/src/libsyntax/ext/deriving/rand.rs +++ b/src/libsyntax/ext/deriving/rand.rs @@ -17,11 +17,13 @@ use ext::deriving::generic::*; use ext::deriving::generic::ty::*; use ptr::P; -pub fn expand_deriving_rand(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_rand<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ let trait_def = TraitDef { span: span, attributes: Vec::new(), @@ -64,7 +66,7 @@ fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) cx.ident_of("Rand"), cx.ident_of("rand") ); - let rand_call = |cx: &mut ExtCtxt, span| { + let mut rand_call = |&mut: cx: &mut ExtCtxt, span| { cx.expr_call_global(span, rand_ident.clone(), vec!(rng.clone())) @@ -133,12 +135,14 @@ fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) _ => cx.bug("Non-static method in `deriving(Rand)`") }; - fn rand_thing(cx: &mut ExtCtxt, - trait_span: Span, - ctor_path: ast::Path, - summary: &StaticFields, - rand_call: |&mut ExtCtxt, Span| -> P<Expr>) - -> P<Expr> { + fn rand_thing<F>(cx: &mut ExtCtxt, + trait_span: Span, + ctor_path: ast::Path, + summary: &StaticFields, + mut rand_call: F) + -> P<Expr> where + F: FnMut(&mut ExtCtxt, Span) -> P<Expr>, + { let path = cx.expr_path(ctor_path.clone()); match *summary { Unnamed(ref fields) => { diff --git a/src/libsyntax/ext/deriving/show.rs b/src/libsyntax/ext/deriving/show.rs index 322a84eaa2b..a68b521bbc9 100644 --- a/src/libsyntax/ext/deriving/show.rs +++ b/src/libsyntax/ext/deriving/show.rs @@ -21,11 +21,13 @@ use ptr::P; use std::collections::HashMap; -pub fn expand_deriving_show(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_show<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ // &mut ::std::fmt::Formatter let fmtr = Ptr(box Literal(Path::new(vec!("std", "fmt", "Formatter"))), Borrowed(None, ast::MutMutable)); diff --git a/src/libsyntax/ext/deriving/zero.rs b/src/libsyntax/ext/deriving/zero.rs index 7f265b529ff..ea32549cad2 100644 --- a/src/libsyntax/ext/deriving/zero.rs +++ b/src/libsyntax/ext/deriving/zero.rs @@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_zero(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_zero<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ let inline = cx.meta_word(span, InternedString::new("inline")); let attrs = vec!(cx.attribute(span, inline)); let trait_def = TraitDef { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index a697d332d16..9c4e85f16ff 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -238,11 +238,13 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> { /// of expansion and the mark which must be applied to the result. /// Our current interface doesn't allow us to apply the mark to the /// result until after calling make_expr, make_items, etc. -fn expand_mac_invoc<T>(mac: ast::Mac, span: codemap::Span, - parse_thunk: |Box<MacResult>|->Option<T>, - mark_thunk: |T,Mrk|->T, - fld: &mut MacroExpander) - -> Option<T> +fn expand_mac_invoc<T, F, G>(mac: ast::Mac, span: codemap::Span, + parse_thunk: F, + mark_thunk: G, + fld: &mut MacroExpander) + -> Option<T> where + F: FnOnce(Box<MacResult>) -> Option<T>, + G: FnOnce(T, Mrk) -> T, { match mac.node { // it would almost certainly be cleaner to pass the whole diff --git a/src/libsyntax/ext/mtwt.rs b/src/libsyntax/ext/mtwt.rs index 48120b575ac..a4e06aeaf63 100644 --- a/src/libsyntax/ext/mtwt.rs +++ b/src/libsyntax/ext/mtwt.rs @@ -105,9 +105,11 @@ pub fn apply_renames(renames: &RenameList, ctxt: SyntaxContext) -> SyntaxContext } /// Fetch the SCTable from TLS, create one if it doesn't yet exist. -pub fn with_sctable<T>(op: |&SCTable| -> T) -> T { +pub fn with_sctable<T, F>(op: F) -> T where + F: FnOnce(&SCTable) -> T, +{ thread_local!(static SCTABLE_KEY: SCTable = new_sctable_internal()) - SCTABLE_KEY.with(|slot| op(slot)) + SCTABLE_KEY.with(move |slot| op(slot)) } // Make a fresh syntax context table with EmptyCtxt in slot zero @@ -167,12 +169,14 @@ type ResolveTable = HashMap<(Name,SyntaxContext),Name>; // okay, I admit, putting this in TLS is not so nice: // fetch the SCTable from TLS, create one if it doesn't yet exist. -fn with_resolve_table_mut<T>(op: |&mut ResolveTable| -> T) -> T { +fn with_resolve_table_mut<T, F>(op: F) -> T where + F: FnOnce(&mut ResolveTable) -> T, +{ thread_local!(static RESOLVE_TABLE_KEY: RefCell<ResolveTable> = { RefCell::new(HashMap::new()) }) - RESOLVE_TABLE_KEY.with(|slot| op(&mut *slot.borrow_mut())) + RESOLVE_TABLE_KEY.with(move |slot| op(&mut *slot.borrow_mut())) } /// Resolve a syntax object to a name, per MTWT. |
