-
-
Notifications
You must be signed in to change notification settings - Fork 14.2k
Specific error message for missplaced doc comments #33922
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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) | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| // Copyright 2015 The Rust Project Developers. See the COPYRIGHT | ||
| // file at the top-level directory of this distribution and at | ||
| // http://rust-lang.org/COPYRIGHT. | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
| // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
| // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
| // option. This file may not be copied, modified, or distributed | ||
| // except according to those terms. | ||
|
|
||
| // compile-flags: -Z continue-parse-after-error | ||
| struct X { | ||
| a: u8 /** document a */, | ||
| //~^ ERROR found a documentation comment that doesn't document anything | ||
| //~| HELP maybe a comment was intended | ||
| } | ||
|
|
||
| fn main() { | ||
| let y = X {a = 1}; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,5 +12,5 @@ | |
|
|
||
| extern { | ||
| /// hi | ||
| //~^ ERROR expected item after doc comment | ||
| } | ||
| //~^^ ERROR expected item after doc comment | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| // Copyright 2015 The Rust Project Developers. See the COPYRIGHT | ||
| // file at the top-level directory of this distribution and at | ||
| // http://rust-lang.org/COPYRIGHT. | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
| // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
| // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
| // option. This file may not be copied, modified, or distributed | ||
| // except according to those terms. | ||
|
|
||
| // compile-flags: -Z continue-parse-after-error | ||
| fn main() { | ||
| /// document | ||
| //~^ ERROR found a documentation comment that doesn't document anything | ||
| //~| HELP maybe a comment was intended | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| // Copyright 2015 The Rust Project Developers. See the COPYRIGHT | ||
| // file at the top-level directory of this distribution and at | ||
| // http://rust-lang.org/COPYRIGHT. | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
| // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
| // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
| // option. This file may not be copied, modified, or distributed | ||
| // except according to those terms. | ||
|
|
||
| // compile-flags: -Z continue-parse-after-error | ||
| fn /// document | ||
| foo() {} | ||
| //~^^ ERROR expected identifier, found `/// document` | ||
|
||
|
|
||
| fn main() { | ||
| foo(); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| // Copyright 2015 The Rust Project Developers. See the COPYRIGHT | ||
| // file at the top-level directory of this distribution and at | ||
| // http://rust-lang.org/COPYRIGHT. | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
| // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
| // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
| // option. This file may not be copied, modified, or distributed | ||
| // except according to those terms. | ||
|
|
||
| // compile-flags: -Z continue-parse-after-error | ||
| mod Foo { | ||
| /// document | ||
| //~^ ERROR expected item after doc comment | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| // Copyright 2015 The Rust Project Developers. See the COPYRIGHT | ||
| // file at the top-level directory of this distribution and at | ||
| // http://rust-lang.org/COPYRIGHT. | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
| // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
| // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
| // option. This file may not be copied, modified, or distributed | ||
| // except according to those terms. | ||
|
|
||
| // compile-flags: -Z continue-parse-after-error | ||
| struct X { | ||
| a: u8, | ||
| /// document | ||
| //~^ ERROR found a documentation comment that doesn't document anything | ||
| //~| HELP maybe a comment was intended | ||
| } | ||
|
|
||
| fn main() { | ||
| let y = X {a = 1}; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| // Copyright 2015 The Rust Project Developers. See the COPYRIGHT | ||
| // file at the top-level directory of this distribution and at | ||
| // http://rust-lang.org/COPYRIGHT. | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
| // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
| // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
| // option. This file may not be copied, modified, or distributed | ||
| // except according to those terms. | ||
|
|
||
| // compile-flags: -Z continue-parse-after-error | ||
| struct X { | ||
| a: u8 /// document | ||
| //~^ ERROR found a documentation comment that doesn't document anything | ||
| //~| HELP maybe a comment was intended | ||
| } | ||
|
|
||
| fn main() { | ||
| let y = X {a = 1}; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this the same as
self.tokenwhich is being matched on?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At this point
last_tokenis the actual doc comment, but the failure is raised by the currentself.tokennot being a valid element at this location, that's why we have to look back to check wether the failure is because the previous element was a doc comment or something else. This is also why we set error toself.last_spaninstead ofself.span.For example, with the following input
file.rs:The type of
self.last_tokenisSome(DocComment(/// document(61)))whileself.tokenisCloseDelim(Brace)and you get the following output with the current code: