Rollup merge of #111449 - compiler-errors:recover-impl-generics-correctly, r=Nilstrieb

Recover `impl<T ?Sized>` correctly

Fixes #111327

r? ````@Nilstrieb```` but you can re-roll

Alternatively, happy to close this if we're okay with just saying "sorry #111327 is just a poor side-effect of parser ambiguity" 🤷
This commit is contained in:
Nilstrieb 2023-05-16 11:39:38 +02:00 committed by GitHub
commit 87a0cd9a41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 0 deletions

View File

@ -453,6 +453,8 @@ pub(super) fn choose_generics_over_qpath(&self, start: usize) -> bool {
// `<` (LIFETIME|IDENT) `:` - generic parameter with bounds // `<` (LIFETIME|IDENT) `:` - generic parameter with bounds
// `<` (LIFETIME|IDENT) `=` - generic parameter with a default // `<` (LIFETIME|IDENT) `=` - generic parameter with a default
// `<` const - generic const parameter // `<` const - generic const parameter
// `<` IDENT `?` - RECOVERY for `impl<T ?Bound` missing a `:`, meant to
// avoid the `T?` to `Option<T>` recovery for types.
// The only truly ambiguous case is // The only truly ambiguous case is
// `<` IDENT `>` `::` IDENT ... // `<` IDENT `>` `::` IDENT ...
// we disambiguate it in favor of generics (`impl<T> ::absolute::Path<T> { ... }`) // we disambiguate it in favor of generics (`impl<T> ::absolute::Path<T> { ... }`)
@ -463,6 +465,9 @@ pub(super) fn choose_generics_over_qpath(&self, start: usize) -> bool {
|| self.look_ahead(start + 1, |t| t.is_lifetime() || t.is_ident()) || self.look_ahead(start + 1, |t| t.is_lifetime() || t.is_ident())
&& self.look_ahead(start + 2, |t| { && self.look_ahead(start + 2, |t| {
matches!(t.kind, token::Gt | token::Comma | token::Colon | token::Eq) matches!(t.kind, token::Gt | token::Comma | token::Colon | token::Eq)
// Recovery-only branch -- this could be removed,
// since it only affects diagnostics currently.
|| matches!(t.kind, token::Question)
}) })
|| self.is_keyword_ahead(start + 1, &[kw::Const])) || self.is_keyword_ahead(start + 1, &[kw::Const]))
} }

View File

@ -0,0 +1,6 @@
trait Tr {}
impl<T ?Sized> Tr for T {}
//~^ ERROR expected one of `,`, `:`, `=`, or `>`, found `?`
fn main() {}

View File

@ -0,0 +1,8 @@
error: expected one of `,`, `:`, `=`, or `>`, found `?`
--> $DIR/impl-on-unsized-typo.rs:3:8
|
LL | impl<T ?Sized> Tr for T {}
| ^ expected one of `,`, `:`, `=`, or `>`
error: aborting due to previous error