Skip to content

Commit

Permalink
Improve recovery for missing trait in a trait impl
Browse files Browse the repository at this point in the history
  • Loading branch information
petrochenkov committed Mar 7, 2019
1 parent 00887f3 commit e19b228
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 16 deletions.
22 changes: 11 additions & 11 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6716,16 +6716,16 @@ impl<'a> Parser<'a> {
ast::ImplPolarity::Positive
};

let possible_missing_trait = self.look_ahead(0, |t| t.is_keyword(keywords::For));

// Parse both types and traits as a type, then reinterpret if necessary.
let ty_first = self.parse_ty().map_err(|mut err| {
if possible_missing_trait {
err.help("did you forget a trait name after `impl`?");
}

err
})?;
let err_path = |span| ast::Path::from_ident(Ident::new(keywords::Invalid.name(), span));
let ty_first = if self.token.is_keyword(keywords::For) &&
self.look_ahead(1, |t| t != &token::Lt) {
let span = self.prev_span.between(self.span);
self.struct_span_err(span, "missing trait in a trait impl").emit();
P(Ty { node: TyKind::Path(None, err_path(span)), span, id: ast::DUMMY_NODE_ID })
} else {
self.parse_ty()?
};

// If `for` is missing we try to recover.
let has_for = self.eat_keyword(keywords::For);
Expand All @@ -6734,7 +6734,7 @@ impl<'a> Parser<'a> {
let ty_second = if self.token == token::DotDot {
// We need to report this error after `cfg` expansion for compatibility reasons
self.bump(); // `..`, do not add it to expected tokens
Some(P(Ty { node: TyKind::Err, span: self.prev_span, id: ast::DUMMY_NODE_ID }))
Some(DummyResult::raw_ty(self.prev_span, true))
} else if has_for || self.token.can_begin_type() {
Some(self.parse_ty()?)
} else {
Expand Down Expand Up @@ -6764,7 +6764,7 @@ impl<'a> Parser<'a> {
TyKind::Path(None, path) => path,
_ => {
self.span_err(ty_first.span, "expected a trait, found type");
ast::Path::from_ident(Ident::new(keywords::Invalid.name(), ty_first.span))
err_path(ty_first.span)
}
};
let trait_ref = TraitRef { path, ref_id: ty_first.id };
Expand Down
1 change: 1 addition & 0 deletions src/test/ui/issues/issue-56031.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
struct T;

impl for T {}
//~^ ERROR missing trait in a trait impl

fn main() {}
8 changes: 3 additions & 5 deletions src/test/ui/issues/issue-56031.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
error: expected `<`, found `T`
--> $DIR/issue-56031.rs:3:10
error: missing trait in a trait impl
--> $DIR/issue-56031.rs:3:5
|
LL | impl for T {}
| ^ expected `<` here
|
= help: did you forget a trait name after `impl`?
| ^

error: aborting due to previous error

0 comments on commit e19b228

Please sign in to comment.