diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2019-03-07 23:18:03 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2019-03-08 00:24:02 +0300 |
| commit | e19b2289594746ce733588ac444df3fefaad4912 (patch) | |
| tree | 3d4ba1b9ff6378ba7cbcac3cc9656f7c8c74e15c | |
| parent | 00887f39d199bc63730d0dd19f8726451fdd5758 (diff) | |
| download | rust-e19b2289594746ce733588ac444df3fefaad4912.tar.gz rust-e19b2289594746ce733588ac444df3fefaad4912.zip | |
Improve recovery for missing trait in a trait impl
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 22 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-56031.rs | 1 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-56031.stderr | 8 |
3 files changed, 15 insertions, 16 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 330be1133ca..64f413e6dd8 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -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); @@ -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 { @@ -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 }; diff --git a/src/test/ui/issues/issue-56031.rs b/src/test/ui/issues/issue-56031.rs index 7dbda3e46d1..b68f5681467 100644 --- a/src/test/ui/issues/issue-56031.rs +++ b/src/test/ui/issues/issue-56031.rs @@ -1,5 +1,6 @@ struct T; impl for T {} +//~^ ERROR missing trait in a trait impl fn main() {} diff --git a/src/test/ui/issues/issue-56031.stderr b/src/test/ui/issues/issue-56031.stderr index dd4f95341ff..3d7acee0a56 100644 --- a/src/test/ui/issues/issue-56031.stderr +++ b/src/test/ui/issues/issue-56031.stderr @@ -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 |
