diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2013-02-11 16:33:31 -0800 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2013-02-16 08:01:10 -0500 |
| commit | c7f85003a345826b17801d473303d0c545d0e8d2 (patch) | |
| tree | 34a6c740c8eebc2d77b7e29a80b9b2737131ae55 /src/libsyntax/parse | |
| parent | 9ad8a1f46566ddcd705cc918863cee2946d8b946 (diff) | |
| download | rust-c7f85003a345826b17801d473303d0c545d0e8d2.tar.gz rust-c7f85003a345826b17801d473303d0c545d0e8d2.zip | |
Permit lifetimes to appear in type parameter lists and after `&`. Lifetimes in
type parameter lists are currently ignored, but `&'a T` is equivalent to `&a/T`.
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 110 |
1 files changed, 99 insertions, 11 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 15258a6bbee..fce0948e711 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -624,8 +624,13 @@ pub impl Parser { sigil: ast::Sigil, ctor: &fn(+v: mt) -> ty_) -> ty_ { - // @foo/fn() or @fn() are parsed directly as fn types: + // @'foo fn() or @foo/fn() or @fn() are parsed directly as fn types: match copy self.token { + token::LIFETIME(rname) => { + self.bump(); + return self.parse_ty_closure(Some(sigil), Some(rname)); + } + token::IDENT(rname, _) => { if self.look_ahead(1u) == token::BINOP(token::SLASH) && self.token_is_closure_keyword(self.look_ahead(2u)) @@ -648,8 +653,13 @@ pub impl Parser { } fn parse_borrowed_pointee() -> ty_ { - // look for `&foo/` and interpret `foo` as the region name: - let rname = match copy self.token { + // look for `&'lt` or `&foo/` and interpret `foo` as the region name: + let rname = match self.token { + token::LIFETIME(sid) => { + self.bump(); + Some(sid) + } + token::IDENT(sid, _) => { if self.look_ahead(1u) == token::BINOP(token::SLASH) { self.bump(); self.bump(); @@ -658,6 +668,7 @@ pub impl Parser { None } } + _ => { None } }; @@ -890,22 +901,95 @@ pub impl Parser { } }; - // Parse any type parameters which may appear: + // Parse any lifetime or type parameters which may appear: let tps = { - if self.token == token::LT { - self.parse_seq_lt_gt(Some(token::COMMA), - |p| p.parse_ty(false)) + if !self.eat(token::LT) { + ~[] } else { - codemap::spanned {node: ~[], span: path.span} + // First consume lifetimes. + let _lifetimes = self.parse_lifetimes(); + let result = self.parse_seq_to_gt( + Some(token::COMMA), + |p| p.parse_ty(false)); + result } }; - @ast::path { span: mk_sp(lo, tps.span.hi), + let hi = self.span.lo; + + @ast::path { span: mk_sp(lo, hi), rp: rp, - types: tps.node, + types: tps, .. *path } } + fn parse_opt_lifetime() -> Option<ast::Lifetime> { + /*! + * + * Parses 0 or 1 lifetime. + */ + + match self.token { + token::LIFETIME(_) => { + Some(self.parse_lifetime()) + } + _ => { + None + } + } + } + + fn parse_lifetime() -> ast::Lifetime { + /*! + * + * Parses a single lifetime. + */ + + match self.token { + token::LIFETIME(i) => { + self.bump(); + return ast::Lifetime { + id: self.get_id(), + span: self.span, + ident: i + }; + } + _ => { + self.fatal(fmt!("Expected a lifetime name")); + } + } + } + + fn parse_lifetimes() -> ~[ast::Lifetime] { + /*! + * + * Parses zero or more comma separated lifetimes. + * Expects each lifetime to be followed by either + * a comma or `>`. Used when parsing type parameter + * lists, where we expect something like `<'a, 'b, T>`. + */ + + let mut res = ~[]; + loop { + match self.token { + token::LIFETIME(_) => { + res.push(self.parse_lifetime()); + } + _ => { + return res; + } + } + + match self.token { + token::COMMA => { self.bump();} + token::GT => { return res; } + _ => { + self.fatal(~"expected `,` or `>` after lifetime name"); + } + } + } + } + fn parse_mutability() -> mutability { if self.eat_keyword(~"mut") { m_mutbl @@ -1424,6 +1508,7 @@ pub impl Parser { } token::AND => { self.bump(); + let _lt = self.parse_opt_lifetime(); let m = self.parse_mutability(); let e = self.parse_prefix_expr(); hi = e.span.hi; @@ -2574,7 +2659,10 @@ pub impl Parser { fn parse_ty_params() -> ~[ty_param] { if self.eat(token::LT) { - self.parse_seq_to_gt(Some(token::COMMA), |p| p.parse_ty_param()) + let _lifetimes = self.parse_lifetimes(); + self.parse_seq_to_gt( + Some(token::COMMA), + |p| p.parse_ty_param()) } else { ~[] } } |
