1
Fork 0

Parse (and discard) lifetime declarations on function types

This commit is contained in:
Niko Matsakis 2013-02-12 15:01:29 -08:00
parent ad8b437ada
commit 6c728e32c0
3 changed files with 43 additions and 31 deletions

View file

@ -307,12 +307,12 @@ pub impl Parser {
{ {
/* /*
extern "ABI" [pure|unsafe] fn (S) -> T extern "ABI" [pure|unsafe] fn <'lt> (S) -> T
^~~~^ ^~~~~~~~~~~~^ ^~^ ^ ^~~~^ ^~~~~~~~~~~~^ ^~~~^ ^~^ ^
| | | | | | | | |
| | | Return type | | | | Return type
| | Argument types | | | Argument types
| | | | Lifetimes
| | | |
| Purity | Purity
ABI ABI
@ -333,12 +333,12 @@ pub impl Parser {
{ {
/* /*
(&|~|@) [r/] [pure|unsafe] [once] fn (S) -> T (&|~|@) [r/] [pure|unsafe] [once] fn <'lt> (S) -> T
^~~~~~^ ^~~^ ^~~~~~~~~~~~^ ^~~~~^ ^~^ ^ ^~~~~~^ ^~~^ ^~~~~~~~~~~~^ ^~~~~^ ^~~~^ ^~^ ^
| | | | | | | | | | | | |
| | | | | Return type | | | | | | Return type
| | | | Argument types | | | | | Argument types
| | | | | | | | Lifetimes
| | | Once-ness (a.k.a., affine) | | | Once-ness (a.k.a., affine)
| | Purity | | Purity
| Lifetime bound | Lifetime bound
@ -394,12 +394,24 @@ pub impl Parser {
} }
fn parse_ty_fn_decl() -> fn_decl { fn parse_ty_fn_decl() -> fn_decl {
let inputs = do self.parse_unspanned_seq( /*
token::LPAREN, token::RPAREN,
seq_sep_trailing_disallowed(token::COMMA)) |p| {
p.parse_arg_general(false) (fn) <'lt> (S) -> T
}; ^~~~^ ^~^ ^
| | |
| | Return type
| Argument types
Lifetimes
*/
if self.eat(token::LT) {
let _lifetimes = self.parse_lifetimes();
self.expect(token::GT);
}
let inputs = self.parse_unspanned_seq(
token::LPAREN, token::RPAREN,
seq_sep_trailing_disallowed(token::COMMA),
|p| p.parse_arg_general(false));
let (ret_style, ret_ty) = self.parse_ret_ty(); let (ret_style, ret_ty) = self.parse_ret_ty();
ast::fn_decl { inputs: inputs, output: ret_ty, cf: ret_style } ast::fn_decl { inputs: inputs, output: ret_ty, cf: ret_style }
} }

View file

@ -10,15 +10,15 @@
enum yes0<'lt> { enum yes0<'lt> {
// This will eventually be legal (and in fact the only way): // This will eventually be legal (and in fact the only way):
x3(&'lt uint) //~ ERROR named regions other than `self` are not allowed as part of a type declaration X3(&'lt uint) //~ ERROR named regions other than `self` are not allowed as part of a type declaration
} }
enum yes1 { enum yes1 {
x4(&'self uint) X4(&'self uint)
} }
enum yes2 { enum yes2 {
x5(&'foo uint) //~ ERROR named regions other than `self` are not allowed as part of a type declaration X5(&'foo uint) //~ ERROR named regions other than `self` are not allowed as part of a type declaration
} }
fn main() {} fn main() {}

View file

@ -10,13 +10,13 @@
fn with<T>(t: T, f: fn(T)) { f(t) } fn with<T>(t: T, f: fn(T)) { f(t) }
fn nested(x: &x/int) { // (1) fn nested<'x>(x: &'x int) { // (1)
do with( do with(
fn&(x: &x/int, // Refers to the region `x` at (1) fn&(x: &'x int, // Refers to the region `x` at (1)
y: &y/int, // A fresh region `y` (2) y: &'y int, // A fresh region `y` (2)
z: fn(x: &x/int, // Refers to `x` at (1) z: fn<'z>(x: &'x int, // Refers to `x` at (1)
y: &y/int, // Refers to `y` at (2) y: &'y int, // Refers to `y` at (2)
z: &z/int) -> &z/int) // A fresh region `z` (3) z: &'z int) -> &'z int) // A fresh region `z` (3)
-> &x/int { -> &x/int {
if false { return z(x, y, x); } if false { return z(x, y, x); }
@ -29,13 +29,13 @@ fn nested(x: &x/int) { // (1)
} }
) |foo| { ) |foo| {
let a: &x/int = foo(x, x, |_x, _y, z| z ); let a: &'x int = foo(x, x, |_x, _y, z| z );
let b: &x/int = foo(x, a, |_x, _y, z| z ); let b: &'x int = foo(x, a, |_x, _y, z| z );
let c: &x/int = foo(a, a, |_x, _y, z| z ); let c: &'x int = foo(a, a, |_x, _y, z| z );
let z = 3i; let z = 3i;
let d: &x/int = foo(x, x, |_x, _y, z| z ); let d: &'x int = foo(x, x, |_x, _y, z| z );
let e: &x/int = foo(x, &z, |_x, _y, z| z ); let e: &'x int = foo(x, &z, |_x, _y, z| z );
// This would result in an error, but it is not reported by typeck // This would result in an error, but it is not reported by typeck
// anymore but rather borrowck. Therefore, it doesn't end up // anymore but rather borrowck. Therefore, it doesn't end up