about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-01-03 03:25:21 +0000
committerbors <bors@rust-lang.org>2015-01-03 03:25:21 +0000
commit9c3e6082e71618c088afd93f7a4a9a7708c9dcbd (patch)
tree7f0a4f049f87f845a99751add69cda3409a91c20 /src/libsyntax/parse
parenta6b109723aa78154ffcfa4db80f3f36b76a9c0a7 (diff)
parentd9769ec3834b62318da892925dc24c8883bb1635 (diff)
downloadrust-9c3e6082e71618c088afd93f7a4a9a7708c9dcbd.tar.gz
rust-9c3e6082e71618c088afd93f7a4a9a7708c9dcbd.zip
auto merge of #20154 : P1start/rust/qualified-assoc-type-generics, r=nikomatsakis
This modifies `Parser::eat_lt` to always split up `<<`s, instead of doing so only when a lifetime name followed or the `force` parameter (now removed) was `true`. This is because `Foo<<TYPE` is now a valid start to a type, whereas previously only `Foo<<LIFETIME` was valid.

This is a [breaking-change]. Change code that looks like this:

```rust
let x = foo as bar << 13;
```

to use parentheses, like this:

```rust
let x = (foo as bar) << 13;
```

Closes #17362.
Diffstat (limited to 'src/libsyntax/parse')
-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 c597968d4ae..e2f86f8fd39 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -681,45 +681,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 `{}`",
@@ -1594,9 +1571,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();
@@ -1877,7 +1853,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 {
@@ -1938,7 +1914,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 {