about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-03-07 23:18:03 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-03-08 00:24:02 +0300
commite19b2289594746ce733588ac444df3fefaad4912 (patch)
tree3d4ba1b9ff6378ba7cbcac3cc9656f7c8c74e15c
parent00887f39d199bc63730d0dd19f8726451fdd5758 (diff)
downloadrust-e19b2289594746ce733588ac444df3fefaad4912.tar.gz
rust-e19b2289594746ce733588ac444df3fefaad4912.zip
Improve recovery for missing trait in a trait impl
-rw-r--r--src/libsyntax/parse/parser.rs22
-rw-r--r--src/test/ui/issues/issue-56031.rs1
-rw-r--r--src/test/ui/issues/issue-56031.stderr8
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