Skip to content

Commit 304d82a

Browse files
committed
syntax: Tweak parsing lifetime bounds on closures
In summary these are some example transitions this change makes: 'a || => ||: 'a proc:Send() => proc():Send The intended syntax for closures is to put the lifetime bound not at the front but rather in the list of bounds. Currently there is no official support in the AST for bounds that are not 'static, so this case is currently specially handled in the parser to desugar to what the AST is expecting. Additionally, this moves the bounds on procedures to the correct position, which is after the argument list. The current grammar for closures and procedures is: procedure := 'proc' [ '<' lifetime-list '>' ] '(' arg-list ')' [ ':' bound-list ] [ '->' type ] closure := [ 'unsafe' ] ['<' 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 This does not currently handle the << ambiguity in `Option<<'a>||>`, I am deferring that to a later patch. Additionally, this removes the support for the obsolete syntaxes of ~fn and &fn. Closes rust-lang#10553 Closes rust-lang#10767 Closes rust-lang#11209 Closes rust-lang#11210 Closes rust-lang#11211
1 parent e63346b commit 304d82a

File tree

7 files changed

+242
-127
lines changed

7 files changed

+242
-127
lines changed

src/doc/rust.md

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3327,8 +3327,21 @@ x = bo(5,7);
33273327

33283328
### Closure types
33293329

3330-
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 `||`.
3330+
~~~~ {.notrust .ebnf .notation}
3331+
closure_type := [ 'unsafe' ] [ '<' lifetime-list '>' ] '|' arg-list '|'
3332+
[ ':' bound-list ] [ '->' type ]
3333+
procedure_type := 'proc' [ '<' lifetime-list '>' ] '(' arg-list ')'
3334+
[ ':' bound-list ] [ '->' type ]
3335+
lifetime-list := lifetime | lifetime ',' lifetime-list
3336+
arg-list := ident ':' type | ident ':' type ',' arg-list
3337+
bound-list := bound | bound '+' bound-list
3338+
bound := path | lifetime
3339+
~~~~
33313340

3341+
The type of a closure mapping an input of type `A` to an output of type `B` is
3342+
`|A| -> B`. A closure with no arguments or return values has type `||`.
3343+
Similarly, a procedure mapping `A` to `B` is `proc(A) -> B` and a no-argument
3344+
and no-return value closure has type `proc()`.
33323345

33333346
An example of creating and calling a closure:
33343347

@@ -3351,6 +3364,30 @@ call_closure(closure_no_args, closure_args);
33513364

33523365
```
33533366

3367+
Unlike closures, procedures may only be invoked once, but own their
3368+
environment, and are allowed to move out of their environment. Procedures are
3369+
allocated on the heap (unlike closures). An example of creating and calling a
3370+
procedure:
3371+
3372+
```rust
3373+
let string = ~"Hello";
3374+
3375+
// Creates a new procedure, passing it to the `spawn` function.
3376+
spawn(proc() {
3377+
println!("{} world!", string);
3378+
})
3379+
3380+
// the variable `string` has been moved into the previous procedure, so it is
3381+
// no longer usable.
3382+
3383+
3384+
// Create an invoke a procedure. Note that the procedure is *moved* when
3385+
// invoked, so it cannot be invoked again.
3386+
let f = proc(n) { n + 22 };
3387+
println!("answer: {}", f(20));
3388+
3389+
```
3390+
33543391
### Object types
33553392

33563393
Every trait item (see [traits](#traits)) defines a type with the same name as the trait.

src/libsyntax/parse/obsolete.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ pub enum ObsoleteSyntax {
3636
ObsoleteEnumWildcard,
3737
ObsoleteStructWildcard,
3838
ObsoleteVecDotDotWildcard,
39-
ObsoleteBoxedClosure,
40-
ObsoleteClosureType,
4139
ObsoleteMultipleImport,
4240
ObsoleteManagedPattern,
4341
ObsoleteManagedString,
@@ -111,16 +109,6 @@ impl<'a> ParserObsoleteMethods for Parser<'a> {
111109
"vec slice wildcard",
112110
"use `..` instead of `.._` for matching slices"
113111
),
114-
ObsoleteBoxedClosure => (
115-
"managed or owned closure",
116-
"managed closures have been removed and owned closures are \
117-
now written `proc()`"
118-
),
119-
ObsoleteClosureType => (
120-
"closure type",
121-
"closures are now written `|A| -> B` rather than `&fn(A) -> \
122-
B`."
123-
),
124112
ObsoleteMultipleImport => (
125113
"multiple imports",
126114
"only one import is allowed per `use` statement"

0 commit comments

Comments
 (0)