Rollup merge of #82579 - osa1:issue82566, r=estebank

Fix turbofish recovery with multiple generic args

This consists of two commits, each can be individually reviewed.

- First commit fixes the issue in [this comment](https://github.com/rust-lang/rust/issues/82566#issuecomment-786924466).
- Second commit fixes #82566

---

r? ````@estebank````
This commit is contained in:
Yuki Okushi 2021-03-02 21:23:17 +09:00 committed by GitHub
commit 906e535205
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 134 additions and 4 deletions

View file

@ -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)) => {

View file

@ -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.

View file

@ -360,12 +360,20 @@ impl<'a> Parser<'a> {
}
Err(err) => return Err(err),
};
let ty = if self.eat(&token::Semi) {
TyKind::Array(elt_ty, self.parse_anon_const_expr()?)
let mut length = self.parse_anon_const_expr()?;
if let Err(e) = self.expect(&token::CloseDelim(token::Bracket)) {
// Try to recover from `X<Y, ...>` when `X::<Y, ...>` works
self.check_mistyped_turbofish_with_multiple_type_params(e, &mut length.value)?;
self.expect(&token::CloseDelim(token::Bracket))?;
}
TyKind::Array(elt_ty, length)
} else {
self.expect(&token::CloseDelim(token::Bracket))?;
TyKind::Slice(elt_ty)
};
self.expect(&token::CloseDelim(token::Bracket))?;
Ok(ty)
}