about summary refs log tree commit diff
path: root/src/libsyntax/parse/parser.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-08-19 18:14:53 -0700
committerGitHub <noreply@github.com>2016-08-19 18:14:53 -0700
commit38fa82a3149a9f1428a9c760aeac7265b045fa24 (patch)
tree185e904d34c00d91e6b2631dc8ba96efc0073372 /src/libsyntax/parse/parser.rs
parentf883b0bbab6c433eb7b7042b605b4339022c563a (diff)
parentc8498cc2c27b699436c5f3d3759695926ee0c825 (diff)
downloadrust-38fa82a3149a9f1428a9c760aeac7265b045fa24.tar.gz
rust-38fa82a3149a9f1428a9c760aeac7265b045fa24.zip
Auto merge of #33922 - estebank:doc-comment, r=alexcrichton
Specific error message for missplaced doc comments

Identify when documetation comments have been missplaced in the following places:

 * After a struct element:

    ```rust
    // file.rs:
    struct X {
        a: u8 /** document a */,
    }
    ```

    ```bash
    $ rustc file.rs
    file.rs:2:11: 2:28 error: found documentation comment that doesn't
    document anything
    file.rs:2     a: u8 /** document a */,
                        ^~~~~~~~~~~~~~~~~
    file.rs:2:11: 2:28 help: doc comments must come before what they document,
    maybe a comment was intended with `//`?
    ```

 * As the last line of a struct:

    ```rust
    // file.rs:
    struct X {
        a: u8,
        /// incorrect documentation
    }
    ```

    ```bash
    $ rustc file.rs
    file.rs:3:5: 3:27 error: found a documentation comment that doesn't
    document anything
    file.rs:3     /// incorrect documentation
                  ^~~~~~~~~~~~~~~~~~~~~~
    file.rs:3:5: 3:27 help: doc comments must come before what they document,
    maybe a comment was intended with `//`?
    ```

 * As the last line of a `fn`:

    ```rust
    // file.rs:
    fn main() {
        let x = 1;
        /// incorrect documentation
    }
    ```

    ```bash
    $ rustc file.rs
    file.rs:3:5: 3:27 error: found a documentation comment that doesn't
    document anything
    file.rs:3     /// incorrect documentation
                  ^~~~~~~~~~~~~~~~~~~~~~
    file.rs:3:5: 3:27 help: doc comments must come before what they document,
    maybe a comment was intended with `//`?
    ```

Fix #27429, #30322
Diffstat (limited to 'src/libsyntax/parse/parser.rs')
-rw-r--r--src/libsyntax/parse/parser.rs52
1 files changed, 36 insertions, 16 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 126e8816d05..9443df6321b 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -520,12 +520,21 @@ impl<'a> Parser<'a> {
                 self.bug("ident interpolation not converted to real token");
             }
             _ => {
-                let mut err = self.fatal(&format!("expected identifier, found `{}`",
-                                                  self.this_token_to_string()));
-                if self.token == token::Underscore {
-                    err.note("`_` is a wildcard pattern, not an identifier");
-                }
-                Err(err)
+                let last_token = self.last_token.clone().map(|t| *t);
+                Err(match last_token {
+                    Some(token::DocComment(_)) => self.span_fatal_help(self.last_span,
+                        "found a documentation comment that doesn't document anything",
+                        "doc comments must come before what they document, maybe a comment was \
+                        intended with `//`?"),
+                    _ => {
+                        let mut err = self.fatal(&format!("expected identifier, found `{}`",
+                                                          self.this_token_to_string()));
+                        if self.token == token::Underscore {
+                            err.note("`_` is a wildcard pattern, not an identifier");
+                        }
+                        err
+                    }
+                })
             }
         }
     }
@@ -927,6 +936,7 @@ impl<'a> Parser<'a> {
         // Stash token for error recovery (sometimes; clone is not necessarily cheap).
         self.last_token = if self.token.is_ident() ||
                           self.token.is_path() ||
+                          self.token.is_doc_comment() ||
                           self.token == token::Comma {
             Some(Box::new(self.token.clone()))
         } else {
@@ -1018,6 +1028,11 @@ impl<'a> Parser<'a> {
     pub fn span_err(&self, sp: Span, m: &str) {
         self.sess.span_diagnostic.span_err(sp, m)
     }
+    pub fn span_err_help(&self, sp: Span, m: &str, h: &str) {
+        let mut err = self.sess.span_diagnostic.mut_span_err(sp, m);
+        err.help(h);
+        err.emit();
+    }
     pub fn span_bug(&self, sp: Span, m: &str) -> ! {
         self.sess.span_diagnostic.span_bug(sp, m)
     }
@@ -4021,8 +4036,14 @@ impl<'a> Parser<'a> {
                 None => {
                     let unused_attrs = |attrs: &[_], s: &mut Self| {
                         if attrs.len() > 0 {
-                            s.span_err(s.span,
-                                "expected statement after outer attribute");
+                            let last_token = s.last_token.clone().map(|t| *t);
+                            match last_token {
+                                Some(token::DocComment(_)) => s.span_err_help(s.last_span,
+                                    "found a documentation comment that doesn't document anything",
+                                    "doc comments must come before what they document, maybe a \
+                                    comment was intended with `//`?"),
+                                _ => s.span_err(s.span, "expected statement after outer attribute"),
+                            }
                         }
                     };
 
@@ -5127,14 +5148,13 @@ impl<'a> Parser<'a> {
                 self.bump();
             }
             token::CloseDelim(token::Brace) => {}
-            _ => {
-                let span = self.span;
-                let token_str = self.this_token_to_string();
-                return Err(self.span_fatal_help(span,
-                                     &format!("expected `,`, or `}}`, found `{}`",
-                                             token_str),
-                                     "struct fields should be separated by commas"))
-            }
+            token::DocComment(_) => return Err(self.span_fatal_help(self.span,
+                        "found a documentation comment that doesn't document anything",
+                        "doc comments must come before what they document, maybe a comment was \
+                        intended with `//`?")),
+            _ => return Err(self.span_fatal_help(self.span,
+                    &format!("expected `,`, or `}}`, found `{}`", self.this_token_to_string()),
+                    "struct fields should be separated by commas")),
         }
         Ok(a_var)
     }