Skip to content

Commit e19b228

Browse files
committed
Improve recovery for missing trait in a trait impl
1 parent 00887f3 commit e19b228

File tree

3 files changed

+15
-16
lines changed

3 files changed

+15
-16
lines changed

src/libsyntax/parse/parser.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -6716,16 +6716,16 @@ impl<'a> Parser<'a> {
67166716
ast::ImplPolarity::Positive
67176717
};
67186718

6719-
let possible_missing_trait = self.look_ahead(0, |t| t.is_keyword(keywords::For));
6720-
67216719
// Parse both types and traits as a type, then reinterpret if necessary.
6722-
let ty_first = self.parse_ty().map_err(|mut err| {
6723-
if possible_missing_trait {
6724-
err.help("did you forget a trait name after `impl`?");
6725-
}
6726-
6727-
err
6728-
})?;
6720+
let err_path = |span| ast::Path::from_ident(Ident::new(keywords::Invalid.name(), span));
6721+
let ty_first = if self.token.is_keyword(keywords::For) &&
6722+
self.look_ahead(1, |t| t != &token::Lt) {
6723+
let span = self.prev_span.between(self.span);
6724+
self.struct_span_err(span, "missing trait in a trait impl").emit();
6725+
P(Ty { node: TyKind::Path(None, err_path(span)), span, id: ast::DUMMY_NODE_ID })
6726+
} else {
6727+
self.parse_ty()?
6728+
};
67296729

67306730
// If `for` is missing we try to recover.
67316731
let has_for = self.eat_keyword(keywords::For);
@@ -6734,7 +6734,7 @@ impl<'a> Parser<'a> {
67346734
let ty_second = if self.token == token::DotDot {
67356735
// We need to report this error after `cfg` expansion for compatibility reasons
67366736
self.bump(); // `..`, do not add it to expected tokens
6737-
Some(P(Ty { node: TyKind::Err, span: self.prev_span, id: ast::DUMMY_NODE_ID }))
6737+
Some(DummyResult::raw_ty(self.prev_span, true))
67386738
} else if has_for || self.token.can_begin_type() {
67396739
Some(self.parse_ty()?)
67406740
} else {
@@ -6764,7 +6764,7 @@ impl<'a> Parser<'a> {
67646764
TyKind::Path(None, path) => path,
67656765
_ => {
67666766
self.span_err(ty_first.span, "expected a trait, found type");
6767-
ast::Path::from_ident(Ident::new(keywords::Invalid.name(), ty_first.span))
6767+
err_path(ty_first.span)
67686768
}
67696769
};
67706770
let trait_ref = TraitRef { path, ref_id: ty_first.id };

src/test/ui/issues/issue-56031.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
struct T;
22

33
impl for T {}
4+
//~^ ERROR missing trait in a trait impl
45

56
fn main() {}

src/test/ui/issues/issue-56031.stderr

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
error: expected `<`, found `T`
2-
--> $DIR/issue-56031.rs:3:10
1+
error: missing trait in a trait impl
2+
--> $DIR/issue-56031.rs:3:5
33
|
44
LL | impl for T {}
5-
| ^ expected `<` here
6-
|
7-
= help: did you forget a trait name after `impl`?
5+
| ^
86

97
error: aborting due to previous error
108

0 commit comments

Comments
 (0)