Skip to content

Commit

Permalink
Fix turbofish recovery with multiple generic args
Browse files Browse the repository at this point in the history
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`)
  • Loading branch information
osa1 committed Feb 27, 2021
1 parent 3da2dd3 commit fb631a5
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 2 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)) => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_parse/src/parser/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
21 changes: 21 additions & 0 deletions src/test/ui/suggestions/issue-82566.rs
Original file line number Diff line number Diff line change
@@ -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 `,`
}
35 changes: 35 additions & 0 deletions src/test/ui/suggestions/issue-82566.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit fb631a5

Please sign in to comment.