about summary refs log tree commit diff
diff options
context:
space:
mode:
authorÖmer Sinan Ağacan <omeragacan@gmail.com>2021-02-27 08:01:32 +0300
committerÖmer Sinan Ağacan <omeragacan@gmail.com>2021-02-27 13:46:49 +0300
commitfb631a55c2acfae37e55e4c338dd3cc03da0fa7f (patch)
tree0c93da2d5d52369a8a4cf27132cff937bd838c83
parent3da2dd3eae7b7cbf16960ab993de666470e43991 (diff)
downloadrust-fb631a55c2acfae37e55e4c338dd3cc03da0fa7f.tar.gz
rust-fb631a55c2acfae37e55e4c338dd3cc03da0fa7f.zip
Fix turbofish recovery with multiple generic args
check_mistyped_turbofish_with_multiple_type_params was previously
expecting type arguments between angle brackets, which is not right, as
we can also see const expressions. We now use generic argument parser
instead of type parser.

Test with one, two, and three generic arguments added to check
consistentcy between

1. check_no_chained_comparison: Called after parsing a nested binop
   application like `x < A > ...` where angle brackets are interpreted as
   binary operators and `A` is an expression.

2. check_mistyped_turbofish_with_multiple_type_params: called by
   `parse_full_stmt` when we expect to see a semicolon after parsing an
   expression but don't see it.

   (In `T2<1, 2>::C;`, the expression is `T2 < 1`)
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs2
-rw-r--r--compiler/rustc_parse/src/parser/path.rs2
-rw-r--r--src/test/ui/suggestions/issue-82566.rs21
-rw-r--r--src/test/ui/suggestions/issue-82566.stderr35
4 files changed, 58 insertions, 2 deletions
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 5b4939b7407..f4ab3260d1a 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -662,7 +662,7 @@ impl<'a> Parser<'a> {
                     let x = self.parse_seq_to_before_end(
                         &token::Gt,
                         SeqSep::trailing_allowed(token::Comma),
-                        |p| p.parse_ty(),
+                        |p| p.parse_generic_arg(),
                     );
                     match x {
                         Ok((_, _, false)) => {
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 6b7059eecf4..9cc600d9ede 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -545,7 +545,7 @@ impl<'a> Parser<'a> {
 
     /// Parse a generic argument in a path segment.
     /// This does not include constraints, e.g., `Item = u8`, which is handled in `parse_angle_arg`.
-    fn parse_generic_arg(&mut self) -> PResult<'a, Option<GenericArg>> {
+    pub(super) fn parse_generic_arg(&mut self) -> PResult<'a, Option<GenericArg>> {
         let start = self.token.span;
         let arg = if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
             // Parse lifetime argument.
diff --git a/src/test/ui/suggestions/issue-82566.rs b/src/test/ui/suggestions/issue-82566.rs
new file mode 100644
index 00000000000..95c31fbaa28
--- /dev/null
+++ b/src/test/ui/suggestions/issue-82566.rs
@@ -0,0 +1,21 @@
+struct T1<const X1: usize>;
+struct T2<const X1: usize, const X2: usize>;
+struct T3<const X1: usize, const X2: usize, const X3: usize>;
+
+impl T1<1> {
+    const C: () = ();
+}
+
+impl T2<1, 2> {
+    const C: () = ();
+}
+
+impl T3<1, 2, 3> {
+    const C: () = ();
+}
+
+fn main() {
+    T1<1>::C; //~ ERROR: comparison operators cannot be chained
+    T2<1, 2>::C; //~ ERROR: expected one of `.`, `;`, `?`, `}`, or an operator, found `,`
+    T3<1, 2, 3>::C; //~ ERROR: expected one of `.`, `;`, `?`, `}`, or an operator, found `,`
+}
diff --git a/src/test/ui/suggestions/issue-82566.stderr b/src/test/ui/suggestions/issue-82566.stderr
new file mode 100644
index 00000000000..e13c097e4cc
--- /dev/null
+++ b/src/test/ui/suggestions/issue-82566.stderr
@@ -0,0 +1,35 @@
+error: comparison operators cannot be chained
+  --> $DIR/issue-82566.rs:18:7
+   |
+LL |     T1<1>::C;
+   |       ^ ^
+   |
+help: use `::<...>` instead of `<...>` to specify type or const arguments
+   |
+LL |     T1::<1>::C;
+   |       ^^
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `,`
+  --> $DIR/issue-82566.rs:19:9
+   |
+LL |     T2<1, 2>::C;
+   |         ^ expected one of `.`, `;`, `?`, `}`, or an operator
+   |
+help: use `::<...>` instead of `<...>` to specify type or const arguments
+   |
+LL |     T2::<1, 2>::C;
+   |       ^^
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `,`
+  --> $DIR/issue-82566.rs:20:9
+   |
+LL |     T3<1, 2, 3>::C;
+   |         ^ expected one of `.`, `;`, `?`, `}`, or an operator
+   |
+help: use `::<...>` instead of `<...>` to specify type or const arguments
+   |
+LL |     T3::<1, 2, 3>::C;
+   |       ^^
+
+error: aborting due to 3 previous errors
+