diff options
| author | P1start <rewi-github@whanau.org> | 2014-12-23 13:13:49 +1300 |
|---|---|---|
| committer | P1start <rewi-github@whanau.org> | 2014-12-25 18:58:47 +1300 |
| commit | d9769ec3834b62318da892925dc24c8883bb1635 (patch) | |
| tree | 0455c075f4c1d37151c726fbbf6621e55448c525 /src/libsyntax/parse/parser.rs | |
| parent | 7e11b22713aebd28ceaaa2ecef937c9b9d247c2f (diff) | |
| download | rust-d9769ec3834b62318da892925dc24c8883bb1635.tar.gz rust-d9769ec3834b62318da892925dc24c8883bb1635.zip | |
Parse fully-qualified associated types in generics without whitespace
This breaks code that looks like this:
let x = foo as bar << 13;
Change such code to look like this:
let x = (foo as bar) << 13;
Closes #17362.
[breaking-change]
Diffstat (limited to 'src/libsyntax/parse/parser.rs')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 44 |
1 files changed, 10 insertions, 34 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 94b61ba56d2..b3dc8c3a61a 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -669,45 +669,22 @@ impl<'a> Parser<'a> { /// `<` and continue. If a `<` is not seen, return false. /// /// This is meant to be used when parsing generics on a path to get the - /// starting token. The `force` parameter is used to forcefully break up a - /// `<<` token. If `force` is false, then `<<` is only broken when a lifetime - /// shows up next. For example, consider the expression: - /// - /// foo as bar << test - /// - /// The parser needs to know if `bar <<` is the start of a generic path or if - /// it's a left-shift token. If `test` were a lifetime, then it's impossible - /// for the token to be a left-shift, but if it's not a lifetime, then it's - /// considered a left-shift. - /// - /// The reason for this is that the only current ambiguity with `<<` is when - /// parsing closure types: - /// - /// foo::<<'a> ||>(); - /// impl Foo<<'a> ||>() { ... } - fn eat_lt(&mut self, force: bool) -> bool { + /// starting token. + fn eat_lt(&mut self) -> bool { match self.token { token::Lt => { self.bump(); true } token::BinOp(token::Shl) => { - let next_lifetime = self.look_ahead(1, |t| match *t { - token::Lifetime(..) => true, - _ => false, - }); - if force || next_lifetime { - let span = self.span; - let lo = span.lo + BytePos(1); - self.replace_token(token::Lt, lo, span.hi); - true - } else { - false - } + let span = self.span; + let lo = span.lo + BytePos(1); + self.replace_token(token::Lt, lo, span.hi); + true } _ => false, } } fn expect_lt(&mut self) { - if !self.eat_lt(true) { + if !self.eat_lt() { let found_token = self.this_token_to_string(); let token_str = Parser::token_to_string(&token::Lt); self.fatal(format!("expected `{}`, found `{}`", @@ -1582,9 +1559,8 @@ impl<'a> Parser<'a> { TyTypeof(e) } else if self.eat_keyword(keywords::Proc) { self.parse_proc_type(Vec::new()) - } else if self.check(&token::Lt) { + } else if self.eat_lt() { // QUALIFIED PATH `<TYPE as TRAIT_REF>::item` - self.bump(); let self_type = self.parse_ty_sum(); self.expect_keyword(keywords::As); let trait_ref = self.parse_trait_ref(); @@ -1870,7 +1846,7 @@ impl<'a> Parser<'a> { let identifier = self.parse_ident(); // Parse types, optionally. - let parameters = if self.eat_lt(false) { + let parameters = if self.eat_lt() { let (lifetimes, types, bindings) = self.parse_generic_values_after_lt(); ast::AngleBracketedParameters(ast::AngleBracketedParameterData { @@ -1931,7 +1907,7 @@ impl<'a> Parser<'a> { } // Check for a type segment. - if self.eat_lt(false) { + if self.eat_lt() { // Consumed `a::b::<`, go look for types let (lifetimes, types, bindings) = self.parse_generic_values_after_lt(); segments.push(ast::PathSegment { |
