Skip to content

Commit

Permalink
Rollup merge of rust-lang#102345 - chenyukang:fix-102182-impl-trait, …
Browse files Browse the repository at this point in the history
…r=estebank

Recover from impl Trait in type param bound

Fixes rust-lang#102182
r? `@estebank`
  • Loading branch information
JohnTitor authored Oct 10, 2022
2 parents 1ba8c95 + 7b2f04a commit c79429d
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 2 deletions.
36 changes: 34 additions & 2 deletions compiler/rustc_parse/src/parser/generics.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -31,13 +33,43 @@ impl<'a> Parser<'a> {
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,
Expand Down
3 changes: 3 additions & 0 deletions src/test/ui/parser/issues/issue-102182-impl-trait-recover.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn foo<T: impl Trait>() {}
//~^ ERROR expected trait bound, found `impl Trait` type
fn main() {}
14 changes: 14 additions & 0 deletions src/test/ui/parser/issues/issue-102182-impl-trait-recover.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit c79429d

Please sign in to comment.