about summary refs log tree commit diff
path: root/src/libsyntax/parse/parser.rs
diff options
context:
space:
mode:
authorP1start <rewi-github@whanau.org>2014-12-23 13:13:49 +1300
committerP1start <rewi-github@whanau.org>2014-12-25 18:58:47 +1300
commitd9769ec3834b62318da892925dc24c8883bb1635 (patch)
tree0455c075f4c1d37151c726fbbf6621e55448c525 /src/libsyntax/parse/parser.rs
parent7e11b22713aebd28ceaaa2ecef937c9b9d247c2f (diff)
downloadrust-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.rs44
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 {