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:
commit
303ebd5b04
@ -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,
|
||||
|
@ -0,0 +1,3 @@
|
||||
fn foo<T: impl Trait>() {}
|
||||
//~^ ERROR expected trait bound, found `impl Trait` type
|
||||
fn main() {}
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user