about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/doc/rust.md39
-rw-r--r--src/libsyntax/parse/obsolete.rs12
-rw-r--r--src/libsyntax/parse/parser.rs223
-rw-r--r--src/libsyntax/print/pprust.rs35
-rw-r--r--src/test/bench/shootout-meteor.rs4
-rw-r--r--src/test/compile-fail/closure-bounds-static-cant-capture-borrowed.rs4
-rw-r--r--src/test/run-pass/closure-syntax.rs76
-rw-r--r--src/test/run-pass/const-fn-val.rs2
-rw-r--r--src/test/run-pass/const-vec-of-fns.rs2
-rw-r--r--src/test/run-pass/expr-block-fn.rs2
-rw-r--r--src/test/run-pass/expr-block-generic-box1.rs2
-rw-r--r--src/test/run-pass/expr-block-generic-box2.rs2
-rw-r--r--src/test/run-pass/expr-block-generic-unique1.rs2
-rw-r--r--src/test/run-pass/expr-block-generic-unique2.rs2
-rw-r--r--src/test/run-pass/expr-block-generic.rs2
-rw-r--r--src/test/run-pass/expr-if-generic-box1.rs2
-rw-r--r--src/test/run-pass/expr-if-generic-box2.rs2
-rw-r--r--src/test/run-pass/expr-if-generic.rs2
-rw-r--r--src/test/run-pass/expr-match-generic-box1.rs2
-rw-r--r--src/test/run-pass/expr-match-generic-box2.rs2
-rw-r--r--src/test/run-pass/expr-match-generic-unique1.rs2
-rw-r--r--src/test/run-pass/expr-match-generic-unique2.rs2
-rw-r--r--src/test/run-pass/fn-coerce-field.rs2
-rw-r--r--src/test/run-pass/hashmap-memory.rs2
-rw-r--r--src/test/run-pass/issue-10767.rs15
-rw-r--r--src/test/run-pass/issue-3052.rs2
-rw-r--r--src/test/run-pass/issue-3904.rs2
-rw-r--r--src/test/run-pass/issue-6157.rs2
-rw-r--r--src/test/run-pass/once-move-out-on-stack.rs2
-rw-r--r--src/test/run-pass/regions-copy-closure.rs4
-rw-r--r--src/test/run-pass/regions-dependent-autofn.rs4
-rw-r--r--src/test/run-pass/regions-static-closure.rs4
32 files changed, 293 insertions, 169 deletions
diff --git a/src/doc/rust.md b/src/doc/rust.md
index 96ec52c8cf9..1e1278f08bb 100644
--- a/src/doc/rust.md
+++ b/src/doc/rust.md
@@ -3420,8 +3420,21 @@ x = bo(5,7);
 
 ### Closure types
 
-The type of a closure mapping an input of type `A` to an output of type `B` is `|A| -> B`. A closure with no arguments or return values has type `||`.
+~~~~ {.notrust .ebnf .notation}
+closure_type := [ 'unsafe' ] [ '<' lifetime-list '>' ] '|' arg-list '|'
+                [ ':' bound-list ] [ '->' type ]
+procedure_type := 'proc' [ '<' lifetime-list '>' ] '(' arg-list ')'
+                  [ ':' bound-list ] [ '->' type ]
+lifetime-list := lifetime | lifetime ',' lifetime-list
+arg-list := ident ':' type | ident ':' type ',' arg-list
+bound-list := bound | bound '+' bound-list
+bound := path | lifetime
+~~~~
 
+The type of a closure mapping an input of type `A` to an output of type `B` is
+`|A| -> B`. A closure with no arguments or return values has type `||`.
+Similarly, a procedure mapping `A` to `B` is `proc(A) -> B` and a no-argument
+and no-return value closure has type `proc()`.
 
 An example of creating and calling a closure:
 
@@ -3444,6 +3457,30 @@ call_closure(closure_no_args, closure_args);
 
 ```
 
+Unlike closures, procedures may only be invoked once, but own their
+environment, and are allowed to move out of their environment. Procedures are
+allocated on the heap (unlike closures). An example of creating and calling a
+procedure:
+
+```rust
+let string = ~"Hello";
+
+// Creates a new procedure, passing it to the `spawn` function.
+spawn(proc() {
+  println!("{} world!", string);
+});
+
+// the variable `string` has been moved into the previous procedure, so it is
+// no longer usable.
+
+
+// Create an invoke a procedure. Note that the procedure is *moved* when
+// invoked, so it cannot be invoked again.
+let f = proc(n: int) { n + 22 };
+println!("answer: {}", f(20));
+
+```
+
 ### Object types
 
 Every trait item (see [traits](#traits)) defines a type with the same name as the trait.
diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
index 63b3fb09ee3..d09a002e117 100644
--- a/src/libsyntax/parse/obsolete.rs
+++ b/src/libsyntax/parse/obsolete.rs
@@ -36,8 +36,6 @@ pub enum ObsoleteSyntax {
     ObsoleteEnumWildcard,
     ObsoleteStructWildcard,
     ObsoleteVecDotDotWildcard,
-    ObsoleteBoxedClosure,
-    ObsoleteClosureType,
     ObsoleteMultipleImport,
     ObsoleteManagedPattern,
     ObsoleteManagedString,
@@ -111,16 +109,6 @@ impl<'a> ParserObsoleteMethods for Parser<'a> {
                 "vec slice wildcard",
                 "use `..` instead of `.._` for matching slices"
             ),
-            ObsoleteBoxedClosure => (
-                "managed or owned closure",
-                "managed closures have been removed and owned closures are \
-                 now written `proc()`"
-            ),
-            ObsoleteClosureType => (
-                "closure type",
-                "closures are now written `|A| -> B` rather than `&fn(A) -> \
-                 B`."
-            ),
             ObsoleteMultipleImport => (
                 "multiple imports",
                 "only one import is allowed per `use` statement"
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 94f5458ba53..62ce0f1e113 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -29,7 +29,7 @@ use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc};
 use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary};
 use ast::{ExprVec, ExprVstore, ExprVstoreSlice};
 use ast::{ExprVstoreMutSlice, ExprWhile, ExprForLoop, ExternFn, Field, FnDecl};
-use ast::{ExprVstoreUniq, Onceness, Once, Many};
+use ast::{ExprVstoreUniq, Once, Many};
 use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod};
 use ast::{Ident, ImpureFn, Inherited, Item, Item_, ItemStatic};
 use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl};
@@ -892,8 +892,44 @@ impl<'a> Parser<'a> {
     // Parses a procedure type (`proc`). The initial `proc` keyword must
     // already have been parsed.
     pub fn parse_proc_type(&mut self) -> Ty_ {
-        let bounds = self.parse_optional_ty_param_bounds();
-        let (decl, lifetimes) = self.parse_ty_fn_decl(false);
+        /*
+
+        proc <'lt> (S) [:Bounds] -> T
+        ^~~^ ^~~~^  ^  ^~~~~~~~^    ^
+         |     |    |      |        |
+         |     |    |      |      Return type
+         |     |    |    Bounds
+         |     |  Argument types
+         |   Lifetimes
+        the `proc` keyword
+
+        */
+
+        // NOTE: remove after the next stage0 snap
+        let (decl, lifetimes, bounds) = if self.token == token::COLON {
+            let (_, bounds) = self.parse_optional_ty_param_bounds(false);
+            let (decl, lifetimes) = self.parse_ty_fn_decl(false);
+            (decl, lifetimes, bounds)
+        } else {
+            let lifetimes = if self.eat(&token::LT) {
+                let lifetimes = self.parse_lifetimes();
+                self.expect_gt();
+                lifetimes
+            } else {
+                Vec::new()
+            };
+
+            let (inputs, variadic) = self.parse_fn_args(false, false);
+            let (_, bounds) = self.parse_optional_ty_param_bounds(false);
+            let (ret_style, ret_ty) = self.parse_ret_ty();
+            let decl = P(FnDecl {
+                inputs: inputs,
+                output: ret_ty,
+                cf: ret_style,
+                variadic: variadic
+            });
+            (decl, lifetimes, bounds)
+        };
         TyClosure(@ClosureTy {
             sigil: OwnedSigil,
             region: None,
@@ -906,102 +942,68 @@ impl<'a> Parser<'a> {
     }
 
     // parse a TyClosure type
-    pub fn parse_ty_closure(&mut self,
-                            opt_sigil: Option<ast::Sigil>,
-                            mut region: Option<ast::Lifetime>)
-                            -> Ty_ {
+    pub fn parse_ty_closure(&mut self) -> Ty_ {
         /*
 
-        (&|~|@) ['r] [unsafe] [once] fn [:Bounds] <'lt> (S) -> T
-        ^~~~~~^ ^~~^ ^~~~~~~^ ^~~~~^    ^~~~~~~~^ ^~~~^ ^~^    ^
-           |     |     |        |           |       |    |     |
-           |     |     |        |           |       |    |   Return type
-           |     |     |        |           |       |  Argument types
-           |     |     |        |           |   Lifetimes
-           |     |     |        |       Closure bounds
-           |     |     |     Once-ness (a.k.a., affine)
-           |     |   Purity
-           | Lifetime bound
-        Allocation type
+        [unsafe] [once] <'lt> |S| [:Bounds] -> T
+        ^~~~~~~^ ^~~~~^ ^~~~^  ^  ^~~~~~~~^    ^
+          |        |      |    |      |        |
+          |        |      |    |      |      Return type
+          |        |      |    |  Closure bounds
+          |        |      |  Argument types
+          |        |    Lifetimes
+          |     Once-ness (a.k.a., affine)
+        Purity
 
         */
 
-        // At this point, the allocation type and lifetime bound have been
-        // parsed.
-
+        // NOTE: remove 'let region' after a stage0 snap
+        let region = self.parse_opt_lifetime();
         let purity = self.parse_unsafety();
-        let onceness = parse_onceness(self);
-
-        let (sigil, decl, lifetimes, bounds) = match opt_sigil {
-            Some(sigil) => {
-                // Old-style closure syntax (`fn(A)->B`).
-                self.expect_keyword(keywords::Fn);
-                let bounds = self.parse_optional_ty_param_bounds();
-                let (decl, lifetimes) = self.parse_ty_fn_decl(false);
-                (sigil, decl, lifetimes, bounds)
-            }
-            None => {
-                // New-style closure syntax (`<'lt>|A|:K -> B`).
-                let lifetimes = if self.eat(&token::LT) {
-                    let lifetimes = self.parse_lifetimes();
-                    self.expect_gt();
-
-                    // Re-parse the region here. What a hack.
-                    if region.is_some() {
-                        self.span_err(self.last_span,
-                                      "lifetime declarations must precede \
-                                       the lifetime associated with a \
-                                       closure");
-                    }
-                    region = self.parse_opt_lifetime();
+        let onceness = if self.eat_keyword(keywords::Once) {Once} else {Many};
 
-                    lifetimes
-                } else {
-                    Vec::new()
-                };
+        let lifetimes = if self.eat(&token::LT) {
+            let lifetimes = self.parse_lifetimes();
+            self.expect_gt();
 
-                let inputs = if self.eat(&token::OROR) {
-                    Vec::new()
-                } else {
-                    self.expect_or();
-                    let inputs = self.parse_seq_to_before_or(
-                        &token::COMMA,
-                        |p| p.parse_arg_general(false));
-                    self.expect_or();
-                    inputs
-                };
+            lifetimes
+        } else {
+            Vec::new()
+        };
 
-                let bounds = self.parse_optional_ty_param_bounds();
+        let inputs = if self.eat(&token::OROR) {
+            Vec::new()
+        } else {
+            self.expect_or();
+            let inputs = self.parse_seq_to_before_or(
+                &token::COMMA,
+                |p| p.parse_arg_general(false));
+            self.expect_or();
+            inputs
+        };
 
-                let (return_style, output) = self.parse_ret_ty();
-                let decl = P(FnDecl {
-                    inputs: inputs,
-                    output: output,
-                    cf: return_style,
-                    variadic: false
-                });
+        let (new_region, bounds) = self.parse_optional_ty_param_bounds(true);
 
-                (BorrowedSigil, decl, lifetimes, bounds)
-            }
-        };
+        // NOTE: this should be removed after a stage0 snap
+        let region = new_region.or(region);
+
+        let (return_style, output) = self.parse_ret_ty();
+        let decl = P(FnDecl {
+            inputs: inputs,
+            output: output,
+            cf: return_style,
+            variadic: false
+        });
 
-        return TyClosure(@ClosureTy {
-            sigil: sigil,
+        TyClosure(@ClosureTy {
+            sigil: BorrowedSigil,
             region: region,
             purity: purity,
             onceness: onceness,
             bounds: bounds,
             decl: decl,
             lifetimes: lifetimes,
-        });
-
-        fn parse_onceness(this: &mut Parser) -> Onceness {
-            if this.eat_keyword(keywords::Once) {
-                Once
-            } else {
-                Many
-            }
-        }
+        })
     }
 
     pub fn parse_unsafety(&mut self) -> Purity {
@@ -1245,6 +1247,7 @@ impl<'a> Parser<'a> {
                 self.token == token::BINOP(token::OR) ||
                 self.token == token::OROR ||
                 self.token == token::LT ||
+                // NOTE: remove this clause after a stage0 snap
                 Parser::token_is_lifetime(&self.token) {
             // CLOSURE
             //
@@ -1252,9 +1255,7 @@ impl<'a> Parser<'a> {
             // introduce a closure, once procs can have lifetime bounds. We
             // will need to refactor the grammar a little bit at that point.
 
-            let lifetime = self.parse_opt_lifetime();
-            let result = self.parse_ty_closure(None, lifetime);
-            result
+            self.parse_ty_closure()
         } else if self.eat_keyword(keywords::Typeof) {
             // TYPEOF
             // In order to not be ambiguous, the type must be surrounded by parens.
@@ -1288,23 +1289,6 @@ impl<'a> Parser<'a> {
     pub fn parse_box_or_uniq_pointee(&mut self,
                                      sigil: ast::Sigil)
                                      -> Ty_ {
-        // ~'foo fn() or ~fn() are parsed directly as obsolete fn types:
-        match self.token {
-            token::LIFETIME(..) => {
-                let lifetime = self.parse_lifetime();
-                self.obsolete(self.last_span, ObsoleteBoxedClosure);
-                return self.parse_ty_closure(Some(sigil), Some(lifetime));
-            }
-
-            token::IDENT(..) => {
-                if self.token_is_old_style_closure_keyword() {
-                    self.obsolete(self.last_span, ObsoleteBoxedClosure);
-                    return self.parse_ty_closure(Some(sigil), None);
-                }
-            }
-            _ => {}
-        }
-
         // other things are parsed as @/~ + a type.  Note that constructs like
         // ~[] and ~str will be resolved during typeck to slices and so forth,
         // rather than boxed ptrs.  But the special casing of str/vec is not
@@ -1320,11 +1304,6 @@ impl<'a> Parser<'a> {
         // look for `&'lt` or `&'foo ` and interpret `foo` as the region name:
         let opt_lifetime = self.parse_opt_lifetime();
 
-        if self.token_is_old_style_closure_keyword() {
-            self.obsolete(self.last_span, ObsoleteClosureType);
-            return self.parse_ty_closure(Some(BorrowedSigil), opt_lifetime);
-        }
-
         let mt = self.parse_mt();
         return TyRptr(opt_lifetime, mt);
     }
@@ -1540,7 +1519,8 @@ impl<'a> Parser<'a> {
 
         // Next, parse a colon and bounded type parameters, if applicable.
         let bounds = if mode == LifetimeAndTypesAndBounds {
-            self.parse_optional_ty_param_bounds()
+            let (_, bounds) = self.parse_optional_ty_param_bounds(false);
+            bounds
         } else {
             None
         };
@@ -3376,11 +3356,19 @@ impl<'a> Parser<'a> {
     // Returns "Some(Empty)" if there's a colon but nothing after (e.g. "T:")
     // Returns "Some(stuff)" otherwise (e.g. "T:stuff").
     // NB: The None/Some distinction is important for issue #7264.
-    fn parse_optional_ty_param_bounds(&mut self) -> Option<OwnedSlice<TyParamBound>> {
+    //
+    // Note that the `allow_any_lifetime` argument is a hack for now while the
+    // AST doesn't support arbitrary lifetimes in bounds on type parameters. In
+    // the future, this flag should be removed, and the return value of this
+    // function should be Option<~[TyParamBound]>
+    fn parse_optional_ty_param_bounds(&mut self, allow_any_lifetime: bool)
+        -> (Option<ast::Lifetime>, Option<OwnedSlice<TyParamBound>>)
+    {
         if !self.eat(&token::COLON) {
-            return None;
+            return (None, None);
         }
 
+        let mut ret_lifetime = None;
         let mut result = vec!();
         loop {
             match self.token {
@@ -3388,6 +3376,19 @@ impl<'a> Parser<'a> {
                     let lifetime_interned_string = token::get_ident(lifetime);
                     if lifetime_interned_string.equiv(&("static")) {
                         result.push(RegionTyParamBound);
+                        if allow_any_lifetime && ret_lifetime.is_none() {
+                            ret_lifetime = Some(ast::Lifetime {
+                                id: ast::DUMMY_NODE_ID,
+                                span: self.span,
+                                name: lifetime.name
+                            });
+                        }
+                    } else if allow_any_lifetime && ret_lifetime.is_none() {
+                        ret_lifetime = Some(ast::Lifetime {
+                            id: ast::DUMMY_NODE_ID,
+                            span: self.span,
+                            name: lifetime.name
+                        });
                     } else {
                         self.span_err(self.span,
                                       "`'static` is the only permissible region bound here");
@@ -3406,13 +3407,13 @@ impl<'a> Parser<'a> {
             }
         }
 
-        return Some(OwnedSlice::from_vec(result));
+        return (ret_lifetime, Some(OwnedSlice::from_vec(result)));
     }
 
     // matches typaram = IDENT optbounds ( EQ ty )?
     fn parse_ty_param(&mut self) -> TyParam {
         let ident = self.parse_ident();
-        let opt_bounds = self.parse_optional_ty_param_bounds();
+        let (_, opt_bounds) = self.parse_optional_ty_param_bounds(false);
         // For typarams we don't care about the difference b/w "<T>" and "<T:>".
         let bounds = opt_bounds.unwrap_or_default();
 
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index fe969c6fd51..44e95aa9573 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1557,7 +1557,7 @@ impl<'a> State<'a> {
 
         match *opt_bounds {
             None => Ok(()),
-            Some(ref bounds) => self.print_bounds(bounds, true),
+            Some(ref bounds) => self.print_bounds(&None, bounds, true),
         }
     }
 
@@ -1813,11 +1813,24 @@ impl<'a> State<'a> {
         self.maybe_print_comment(decl.output.span.lo)
     }
 
-    pub fn print_bounds(&mut self, bounds: &OwnedSlice<ast::TyParamBound>,
+    pub fn print_bounds(&mut self,
+                        region: &Option<ast::Lifetime>,
+                        bounds: &OwnedSlice<ast::TyParamBound>,
                         print_colon_anyway: bool) -> IoResult<()> {
-        if !bounds.is_empty() {
+        if !bounds.is_empty() || region.is_some() {
             try!(word(&mut self.s, ":"));
             let mut first = true;
+            match *region {
+                Some(ref lt) => {
+                    let token = token::get_name(lt.name);
+                    if token.get() != "static" {
+                        try!(self.nbsp());
+                        first = false;
+                        try!(self.print_lifetime(lt));
+                    }
+                }
+                None => {}
+            }
             for bound in bounds.iter() {
                 try!(self.nbsp());
                 if first {
@@ -1866,7 +1879,7 @@ impl<'a> State<'a> {
                         let idx = idx - generics.lifetimes.len();
                         let param = generics.ty_params.get(idx);
                         try!(s.print_ident(param.ident));
-                        try!(s.print_bounds(&param.bounds, false));
+                        try!(s.print_bounds(&None, &param.bounds, false));
                         match param.default {
                             Some(default) => {
                                 try!(space(&mut s.s));
@@ -2027,15 +2040,11 @@ impl<'a> State<'a> {
             try!(word(&mut self.s, "proc"));
         } else if opt_sigil == Some(ast::BorrowedSigil) {
             try!(self.print_extern_opt_abi(opt_abi));
-            for lifetime in opt_region.iter() {
-                try!(self.print_lifetime(lifetime));
-            }
             try!(self.print_purity(purity));
             try!(self.print_onceness(onceness));
         } else {
             try!(self.print_opt_abi_and_extern_if_nondefault(opt_abi));
             try!(self.print_opt_sigil(opt_sigil));
-            try!(self.print_opt_lifetime(opt_region));
             try!(self.print_purity(purity));
             try!(self.print_onceness(onceness));
             try!(word(&mut self.s, "fn"));
@@ -2049,10 +2058,6 @@ impl<'a> State<'a> {
             _ => ()
         }
 
-        if opt_sigil != Some(ast::BorrowedSigil) {
-            opt_bounds.as_ref().map(|bounds| self.print_bounds(bounds, true));
-        }
-
         match generics { Some(g) => try!(self.print_generics(g)), _ => () }
         try!(zerobreak(&mut self.s));
 
@@ -2066,8 +2071,6 @@ impl<'a> State<'a> {
 
         if opt_sigil == Some(ast::BorrowedSigil) {
             try!(word(&mut self.s, "|"));
-
-            opt_bounds.as_ref().map(|bounds| self.print_bounds(bounds, true));
         } else {
             if decl.variadic {
                 try!(word(&mut self.s, ", ..."));
@@ -2075,6 +2078,10 @@ impl<'a> State<'a> {
             try!(self.pclose());
         }
 
+        opt_bounds.as_ref().map(|bounds| {
+            self.print_bounds(opt_region, bounds, true)
+        });
+
         try!(self.maybe_print_comment(decl.output.span.lo));
 
         match decl.output.node {
diff --git a/src/test/bench/shootout-meteor.rs b/src/test/bench/shootout-meteor.rs
index 45ce1776620..ee1697e52cf 100644
--- a/src/test/bench/shootout-meteor.rs
+++ b/src/test/bench/shootout-meteor.rs
@@ -15,11 +15,11 @@
 
 // returns an infinite iterator of repeated applications of f to x,
 // i.e. [x, f(x), f(f(x)), ...], as haskell iterate function.
-fn iterate<'a, T>(x: T, f: 'a |&T| -> T) -> Iterate<'a, T> {
+fn iterate<'a, T>(x: T, f: |&T|: 'a -> T) -> Iterate<'a, T> {
     Iterate {f: f, next: x}
 }
 struct Iterate<'a, T> {
-    f: 'a |&T| -> T,
+    f: |&T|: 'a -> T,
     next: T
 }
 impl<'a, T> Iterator<T> for Iterate<'a, T> {
diff --git a/src/test/compile-fail/closure-bounds-static-cant-capture-borrowed.rs b/src/test/compile-fail/closure-bounds-static-cant-capture-borrowed.rs
index 1c6d65ba541..9176412cd79 100644
--- a/src/test/compile-fail/closure-bounds-static-cant-capture-borrowed.rs
+++ b/src/test/compile-fail/closure-bounds-static-cant-capture-borrowed.rs
@@ -12,8 +12,8 @@ fn bar(blk: ||:'static) {
 }
 
 fn foo(x: &()) {
-    bar(|| {
-        let _ = x; //~ ERROR does not fulfill `'static`
+    bar(|| { //~ ERROR cannot infer an appropriate lifetime
+        let _ = x;
     })
 }
 
diff --git a/src/test/run-pass/closure-syntax.rs b/src/test/run-pass/closure-syntax.rs
new file mode 100644
index 00000000000..798808a1572
--- /dev/null
+++ b/src/test/run-pass/closure-syntax.rs
@@ -0,0 +1,76 @@
+// 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.
+
+// ignore-pretty #13324
+
+#![allow(dead_code)]
+
+fn foo<T>() {}
+
+trait Bar1 {}
+impl Bar1 for proc() {}
+
+trait Bar2 {}
+impl Bar2 for proc(): Send {}
+
+trait Bar3 {}
+impl<'b> Bar3 for <'a>|&'a int|: 'b + Send -> &'a int {}
+
+trait Bar4 {}
+impl Bar4 for proc<'a>(&'a int) -> &'a int {}
+
+struct Foo<'a> {
+    a: ||: 'a,
+    b: ||: 'static,
+    c: <'b>||: 'a,
+    d: ||: 'a + Share,
+    e: <'b>|int|: 'a + Share -> &'b f32,
+    f: proc(),
+    g: proc(): 'static + Share,
+    h: proc<'b>(int): Share -> &'b f32,
+}
+
+fn f<'a>(a: &'a int, f: <'b>|&'b int| -> &'b int) -> &'a int {
+    f(a)
+}
+
+fn g<'a>(a: &'a int, f: proc<'b>(&'b int) -> &'b int) -> &'a int {
+    f(a)
+}
+
+fn bar<'b>() {
+    foo::<||>();
+    foo::<|| -> ()>();
+    foo::<||:>();
+    foo::<||:'b>();
+    foo::<||:'b + Share>();
+    foo::<||:Share>();
+    foo::< <'a>|int, f32, &'a int|:'b + Share -> &'a int>();
+    foo::<proc()>();
+    foo::<proc() -> ()>();
+    foo::<proc():>();
+    foo::<proc():'static>();
+    foo::<proc():Share>();
+    foo::<proc<'a>(int, f32, &'a int):'static + Share -> &'a int>();
+
+    // issue #11209
+    let _: 'b ||; // for comparison
+    let _: <'a> ||;
+
+    let _: Option<||:'b>;
+    // let _: Option<<'a>||>;
+    let _: Option< <'a>||>;
+
+    // issue #11210
+    let _: 'static ||;
+}
+
+pub fn main() {
+}
diff --git a/src/test/run-pass/const-fn-val.rs b/src/test/run-pass/const-fn-val.rs
index 18638ab6877..57e37aaf393 100644
--- a/src/test/run-pass/const-fn-val.rs
+++ b/src/test/run-pass/const-fn-val.rs
@@ -12,7 +12,7 @@ fn foo() -> int {
     return 0xca7f000d;
 }
 
-struct Bar<'a> { f: 'a || -> int }
+struct Bar<'a> { f: ||: 'a -> int }
 
 static mut b : Bar<'static> = Bar { f: foo };
 
diff --git a/src/test/run-pass/const-vec-of-fns.rs b/src/test/run-pass/const-vec-of-fns.rs
index 9a93fcb5f89..1f5c1a556a9 100644
--- a/src/test/run-pass/const-vec-of-fns.rs
+++ b/src/test/run-pass/const-vec-of-fns.rs
@@ -17,7 +17,7 @@
 
 fn f() { }
 static bare_fns: &'static [fn()] = &[f, f];
-struct S<'a>('a ||);
+struct S<'a>(||:'a);
 static mut closures: &'static [S<'static>] = &[S(f), S(f)];
 
 pub fn main() {
diff --git a/src/test/run-pass/expr-block-fn.rs b/src/test/run-pass/expr-block-fn.rs
index 9ca41c56dc9..3a6cd61fa09 100644
--- a/src/test/run-pass/expr-block-fn.rs
+++ b/src/test/run-pass/expr-block-fn.rs
@@ -11,7 +11,7 @@
 
 
 fn test_fn() {
-    type t = 'static || -> int;
+    type t = ||: 'static -> int;
     fn ten() -> int { return 10; }
     let rs: t = ten;
     assert!((rs() == 10));
diff --git a/src/test/run-pass/expr-block-generic-box1.rs b/src/test/run-pass/expr-block-generic-box1.rs
index eaead09a2f7..513dbf2eba8 100644
--- a/src/test/run-pass/expr-block-generic-box1.rs
+++ b/src/test/run-pass/expr-block-generic-box1.rs
@@ -10,7 +10,7 @@
 
 #[feature(managed_boxes)];
 
-type compare<T> = 'static |@T, @T| -> bool;
+type compare<T> = |@T, @T|: 'static -> bool;
 
 fn test_generic<T>(expected: @T, eq: compare<T>) {
     let actual: @T = { expected };
diff --git a/src/test/run-pass/expr-block-generic-box2.rs b/src/test/run-pass/expr-block-generic-box2.rs
index 9727f41d144..5eb3f36ce1b 100644
--- a/src/test/run-pass/expr-block-generic-box2.rs
+++ b/src/test/run-pass/expr-block-generic-box2.rs
@@ -12,7 +12,7 @@
 
 // ignore-fast
 
-type compare<'a, T> = 'a |T, T| -> bool;
+type compare<'a, T> = |T, T|: 'a -> bool;
 
 fn test_generic<T:Clone>(expected: T, eq: compare<T>) {
     let actual: T = { expected.clone() };
diff --git a/src/test/run-pass/expr-block-generic-unique1.rs b/src/test/run-pass/expr-block-generic-unique1.rs
index b3fbd8c7658..95f3ff62d26 100644
--- a/src/test/run-pass/expr-block-generic-unique1.rs
+++ b/src/test/run-pass/expr-block-generic-unique1.rs
@@ -10,7 +10,7 @@
 
 
 
-type compare<'a, T> = 'a |~T, ~T| -> bool;
+type compare<'a, T> = |~T, ~T|: 'a -> bool;
 
 fn test_generic<T:Clone>(expected: ~T, eq: compare<T>) {
     let actual: ~T = { expected.clone() };
diff --git a/src/test/run-pass/expr-block-generic-unique2.rs b/src/test/run-pass/expr-block-generic-unique2.rs
index 787f50c1b03..85a1d137d21 100644
--- a/src/test/run-pass/expr-block-generic-unique2.rs
+++ b/src/test/run-pass/expr-block-generic-unique2.rs
@@ -10,7 +10,7 @@
 
 // ignore-fast
 
-type compare<'a, T> = 'a |T, T| -> bool;
+type compare<'a, T> = |T, T|: 'a -> bool;
 
 fn test_generic<T:Clone>(expected: T, eq: compare<T>) {
     let actual: T = { expected.clone() };
diff --git a/src/test/run-pass/expr-block-generic.rs b/src/test/run-pass/expr-block-generic.rs
index 3a1a79aa38e..4c8a32ce3cb 100644
--- a/src/test/run-pass/expr-block-generic.rs
+++ b/src/test/run-pass/expr-block-generic.rs
@@ -12,7 +12,7 @@
 // ignore-fast
 
 // Tests for standalone blocks as expressions with dynamic type sizes
-type compare<'a, T> = 'a |T, T| -> bool;
+type compare<'a, T> = |T, T|: 'a -> bool;
 
 fn test_generic<T:Clone>(expected: T, eq: compare<T>) {
     let actual: T = { expected.clone() };
diff --git a/src/test/run-pass/expr-if-generic-box1.rs b/src/test/run-pass/expr-if-generic-box1.rs
index cba01fbd8dd..78f42120ab7 100644
--- a/src/test/run-pass/expr-if-generic-box1.rs
+++ b/src/test/run-pass/expr-if-generic-box1.rs
@@ -10,7 +10,7 @@
 
 #[feature(managed_boxes)];
 
-type compare<T> = 'static |@T, @T| -> bool;
+type compare<T> = |@T, @T|: 'static -> bool;
 
 fn test_generic<T>(expected: @T, not_expected: @T, eq: compare<T>) {
     let actual: @T = if true { expected } else { not_expected };
diff --git a/src/test/run-pass/expr-if-generic-box2.rs b/src/test/run-pass/expr-if-generic-box2.rs
index eba30fa9bca..8b78aabd860 100644
--- a/src/test/run-pass/expr-if-generic-box2.rs
+++ b/src/test/run-pass/expr-if-generic-box2.rs
@@ -12,7 +12,7 @@
 
 // ignore-fast
 
-type compare<T> = 'static |T, T| -> bool;
+type compare<T> = |T, T|: 'static -> bool;
 
 fn test_generic<T:Clone>(expected: T, not_expected: T, eq: compare<T>) {
     let actual: T = if true { expected.clone() } else { not_expected };
diff --git a/src/test/run-pass/expr-if-generic.rs b/src/test/run-pass/expr-if-generic.rs
index 7e58d466b90..f250db1f692 100644
--- a/src/test/run-pass/expr-if-generic.rs
+++ b/src/test/run-pass/expr-if-generic.rs
@@ -11,7 +11,7 @@
 // ignore-fast
 
 // Tests for if as expressions with dynamic type sizes
-type compare<T> = 'static |T, T| -> bool;
+type compare<T> = |T, T|: 'static -> bool;
 
 fn test_generic<T:Clone>(expected: T, not_expected: T, eq: compare<T>) {
     let actual: T = if true { expected.clone() } else { not_expected };
diff --git a/src/test/run-pass/expr-match-generic-box1.rs b/src/test/run-pass/expr-match-generic-box1.rs
index 82e80e7da7d..287e0ea349d 100644
--- a/src/test/run-pass/expr-match-generic-box1.rs
+++ b/src/test/run-pass/expr-match-generic-box1.rs
@@ -10,7 +10,7 @@
 
 #[feature(managed_boxes)];
 
-type compare<T> = 'static |@T, @T| -> bool;
+type compare<T> = |@T, @T|: 'static -> bool;
 
 fn test_generic<T>(expected: @T, eq: compare<T>) {
     let actual: @T = match true { true => { expected }, _ => fail!() };
diff --git a/src/test/run-pass/expr-match-generic-box2.rs b/src/test/run-pass/expr-match-generic-box2.rs
index 1ad9db46257..01b46528c7b 100644
--- a/src/test/run-pass/expr-match-generic-box2.rs
+++ b/src/test/run-pass/expr-match-generic-box2.rs
@@ -12,7 +12,7 @@
 
 // ignore-fast
 
-type compare<T> = 'static |T, T| -> bool;
+type compare<T> = |T, T|: 'static -> bool;
 
 fn test_generic<T:Clone>(expected: T, eq: compare<T>) {
     let actual: T = match true { true => { expected.clone() }, _ => fail!("wat") };
diff --git a/src/test/run-pass/expr-match-generic-unique1.rs b/src/test/run-pass/expr-match-generic-unique1.rs
index af9022ed322..991a1f449f1 100644
--- a/src/test/run-pass/expr-match-generic-unique1.rs
+++ b/src/test/run-pass/expr-match-generic-unique1.rs
@@ -10,7 +10,7 @@
 
 
 
-type compare<T> = 'static |~T, ~T| -> bool;
+type compare<T> = |~T, ~T|: 'static -> bool;
 
 fn test_generic<T:Clone>(expected: ~T, eq: compare<T>) {
     let actual: ~T = match true {
diff --git a/src/test/run-pass/expr-match-generic-unique2.rs b/src/test/run-pass/expr-match-generic-unique2.rs
index 97848471590..6c1a6d22de7 100644
--- a/src/test/run-pass/expr-match-generic-unique2.rs
+++ b/src/test/run-pass/expr-match-generic-unique2.rs
@@ -10,7 +10,7 @@
 
 // ignore-fast
 
-type compare<'a, T> = 'a |T, T| -> bool;
+type compare<'a, T> = |T, T|: 'a -> bool;
 
 fn test_generic<T:Clone>(expected: T, eq: compare<T>) {
     let actual: T = match true {
diff --git a/src/test/run-pass/fn-coerce-field.rs b/src/test/run-pass/fn-coerce-field.rs
index e49b1e9ed61..6b7490ba673 100644
--- a/src/test/run-pass/fn-coerce-field.rs
+++ b/src/test/run-pass/fn-coerce-field.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 struct r<'a> {
-    field: 'a ||
+    field: ||: 'a,
 }
 
 pub fn main() {
diff --git a/src/test/run-pass/hashmap-memory.rs b/src/test/run-pass/hashmap-memory.rs
index a57cf3e59ae..3ff7fea95f1 100644
--- a/src/test/run-pass/hashmap-memory.rs
+++ b/src/test/run-pass/hashmap-memory.rs
@@ -28,7 +28,7 @@ mod map_reduce {
     use std::str;
     use std::task;
 
-    pub type putter<'a> = 'a |~str, ~str|;
+    pub type putter<'a> = |~str, ~str|: 'a;
 
     pub type mapper = extern fn(~str, putter);
 
diff --git a/src/test/run-pass/issue-10767.rs b/src/test/run-pass/issue-10767.rs
new file mode 100644
index 00000000000..3254f5bc35f
--- /dev/null
+++ b/src/test/run-pass/issue-10767.rs
@@ -0,0 +1,15 @@
+// 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.
+
+pub fn main() {
+    fn f() {
+    };
+    let _: ~fn() = ~f;
+}
diff --git a/src/test/run-pass/issue-3052.rs b/src/test/run-pass/issue-3052.rs
index 5bd41e8bf3b..00e6b5ca8fe 100644
--- a/src/test/run-pass/issue-3052.rs
+++ b/src/test/run-pass/issue-3052.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 
-type Connection = 'static |Vec<u8> |;
+type Connection = |Vec<u8>|: 'static;
 
 fn f() -> Option<Connection> {
     let mock_connection: Connection = |_| {};
diff --git a/src/test/run-pass/issue-3904.rs b/src/test/run-pass/issue-3904.rs
index fe6521b4df9..81a7d073c4c 100644
--- a/src/test/run-pass/issue-3904.rs
+++ b/src/test/run-pass/issue-3904.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-type ErrPrinter<'a> = 'a |&str, &str|;
+type ErrPrinter<'a> = |&str, &str|: 'a;
 
 fn example_err(prog: &str, arg: &str) {
     println!("{}: {}", prog, arg)
diff --git a/src/test/run-pass/issue-6157.rs b/src/test/run-pass/issue-6157.rs
index 50e5f97034a..5a78aed5826 100644
--- a/src/test/run-pass/issue-6157.rs
+++ b/src/test/run-pass/issue-6157.rs
@@ -10,7 +10,7 @@
 
 pub trait OpInt<'a> { fn call<'a>(&'a self, int, int) -> int; }
 
-impl<'a> OpInt<'a> for 'a |int, int| -> int {
+impl<'a> OpInt<'a> for |int, int|: 'a -> int {
     fn call(&self, a:int, b:int) -> int {
         (*self)(a, b)
     }
diff --git a/src/test/run-pass/once-move-out-on-stack.rs b/src/test/run-pass/once-move-out-on-stack.rs
index f14827c7245..995fc091113 100644
--- a/src/test/run-pass/once-move-out-on-stack.rs
+++ b/src/test/run-pass/once-move-out-on-stack.rs
@@ -12,7 +12,7 @@
 
 // ignore-fast
 
-#[feature(once_fns)];
+#![feature(once_fns)]
 extern crate sync;
 use sync::Arc;
 
diff --git a/src/test/run-pass/regions-copy-closure.rs b/src/test/run-pass/regions-copy-closure.rs
index 55cb5c62684..ac40fb885a1 100644
--- a/src/test/run-pass/regions-copy-closure.rs
+++ b/src/test/run-pass/regions-copy-closure.rs
@@ -9,10 +9,10 @@
 // except according to those terms.
 
 struct closure_box<'a> {
-    cl: 'a ||,
+    cl: ||: 'a,
 }
 
-fn box_it<'r>(x: 'r ||) -> closure_box<'r> {
+fn box_it<'r>(x: ||: 'r) -> closure_box<'r> {
     closure_box {cl: x}
 }
 
diff --git a/src/test/run-pass/regions-dependent-autofn.rs b/src/test/run-pass/regions-dependent-autofn.rs
index b50930dd294..e9cd7fb4973 100644
--- a/src/test/run-pass/regions-dependent-autofn.rs
+++ b/src/test/run-pass/regions-dependent-autofn.rs
@@ -11,9 +11,9 @@
 // Test lifetimes are linked properly when we autoslice a vector.
 // Issue #3148.
 
-fn subslice<'r>(v: 'r ||) -> 'r || { v }
+fn subslice<'r>(v: ||: 'r) -> ||: 'r { v }
 
-fn both<'r>(v: 'r ||) -> 'r || {
+fn both<'r>(v: ||: 'r) -> ||: 'r {
     subslice(subslice(v))
 }
 
diff --git a/src/test/run-pass/regions-static-closure.rs b/src/test/run-pass/regions-static-closure.rs
index ff4b43cb6b5..d91c11dde10 100644
--- a/src/test/run-pass/regions-static-closure.rs
+++ b/src/test/run-pass/regions-static-closure.rs
@@ -9,10 +9,10 @@
 // except according to those terms.
 
 struct closure_box<'a> {
-    cl: 'a ||,
+    cl: ||: 'a,
 }
 
-fn box_it<'r>(x: 'r ||) -> closure_box<'r> {
+fn box_it<'r>(x: ||: 'r) -> closure_box<'r> {
     closure_box {cl: x}
 }