about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libsyntax/parse/parser.rs19
-rw-r--r--src/test/ui/issue-22644.rs2
-rw-r--r--src/test/ui/issue-22644.stderr13
-rw-r--r--src/test/ui/issue-44406.rs19
-rw-r--r--src/test/ui/issue-44406.stderr26
5 files changed, 74 insertions, 5 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 978e06c75dd..ff020445715 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2890,17 +2890,30 @@ impl<'a> Parser<'a> {
 
                 match self.parse_path(PathStyle::Expr) {
                     Ok(path) => {
+                        let (op_noun, op_verb) = match self.token {
+                            token::Lt => ("comparison", "comparing"),
+                            token::BinOp(token::Shl) => ("shift", "shifting"),
+                            _ => {
+                                // We can end up here even without `<` being the next token, for
+                                // example because `parse_ty_no_plus` returns `Err` on keywords,
+                                // but `parse_path` returns `Ok` on them due to error recovery.
+                                // Return original error and parser state.
+                                mem::replace(self, parser_snapshot_after_type);
+                                return Err(type_err);
+                            }
+                        };
+
                         // Successfully parsed the type path leaving a `<` yet to parse.
                         type_err.cancel();
 
                         // Report non-fatal diagnostics, keep `x as usize` as an expression
                         // in AST and continue parsing.
                         let msg = format!("`<` is interpreted as a start of generic \
-                                           arguments for `{}`, not a comparison", path);
+                                           arguments for `{}`, not a {}", path, op_noun);
                         let mut err = self.sess.span_diagnostic.struct_span_err(self.span, &msg);
                         err.span_label(self.look_ahead_span(1).to(parser_snapshot_after_type.span),
                                        "interpreted as generic arguments");
-                        err.span_label(self.span, "not interpreted as comparison");
+                        err.span_label(self.span, format!("not interpreted as {}", op_noun));
 
                         let expr = mk_expr(self, P(Ty {
                             span: path.span,
@@ -2911,7 +2924,7 @@ impl<'a> Parser<'a> {
                         let expr_str = self.sess.codemap().span_to_snippet(expr.span)
                                                 .unwrap_or(pprust::expr_to_string(&expr));
                         err.span_suggestion(expr.span,
-                                            "try comparing the casted value",
+                                            &format!("try {} the casted value", op_verb),
                                             format!("({})", expr_str));
                         err.emit();
 
diff --git a/src/test/ui/issue-22644.rs b/src/test/ui/issue-22644.rs
index b482d0595f7..c8e0cd1763f 100644
--- a/src/test/ui/issue-22644.rs
+++ b/src/test/ui/issue-22644.rs
@@ -35,5 +35,7 @@ fn main() {
                    <
                    5);
 
+    println!("{}", a as usize << long_name);
+
     println!("{}", a: &mut 4);
 }
diff --git a/src/test/ui/issue-22644.stderr b/src/test/ui/issue-22644.stderr
index 54c325b24a3..f4967c4803b 100644
--- a/src/test/ui/issue-22644.stderr
+++ b/src/test/ui/issue-22644.stderr
@@ -76,9 +76,18 @@ help: try comparing the casted value
 33 | 
  ...
 
+error: `<` is interpreted as a start of generic arguments for `usize`, not a shift
+  --> $DIR/issue-22644.rs:38:31
+   |
+38 |     println!("{}", a as usize << long_name);
+   |                    ---------- ^^ --------- interpreted as generic arguments
+   |                    |          |
+   |                    |          not interpreted as shift
+   |                    help: try shifting the casted value: `(a as usize)`
+
 error: expected type, found `4`
-  --> $DIR/issue-22644.rs:38:28
+  --> $DIR/issue-22644.rs:40:28
    |
-38 |     println!("{}", a: &mut 4);
+40 |     println!("{}", a: &mut 4);
    |                            ^ expecting a type here because of type ascription
 
diff --git a/src/test/ui/issue-44406.rs b/src/test/ui/issue-44406.rs
new file mode 100644
index 00000000000..abf572118fc
--- /dev/null
+++ b/src/test/ui/issue-44406.rs
@@ -0,0 +1,19 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+macro_rules! foo {
+    ($rest: tt) => {
+        bar(baz: $rest)
+    }
+}
+
+fn main() {
+    foo!(true);
+}
diff --git a/src/test/ui/issue-44406.stderr b/src/test/ui/issue-44406.stderr
new file mode 100644
index 00000000000..e07face24ba
--- /dev/null
+++ b/src/test/ui/issue-44406.stderr
@@ -0,0 +1,26 @@
+error: expected identifier, found keyword `true`
+  --> $DIR/issue-44406.rs:18:10
+   |
+18 |     foo!(true);
+   |          ^^^^
+
+error: expected type, found keyword `true`
+  --> $DIR/issue-44406.rs:18:10
+   |
+13 |         bar(baz: $rest)
+   |                - help: did you mean to use `;` here?
+...
+18 |     foo!(true);
+   |          ^^^^ expecting a type here because of type ascription
+
+error: expected one of `!`, `&&`, `&`, `(`, `*`, `.`, `;`, `<`, `?`, `[`, `_`, `extern`, `fn`, `for`, `impl`, `unsafe`, `}`, an operator, or lifetime, found `true`
+  --> $DIR/issue-44406.rs:18:10
+   |
+13 |         bar(baz: $rest)
+   |                 - expected one of 19 possible tokens here
+...
+18 |     foo!(true);
+   |          ^^^^ unexpected token
+
+error: aborting due to 3 previous errors
+