diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2014-08-05 22:59:24 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2014-08-07 07:23:59 -0400 |
| commit | fcab98038c3b466d9ecd00b0f27e9c748e7acbde (patch) | |
| tree | 345deba110cec778935c4d2fa1b7f9150c90f7c3 /src/libsyntax/parse | |
| parent | 1a53c001170f8084ce850498d5e8f22b5e7da72c (diff) | |
| download | rust-fcab98038c3b466d9ecd00b0f27e9c748e7acbde.tar.gz rust-fcab98038c3b466d9ecd00b0f27e9c748e7acbde.zip | |
Temporary bootstrapping hack: introduce syntax for r egion bounds like `'b:'a`,
meaning `'b outlives 'a`. Syntax currently does nothing but is needed for full fix to #5763. To use this syntax, the issue_5763_bootstrap feature guard is required.
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 91 |
1 files changed, 62 insertions, 29 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index c9fba355c4d..7ea000d3aac 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1053,10 +1053,10 @@ impl<'a> Parser<'a> { */ - let lifetimes = if self.eat(&token::LT) { - let lifetimes = self.parse_lifetimes(); + let lifetime_defs = if self.eat(&token::LT) { + let lifetime_defs = self.parse_lifetime_defs(); self.expect_gt(); - lifetimes + lifetime_defs } else { Vec::new() }; @@ -1082,7 +1082,7 @@ impl<'a> Parser<'a> { onceness: Once, bounds: bounds, decl: decl, - lifetimes: lifetimes, + lifetimes: lifetime_defs, }) } @@ -1096,7 +1096,7 @@ impl<'a> Parser<'a> { | | | | | Return type | | | | Closure bounds | | | Argument types - | | Lifetimes + | | Lifetime defs | Once-ness (a.k.a., affine) Function Style @@ -1105,11 +1105,11 @@ impl<'a> Parser<'a> { let fn_style = self.parse_unsafety(); let onceness = if self.eat_keyword(keywords::Once) {Once} else {Many}; - let lifetimes = if self.eat(&token::LT) { - let lifetimes = self.parse_lifetimes(); + let lifetime_defs = if self.eat(&token::LT) { + let lifetime_defs = self.parse_lifetime_defs(); self.expect_gt(); - lifetimes + lifetime_defs } else { Vec::new() }; @@ -1164,7 +1164,7 @@ impl<'a> Parser<'a> { onceness: onceness, bounds: bounds, decl: decl, - lifetimes: lifetimes, + lifetimes: lifetime_defs, }, region) } } @@ -1179,7 +1179,7 @@ impl<'a> Parser<'a> { /// Parse a function type (following the 'fn') pub fn parse_ty_fn_decl(&mut self, allow_variadic: bool) - -> (P<FnDecl>, Vec<ast::Lifetime>) { + -> (P<FnDecl>, Vec<ast::LifetimeDef>) { /* (fn) <'lt> (S) -> T @@ -1187,13 +1187,13 @@ impl<'a> Parser<'a> { | | | | | Return type | Argument types - Lifetimes + Lifetime_defs */ - let lifetimes = if self.eat(&token::LT) { - let lifetimes = self.parse_lifetimes(); + let lifetime_defs = if self.eat(&token::LT) { + let lifetime_defs = self.parse_lifetime_defs(); self.expect_gt(); - lifetimes + lifetime_defs } else { Vec::new() }; @@ -1206,7 +1206,7 @@ impl<'a> Parser<'a> { cf: ret_style, variadic: variadic }); - (decl, lifetimes) + (decl, lifetime_defs) } /// Parse the methods in a trait declaration @@ -1770,31 +1770,34 @@ impl<'a> Parser<'a> { } } - // matches lifetimes = ( lifetime ) | ( lifetime , lifetimes ) - // actually, it matches the empty one too, but putting that in there - // messes up the grammar.... - pub fn parse_lifetimes(&mut self) -> Vec<ast::Lifetime> { + pub fn parse_lifetime_defs(&mut self) -> Vec<ast::LifetimeDef> { /*! - * - * 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>`. + * Parses `lifetime_defs = [ lifetime_defs { ',' lifetime_defs } ]` + * where `lifetime_def = lifetime [':' lifetimes]` */ let mut res = Vec::new(); loop { match self.token { token::LIFETIME(_) => { - res.push(self.parse_lifetime()); + let lifetime = self.parse_lifetime(); + let bounds = + if self.eat(&token::COLON) { + self.parse_lifetimes(token::BINOP(token::PLUS)) + } else { + Vec::new() + }; + res.push(ast::LifetimeDef { lifetime: lifetime, + bounds: bounds }); } + _ => { return res; } } match self.token { - token::COMMA => { self.bump();} + token::COMMA => { self.bump(); } token::GT => { return res; } token::BINOP(token::SHR) => { return res; } _ => { @@ -1807,6 +1810,36 @@ impl<'a> Parser<'a> { } } + // matches lifetimes = ( lifetime ) | ( lifetime , lifetimes ) + // actually, it matches the empty one too, but putting that in there + // messes up the grammar.... + pub fn parse_lifetimes(&mut self, sep: token::Token) -> Vec<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 = Vec::new(); + loop { + match self.token { + token::LIFETIME(_) => { + res.push(self.parse_lifetime()); + } + _ => { + return res; + } + } + + if self.token != sep { + return res; + } + + self.bump(); + } + } + pub fn token_is_mutability(tok: &token::Token) -> bool { token::is_keyword(keywords::Mut, tok) || token::is_keyword(keywords::Const, tok) @@ -3664,7 +3697,7 @@ impl<'a> Parser<'a> { /// where typaramseq = ( typaram ) | ( typaram , typaramseq ) pub fn parse_generics(&mut self) -> ast::Generics { if self.eat(&token::LT) { - let lifetimes = self.parse_lifetimes(); + let lifetime_defs = self.parse_lifetime_defs(); let mut seen_default = false; let ty_params = self.parse_seq_to_gt(Some(token::COMMA), |p| { p.forbid_lifetime(); @@ -3678,14 +3711,14 @@ impl<'a> Parser<'a> { } ty_param }); - ast::Generics { lifetimes: lifetimes, ty_params: ty_params } + ast::Generics { lifetimes: lifetime_defs, ty_params: ty_params } } else { ast_util::empty_generics() } } fn parse_generic_values_after_lt(&mut self) -> (Vec<ast::Lifetime>, Vec<P<Ty>> ) { - let lifetimes = self.parse_lifetimes(); + let lifetimes = self.parse_lifetimes(token::COMMA); let result = self.parse_seq_to_gt( Some(token::COMMA), |p| { |
