diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2016-05-27 19:05:22 -0700 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2016-07-05 23:09:02 -0700 |
| commit | c8498cc2c27b699436c5f3d3759695926ee0c825 (patch) | |
| tree | 566e8d96c6d2664c7c83d122a4c082fab12d4aa0 /src/libsyntax/parse | |
| parent | 731d37561971d80f5d7ccaba8c2affcf39965917 (diff) | |
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')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 52 | ||||
| -rw-r--r-- | src/libsyntax/parse/token.rs | 10 |
2 files changed, 45 insertions, 17 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 6fa95afd9fb..027b78c17d3 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -578,12 +578,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 + } + }) } } } @@ -985,6 +994,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 { @@ -1076,6 +1086,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) } @@ -4029,8 +4044,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"), + } } }; @@ -5198,14 +5219,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) } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 8376d28164d..3f78dffd31c 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -202,7 +202,7 @@ impl Token { pub fn is_lit(&self) -> bool { match *self { Literal(_, _) => true, - _ => false, + _ => false, } } @@ -214,6 +214,14 @@ impl Token { } } + /// Returns `true` if the token is a documentation comment. + pub fn is_doc_comment(&self) -> bool { + match *self { + DocComment(..) => true, + _ => false, + } + } + /// Returns `true` if the token is interpolated. pub fn is_interpolated(&self) -> bool { match *self { |
