about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2014-09-05 21:27:47 -0700
committerPatrick Walton <pcwalton@mimiga.net>2014-09-18 16:31:58 -0700
commit7c00d77e8bd18d2e1873e8e995885b3500a88a0d (patch)
tree21d5a718a9a40ed6920463b2348a0788fadebc2c
parent9c41064308806907067a1bc5f6f9138c29310221 (diff)
downloadrust-7c00d77e8bd18d2e1873e8e995885b3500a88a0d.tar.gz
rust-7c00d77e8bd18d2e1873e8e995885b3500a88a0d.zip
librustc: Implement the syntax in the RFC for unboxed closure sugar.
Part of issue #16640. I am leaving this issue open to handle parsing of
higher-rank lifetimes in traits.

This change breaks code that used unboxed closures:

* Instead of `F:|&: int| -> int`, write `F:Fn(int) -> int`.

* Instead of `F:|&mut: int| -> int`, write `F:FnMut(int) -> int`.

* Instead of `F:|: int| -> int`, write `F:FnOnce(int) -> int`.

[breaking-change]
-rw-r--r--src/librustc/middle/resolve.rs28
-rw-r--r--src/librustc/middle/typeck/astconv.rs28
-rw-r--r--src/librustc/middle/typeck/collect.rs42
-rw-r--r--src/libsyntax/ast.rs9
-rw-r--r--src/libsyntax/fold.rs24
-rw-r--r--src/libsyntax/parse/parser.rs76
-rw-r--r--src/libsyntax/print/pprust.rs49
-rw-r--r--src/test/compile-fail/borrowck-unboxed-closures.rs6
-rw-r--r--src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs18
-rw-r--r--src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs17
-rw-r--r--src/test/compile-fail/unboxed-closures-wrong-trait.rs2
-rw-r--r--src/test/run-pass/fn-trait-sugar.rs2
-rw-r--r--src/test/run-pass/unboxed-closures-all-traits.rs6
-rw-r--r--src/test/run-pass/unboxed-closures-drop.rs6
-rw-r--r--src/test/run-pass/unboxed-closures-single-word-env.rs6
-rw-r--r--src/test/run-pass/unboxed-closures-unique-type-id.rs3
-rw-r--r--src/test/run-pass/where-clauses-unboxed-closures.rs2
17 files changed, 207 insertions, 117 deletions
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 6fa33f4b5aa..15564f7bc53 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -4328,6 +4328,34 @@ impl<'a> Resolver<'a> {
                 self.resolve_trait_reference(id, tref, reference_type)
             }
             UnboxedFnTyParamBound(ref unboxed_function) => {
+                match self.resolve_path(unboxed_function.ref_id,
+                                        &unboxed_function.path,
+                                        TypeNS,
+                                        true) {
+                    None => {
+                        let path_str = self.path_idents_to_string(
+                            &unboxed_function.path);
+                        self.resolve_error(unboxed_function.path.span,
+                                           format!("unresolved trait `{}`",
+                                                   path_str).as_slice())
+                    }
+                    Some(def) => {
+                        match def {
+                            (DefTrait(_), _) => {
+                                self.record_def(unboxed_function.ref_id, def);
+                            }
+                            _ => {
+                                let msg =
+                                    format!("`{}` is not a trait",
+                                            self.path_idents_to_string(
+                                                &unboxed_function.path));
+                                self.resolve_error(unboxed_function.path.span,
+                                                   msg.as_slice());
+                            }
+                        }
+                    }
+                }
+
                 for argument in unboxed_function.decl.inputs.iter() {
                     self.resolve_type(&*argument.ty);
                 }
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index 8f60be8f7fb..2503fb2541b 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -585,32 +585,29 @@ pub fn trait_ref_for_unboxed_function<'tcx, AC: AstConv<'tcx>,
                                       RS:RegionScope>(
                                       this: &AC,
                                       rscope: &RS,
-                                      unboxed_function: &ast::UnboxedFnTy,
+                                      kind: ast::UnboxedClosureKind,
+                                      decl: &ast::FnDecl,
                                       self_ty: Option<ty::t>)
                                       -> ty::TraitRef {
-    let lang_item = match unboxed_function.kind {
+    let lang_item = match kind {
         ast::FnUnboxedClosureKind => FnTraitLangItem,
         ast::FnMutUnboxedClosureKind => FnMutTraitLangItem,
         ast::FnOnceUnboxedClosureKind => FnOnceTraitLangItem,
     };
     let trait_did = this.tcx().lang_items.require(lang_item).unwrap();
-    let input_types =
-        unboxed_function.decl
-                        .inputs
-                        .iter()
-                        .map(|input| {
+    let input_types = decl.inputs
+                          .iter()
+                          .map(|input| {
                             ast_ty_to_ty(this, rscope, &*input.ty)
-                        }).collect::<Vec<_>>();
+                          }).collect::<Vec<_>>();
     let input_tuple = if input_types.len() == 0 {
         ty::mk_nil()
     } else {
         ty::mk_tup(this.tcx(), input_types)
     };
-    let output_type = ast_ty_to_ty(this,
-                                   rscope,
-                                   &*unboxed_function.decl.output);
+    let output_type = ast_ty_to_ty(this, rscope, &*decl.output);
     let mut substs = Substs::new_type(vec!(input_tuple, output_type),
-                                             Vec::new());
+                                      Vec::new());
 
     match self_ty {
         Some(s) => substs.types.push(SelfSpace, s),
@@ -648,7 +645,8 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
                 substs
             } = trait_ref_for_unboxed_function(this,
                                                rscope,
-                                               &**unboxed_function,
+                                               unboxed_function.kind,
+                                               &*unboxed_function.decl,
                                                None);
             let r = ptr_ty.default_region();
             let tr = ty::mk_trait(this.tcx(),
@@ -1510,7 +1508,7 @@ fn compute_region_bound<'tcx, AC: AstConv<'tcx>, RS:RegionScope>(
 pub struct PartitionedBounds<'a> {
     pub builtin_bounds: ty::BuiltinBounds,
     pub trait_bounds: Vec<&'a ast::TraitRef>,
-    pub unboxed_fn_ty_bounds: Vec<&'a ast::UnboxedFnTy>,
+    pub unboxed_fn_ty_bounds: Vec<&'a ast::UnboxedFnBound>,
     pub region_bounds: Vec<&'a ast::Lifetime>,
 }
 
@@ -1574,7 +1572,7 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt,
                 region_bounds.push(l);
             }
             ast::UnboxedFnTyParamBound(ref unboxed_function) => {
-                unboxed_fn_ty_bounds.push(unboxed_function);
+                unboxed_fn_ty_bounds.push(&**unboxed_function);
             }
         }
     }
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index b7aa7656ae9..40c52fd36b9 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -1427,7 +1427,8 @@ pub fn instantiate_unboxed_fn_ty<'tcx,AC>(this: &AC,
     let param_ty = param_ty.to_ty(this.tcx());
     Rc::new(astconv::trait_ref_for_unboxed_function(this,
                                                     &rscope,
-                                                    unboxed_function,
+                                                    unboxed_function.kind,
+                                                    &*unboxed_function.decl,
                                                     Some(param_ty)))
 }
 
@@ -2165,9 +2166,42 @@ fn conv_param_bounds<'tcx,AC>(this: &AC,
                                      region_bounds,
                                      unboxed_fn_ty_bounds } =
         astconv::partition_bounds(this.tcx(), span, all_bounds.as_slice());
-    let unboxed_fn_ty_bounds =
-        unboxed_fn_ty_bounds.into_iter()
-        .map(|b| instantiate_unboxed_fn_ty(this, b, param_ty));
+
+    let unboxed_fn_ty_bounds = unboxed_fn_ty_bounds.move_iter().map(|b| {
+        let trait_id = this.tcx().def_map.borrow().get(&b.ref_id).def_id();
+        let mut kind = None;
+        for &(lang_item, this_kind) in [
+            (this.tcx().lang_items.fn_trait(), ast::FnUnboxedClosureKind),
+            (this.tcx().lang_items.fn_mut_trait(),
+             ast::FnMutUnboxedClosureKind),
+            (this.tcx().lang_items.fn_once_trait(),
+             ast::FnOnceUnboxedClosureKind)
+        ].iter() {
+            if Some(trait_id) == lang_item {
+                kind = Some(this_kind);
+                break
+            }
+        }
+
+        let kind = match kind {
+            Some(kind) => kind,
+            None => {
+                this.tcx().sess.span_err(b.path.span,
+                                         "unboxed function trait must be one \
+                                          of `Fn`, `FnMut`, or `FnOnce`");
+                ast::FnMutUnboxedClosureKind
+            }
+        };
+
+        let rscope = ExplicitRscope;
+        let param_ty = param_ty.to_ty(this.tcx());
+        Rc::new(astconv::trait_ref_for_unboxed_function(this,
+                                                        &rscope,
+                                                        kind,
+                                                        &*b.decl,
+                                                        Some(param_ty)))
+    });
+
     let trait_bounds: Vec<Rc<ty::TraitRef>> =
         trait_bounds.into_iter()
         .map(|b| {
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index eac158e664c..e74222fac09 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -213,13 +213,20 @@ pub static DUMMY_NODE_ID: NodeId = -1;
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum TyParamBound {
     TraitTyParamBound(TraitRef),
-    UnboxedFnTyParamBound(UnboxedFnTy),
+    UnboxedFnTyParamBound(P<UnboxedFnBound>),
     RegionTyParamBound(Lifetime)
 }
 
 pub type TyParamBounds = OwnedSlice<TyParamBound>;
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
+pub struct UnboxedFnBound {
+    pub path: Path,
+    pub decl: P<FnDecl>,
+    pub ref_id: NodeId,
+}
+
+#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub struct TyParam {
     pub ident: Ident,
     pub id: NodeId,
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 3beba5bcda4..1441f5beb6a 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -657,16 +657,26 @@ pub fn noop_fold_fn_decl<T: Folder>(decl: P<FnDecl>, fld: &mut T) -> P<FnDecl> {
     })
 }
 
-pub fn noop_fold_ty_param_bound<T: Folder>(tpb: TyParamBound, fld: &mut T)
-                                           -> TyParamBound {
+pub fn noop_fold_ty_param_bound<T>(tpb: TyParamBound, fld: &mut T)
+                                   -> TyParamBound
+                                   where T: Folder {
     match tpb {
         TraitTyParamBound(ty) => TraitTyParamBound(fld.fold_trait_ref(ty)),
         RegionTyParamBound(lifetime) => RegionTyParamBound(fld.fold_lifetime(lifetime)),
-        UnboxedFnTyParamBound(UnboxedFnTy {decl, kind}) => {
-            UnboxedFnTyParamBound(UnboxedFnTy {
-                decl: fld.fold_fn_decl(decl),
-                kind: kind,
-            })
+        UnboxedFnTyParamBound(bound) => {
+            match *bound {
+                UnboxedFnBound {
+                    ref path,
+                    ref decl,
+                    ref_id
+                } => {
+                    UnboxedFnTyParamBound(P(UnboxedFnBound {
+                        path: fld.fold_path(path.clone()),
+                        decl: fld.fold_fn_decl(decl.clone()),
+                        ref_id: fld.new_id(ref_id),
+                    }))
+                }
+            }
         }
     }
 }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index ff4fd41fbd7..8a0027e5c06 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -55,7 +55,8 @@ use ast::{TyTypeof, TyInfer, TypeMethod};
 use ast::{TyNil, TyParam, TyParamBound, TyParen, TyPath, TyPtr, TyQPath};
 use ast::{TyRptr, TyTup, TyU32, TyUnboxedFn, TyUniq, TyVec, UnUniq};
 use ast::{TypeImplItem, TypeTraitItem, Typedef, UnboxedClosureKind};
-use ast::{UnboxedFnTy, UnboxedFnTyParamBound, UnnamedField, UnsafeBlock};
+use ast::{UnboxedFnBound, UnboxedFnTy, UnboxedFnTyParamBound};
+use ast::{UnnamedField, UnsafeBlock};
 use ast::{UnsafeFn, ViewItem, ViewItem_, ViewItemExternCrate, ViewItemUse};
 use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
 use ast::{Visibility, WhereClause, WherePredicate};
@@ -3666,39 +3667,6 @@ impl<'a> Parser<'a> {
         })
     }
 
-    fn parse_unboxed_function_type(&mut self) -> UnboxedFnTy {
-        let (optional_unboxed_closure_kind, inputs) =
-            if self.eat(&token::OROR) {
-                (None, Vec::new())
-            } else {
-                self.expect_or();
-
-                let optional_unboxed_closure_kind =
-                    self.parse_optional_unboxed_closure_kind();
-
-                let inputs = self.parse_seq_to_before_or(&token::COMMA,
-                                                         |p| {
-                    p.parse_arg_general(false)
-                });
-                self.expect_or();
-                (optional_unboxed_closure_kind, inputs)
-            };
-
-        let (return_style, output) = self.parse_ret_ty();
-        UnboxedFnTy {
-            decl: P(FnDecl {
-                inputs: inputs,
-                output: output,
-                cf: return_style,
-                variadic: false,
-            }),
-            kind: match optional_unboxed_closure_kind {
-                Some(kind) => kind,
-                None => FnMutUnboxedClosureKind,
-            },
-        }
-    }
-
     // Parses a sequence of bounds if a `:` is found,
     // otherwise returns empty list.
     fn parse_colon_then_ty_param_bounds(&mut self)
@@ -3730,13 +3698,31 @@ impl<'a> Parser<'a> {
                     self.bump();
                 }
                 token::MOD_SEP | token::IDENT(..) => {
-                    let tref = self.parse_trait_ref();
-                    result.push(TraitTyParamBound(tref));
-                }
-                token::BINOP(token::OR) | token::OROR => {
-                    let unboxed_function_type =
-                        self.parse_unboxed_function_type();
-                    result.push(UnboxedFnTyParamBound(unboxed_function_type));
+                    let path =
+                        self.parse_path(LifetimeAndTypesWithoutColons).path;
+                    if self.token == token::LPAREN {
+                        self.bump();
+                        let inputs = self.parse_seq_to_end(
+                            &token::RPAREN,
+                            seq_sep_trailing_allowed(token::COMMA),
+                            |p| p.parse_arg_general(false));
+                        let (return_style, output) = self.parse_ret_ty();
+                        result.push(UnboxedFnTyParamBound(P(UnboxedFnBound {
+                            path: path,
+                            decl: P(FnDecl {
+                                inputs: inputs,
+                                output: output,
+                                cf: return_style,
+                                variadic: false,
+                            }),
+                            ref_id: ast::DUMMY_NODE_ID,
+                        })));
+                    } else {
+                        result.push(TraitTyParamBound(ast::TraitRef {
+                            path: path,
+                            ref_id: ast::DUMMY_NODE_ID,
+                        }))
+                    }
                 }
                 _ => break,
             }
@@ -4423,14 +4409,6 @@ impl<'a> Parser<'a> {
          Some(attrs))
     }
 
-    /// Parse a::B<String,int>
-    fn parse_trait_ref(&mut self) -> TraitRef {
-        ast::TraitRef {
-            path: self.parse_path(LifetimeAndTypesWithoutColons).path,
-            ref_id: ast::DUMMY_NODE_ID,
-        }
-    }
-
     /// Parse struct Foo { ... }
     fn parse_item_struct(&mut self, is_virtual: bool) -> ItemInfo {
         let class_name = self.parse_ident();
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 0ae5303641b..d7dd87a096e 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -2190,16 +2190,13 @@ impl<'a> State<'a> {
                         self.print_lifetime(lt)
                     }
                     UnboxedFnTyParamBound(ref unboxed_function_type) => {
-                        self.print_ty_fn(None,
-                                         None,
-                                         ast::NormalFn,
-                                         ast::Many,
-                                         &*unboxed_function_type.decl,
-                                         None,
-                                         &OwnedSlice::empty(),
-                                         None,
-                                         None,
-                                         Some(unboxed_function_type.kind))
+                        try!(self.print_path(&unboxed_function_type.path,
+                                             false));
+                        try!(self.popen());
+                        try!(self.print_fn_args(&*unboxed_function_type.decl,
+                                                None));
+                        try!(self.pclose());
+                        self.print_fn_output(&*unboxed_function_type.decl)
                     }
                 })
             }
@@ -2430,6 +2427,23 @@ impl<'a> State<'a> {
         self.end()
     }
 
+    pub fn print_fn_output(&mut self, decl: &ast::FnDecl) -> IoResult<()> {
+        match decl.output.node {
+            ast::TyNil => Ok(()),
+            _ => {
+                try!(self.space_if_not_bol());
+                try!(self.ibox(indent_unit));
+                try!(self.word_space("->"));
+                if decl.cf == ast::NoReturn {
+                    try!(self.word_nbsp("!"));
+                } else {
+                    try!(self.print_type(&*decl.output));
+                }
+                self.end()
+            }
+        }
+    }
+
     pub fn print_ty_fn(&mut self,
                        opt_abi: Option<abi::Abi>,
                        opt_sigil: Option<char>,
@@ -2510,20 +2524,7 @@ impl<'a> State<'a> {
 
         try!(self.maybe_print_comment(decl.output.span.lo));
 
-        match decl.output.node {
-            ast::TyNil => {}
-            _ => {
-                try!(self.space_if_not_bol());
-                try!(self.ibox(indent_unit));
-                try!(self.word_space("->"));
-                if decl.cf == ast::NoReturn {
-                    try!(self.word_nbsp("!"));
-                } else {
-                    try!(self.print_type(&*decl.output));
-                }
-                try!(self.end());
-            }
-        }
+        try!(self.print_fn_output(decl));
 
         match generics {
             Some(generics) => try!(self.print_where_clause(generics)),
diff --git a/src/test/compile-fail/borrowck-unboxed-closures.rs b/src/test/compile-fail/borrowck-unboxed-closures.rs
index d822bb22e2a..03438b1d7e1 100644
--- a/src/test/compile-fail/borrowck-unboxed-closures.rs
+++ b/src/test/compile-fail/borrowck-unboxed-closures.rs
@@ -10,17 +10,17 @@
 
 #![feature(overloaded_calls)]
 
-fn a<F:|&: int, int| -> int>(mut f: F) {
+fn a<F:Fn(int, int) -> int>(mut f: F) {
     let g = &mut f;
     f(1, 2);    //~ ERROR cannot borrow `f` as immutable
     //~^ ERROR cannot borrow `f` as immutable
 }
 
-fn b<F:|&mut: int, int| -> int>(f: F) {
+fn b<F:FnMut(int, int) -> int>(f: F) {
     f(1, 2);    //~ ERROR cannot borrow immutable argument
 }
 
-fn c<F:|: int, int| -> int>(f: F) {
+fn c<F:FnOnce(int, int) -> int>(f: F) {
     f(1, 2);
     f(1, 2);    //~ ERROR use of moved value
 }
diff --git a/src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs b/src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs
new file mode 100644
index 00000000000..f51160a1b23
--- /dev/null
+++ b/src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs
@@ -0,0 +1,18 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn f<F:Nonexist(int) -> int>(x: F) {} //~ ERROR unresolved trait
+
+type Typedef = int;
+
+fn g<F:Typedef(int) -> int>(x: F) {} //~ ERROR `Typedef` is not a trait
+
+fn main() {}
+
diff --git a/src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs b/src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs
new file mode 100644
index 00000000000..a751ae1c518
--- /dev/null
+++ b/src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs
@@ -0,0 +1,17 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait Trait {}
+
+fn f<F:Trait(int) -> int>(x: F) {}
+//~^ ERROR unboxed function trait must be one of `Fn`, `FnMut`, or `FnOnce`
+
+fn main() {}
+
diff --git a/src/test/compile-fail/unboxed-closures-wrong-trait.rs b/src/test/compile-fail/unboxed-closures-wrong-trait.rs
index 27f1da75c3a..97ad64a77ba 100644
--- a/src/test/compile-fail/unboxed-closures-wrong-trait.rs
+++ b/src/test/compile-fail/unboxed-closures-wrong-trait.rs
@@ -10,7 +10,7 @@
 
 #![feature(lang_items, overloaded_calls, unboxed_closures)]
 
-fn c<F:|: int, int| -> int>(f: F) -> int {
+fn c<F:FnOnce(int, int) -> int>(f: F) -> int {
     f(5, 6)
 }
 
diff --git a/src/test/run-pass/fn-trait-sugar.rs b/src/test/run-pass/fn-trait-sugar.rs
index ccb5634f7a2..b0947f46a86 100644
--- a/src/test/run-pass/fn-trait-sugar.rs
+++ b/src/test/run-pass/fn-trait-sugar.rs
@@ -21,7 +21,7 @@ impl FnMut<(int,),int> for S {
     }
 }
 
-fn call_it<F:|int|->int>(mut f: F, x: int) -> int {
+fn call_it<F:FnMut(int)->int>(mut f: F, x: int) -> int {
     f.call_mut((x,)) + 3
 }
 
diff --git a/src/test/run-pass/unboxed-closures-all-traits.rs b/src/test/run-pass/unboxed-closures-all-traits.rs
index c362a83e60c..d9120495155 100644
--- a/src/test/run-pass/unboxed-closures-all-traits.rs
+++ b/src/test/run-pass/unboxed-closures-all-traits.rs
@@ -10,15 +10,15 @@
 
 #![feature(lang_items, overloaded_calls, unboxed_closures)]
 
-fn a<F:|&: int, int| -> int>(f: F) -> int {
+fn a<F:Fn(int, int) -> int>(f: F) -> int {
     f(1, 2)
 }
 
-fn b<F:|&mut: int, int| -> int>(mut f: F) -> int {
+fn b<F:FnMut(int, int) -> int>(mut f: F) -> int {
     f(3, 4)
 }
 
-fn c<F:|: int, int| -> int>(f: F) -> int {
+fn c<F:FnOnce(int, int) -> int>(f: F) -> int {
     f(5, 6)
 }
 
diff --git a/src/test/run-pass/unboxed-closures-drop.rs b/src/test/run-pass/unboxed-closures-drop.rs
index f20dddcae54..a455e4d2032 100644
--- a/src/test/run-pass/unboxed-closures-drop.rs
+++ b/src/test/run-pass/unboxed-closures-drop.rs
@@ -41,15 +41,15 @@ impl Drop for Droppable {
     }
 }
 
-fn a<F:|&: int, int| -> int>(f: F) -> int {
+fn a<F:Fn(int, int) -> int>(f: F) -> int {
     f(1, 2)
 }
 
-fn b<F:|&mut: int, int| -> int>(mut f: F) -> int {
+fn b<F:FnMut(int, int) -> int>(mut f: F) -> int {
     f(3, 4)
 }
 
-fn c<F:|: int, int| -> int>(f: F) -> int {
+fn c<F:FnOnce(int, int) -> int>(f: F) -> int {
     f(5, 6)
 }
 
diff --git a/src/test/run-pass/unboxed-closures-single-word-env.rs b/src/test/run-pass/unboxed-closures-single-word-env.rs
index 754b1f70644..aef6956118e 100644
--- a/src/test/run-pass/unboxed-closures-single-word-env.rs
+++ b/src/test/run-pass/unboxed-closures-single-word-env.rs
@@ -13,15 +13,15 @@
 
 #![feature(overloaded_calls, unboxed_closures)]
 
-fn a<F:|&: int, int| -> int>(f: F) -> int {
+fn a<F:Fn(int, int) -> int>(f: F) -> int {
     f(1, 2)
 }
 
-fn b<F:|&mut: int, int| -> int>(mut f: F) -> int {
+fn b<F:FnMut(int, int) -> int>(mut f: F) -> int {
     f(3, 4)
 }
 
-fn c<F:|: int, int| -> int>(f: F) -> int {
+fn c<F:FnOnce(int, int) -> int>(f: F) -> int {
     f(5, 6)
 }
 
diff --git a/src/test/run-pass/unboxed-closures-unique-type-id.rs b/src/test/run-pass/unboxed-closures-unique-type-id.rs
index 55d89d4e4f6..f35daa65a43 100644
--- a/src/test/run-pass/unboxed-closures-unique-type-id.rs
+++ b/src/test/run-pass/unboxed-closures-unique-type-id.rs
@@ -21,8 +21,7 @@
 
 use std::ptr;
 
-pub fn replace_map<'a, T, F>(src: &mut T, prod: F)
-where F: |: T| -> T {
+pub fn replace_map<'a, T, F>(src: &mut T, prod: F) where F: FnOnce(T) -> T {
     unsafe { *src = prod(ptr::read(src as *mut T as *const T)); }
 }
 
diff --git a/src/test/run-pass/where-clauses-unboxed-closures.rs b/src/test/run-pass/where-clauses-unboxed-closures.rs
index ae005b4ae53..808e937bc72 100644
--- a/src/test/run-pass/where-clauses-unboxed-closures.rs
+++ b/src/test/run-pass/where-clauses-unboxed-closures.rs
@@ -13,7 +13,7 @@
 struct Bencher;
 
 // ICE
-fn warm_up<'a, F>(f: F) where F: |&: &'a mut Bencher| {
+fn warm_up<'a, F>(f: F) where F: Fn(&'a mut Bencher) {
 }
 
 fn main() {