Rollup merge of #102345 - chenyukang:fix-102182-impl-trait, r=estebank

Recover from impl Trait in type param bound

Fixes #102182
r? ``@estebank``
This commit is contained in:
Yuki Okushi 2022-10-10 10:23:04 +09:00 committed by GitHub
commit 303ebd5b04
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 2 deletions

View File

@ -1,7 +1,9 @@
use super::{ForceCollect, Parser, TrailingToken};
use rustc_ast::token;
use rustc_ast::{self as ast, AttrVec, GenericBounds, GenericParam, GenericParamKind, WhereClause};
use rustc_ast::{
self as ast, AttrVec, GenericBounds, GenericParam, GenericParamKind, TyKind, WhereClause,
};
use rustc_errors::{Applicability, PResult};
use rustc_span::symbol::kw;
@ -31,13 +33,43 @@ fn parse_ty_param(&mut self, preceding_attrs: AttrVec) -> PResult<'a, GenericPar
let mut colon_span = None;
let bounds = if self.eat(&token::Colon) {
colon_span = Some(self.prev_token.span);
// recover from `impl Trait` in type param bound
if self.token.is_keyword(kw::Impl) {
let impl_span = self.token.span;
let snapshot = self.create_snapshot_for_diagnostic();
match self.parse_ty() {
Ok(p) => {
if let TyKind::ImplTrait(_, bounds) = &(*p).kind {
let span = impl_span.to(self.token.span.shrink_to_lo());
let mut err = self.struct_span_err(
span,
"expected trait bound, found `impl Trait` type",
);
err.span_label(span, "not a trait");
if let [bound, ..] = &bounds[..] {
err.span_suggestion_verbose(
impl_span.until(bound.span()),
"use the trait bounds directly",
String::new(),
Applicability::MachineApplicable,
);
}
err.emit();
return Err(err);
}
}
Err(err) => {
err.cancel();
}
}
self.restore_snapshot(snapshot);
}
self.parse_generic_bounds(colon_span)?
} else {
Vec::new()
};
let default = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None };
Ok(GenericParam {
ident,
id: ast::DUMMY_NODE_ID,

View File

@ -0,0 +1,3 @@
fn foo<T: impl Trait>() {}
//~^ ERROR expected trait bound, found `impl Trait` type
fn main() {}

View File

@ -0,0 +1,14 @@
error: expected trait bound, found `impl Trait` type
--> $DIR/issue-102182-impl-trait-recover.rs:1:11
|
LL | fn foo<T: impl Trait>() {}
| ^^^^^^^^^^ not a trait
|
help: use the trait bounds directly
|
LL - fn foo<T: impl Trait>() {}
LL + fn foo<T: Trait>() {}
|
error: aborting due to previous error