Skip to content

Commit 4a76700

Browse files
committed
libsyntax: Explicit error message for sugared doc comments.
Display an explicit message about items missing after sugared doc comment attributes. References #2789.
1 parent 5d335c9 commit 4a76700

8 files changed

+120
-11
lines changed

Diff for: src/libsyntax/parse/parser.rs

+28-11
Original file line numberDiff line numberDiff line change
@@ -3480,22 +3480,32 @@ impl<'a> Parser<'a> {
34803480
})
34813481
}
34823482

3483+
/// Get an expected item after attributes error message.
3484+
fn expected_item_err(attrs: &[Attribute]) -> &'static str {
3485+
match attrs.last() {
3486+
Some(&Attribute { node: ast::Attribute_ { is_sugared_doc: true, .. }, .. }) => {
3487+
"expected item after doc comment"
3488+
}
3489+
_ => "expected item after attributes",
3490+
}
3491+
}
3492+
34833493
/// Parse a statement. may include decl.
34843494
/// Precondition: any attributes are parsed already
34853495
pub fn parse_stmt(&mut self, item_attrs: Vec<Attribute>) -> P<Stmt> {
34863496
maybe_whole!(self, NtStmt);
34873497

3488-
fn check_expected_item(p: &mut Parser, found_attrs: bool) {
3498+
fn check_expected_item(p: &mut Parser, attrs: &[Attribute]) {
34893499
// If we have attributes then we should have an item
3490-
if found_attrs {
3500+
if !attrs.is_empty() {
34913501
let last_span = p.last_span;
3492-
p.span_err(last_span, "expected item after attributes");
3502+
p.span_err(last_span, Parser::expected_item_err(attrs));
34933503
}
34943504
}
34953505

34963506
let lo = self.span.lo;
34973507
if self.is_keyword(keywords::Let) {
3498-
check_expected_item(self, !item_attrs.is_empty());
3508+
check_expected_item(self, item_attrs.as_slice());
34993509
self.expect_keyword(keywords::Let);
35003510
let decl = self.parse_let();
35013511
P(spanned(lo, decl.span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID)))
@@ -3504,7 +3514,7 @@ impl<'a> Parser<'a> {
35043514
&& self.look_ahead(1, |t| *t == token::NOT) {
35053515
// it's a macro invocation:
35063516

3507-
check_expected_item(self, !item_attrs.is_empty());
3517+
check_expected_item(self, item_attrs.as_slice());
35083518

35093519
// Potential trouble: if we allow macros with paths instead of
35103520
// idents, we'd need to look ahead past the whole path here...
@@ -3561,6 +3571,7 @@ impl<'a> Parser<'a> {
35613571

35623572
} else {
35633573
let found_attrs = !item_attrs.is_empty();
3574+
let item_err = Parser::expected_item_err(item_attrs.as_slice());
35643575
match self.parse_item_or_view_item(item_attrs, false) {
35653576
IoviItem(i) => {
35663577
let hi = i.span.hi;
@@ -3575,7 +3586,10 @@ impl<'a> Parser<'a> {
35753586
self.fatal("foreign items are not allowed here");
35763587
}
35773588
IoviNone(_) => {
3578-
check_expected_item(self, found_attrs);
3589+
if found_attrs {
3590+
let last_span = self.last_span;
3591+
self.span_err(last_span, item_err);
3592+
}
35793593

35803594
// Remainder are line-expr stmts.
35813595
let e = self.parse_expr_res(RestrictionStmtExpr);
@@ -3653,7 +3667,8 @@ impl<'a> Parser<'a> {
36533667
token::SEMI => {
36543668
if !attributes_box.is_empty() {
36553669
let last_span = self.last_span;
3656-
self.span_err(last_span, "expected item after attributes");
3670+
self.span_err(last_span,
3671+
Parser::expected_item_err(attributes_box.as_slice()));
36573672
attributes_box = Vec::new();
36583673
}
36593674
self.bump(); // empty
@@ -3739,7 +3754,8 @@ impl<'a> Parser<'a> {
37393754

37403755
if !attributes_box.is_empty() {
37413756
let last_span = self.last_span;
3742-
self.span_err(last_span, "expected item after attributes");
3757+
self.span_err(last_span,
3758+
Parser::expected_item_err(attributes_box.as_slice()));
37433759
}
37443760

37453761
let hi = self.span.hi;
@@ -4685,7 +4701,8 @@ impl<'a> Parser<'a> {
46854701
if first && attrs_remaining_len > 0u {
46864702
// We parsed attributes for the first item but didn't find it
46874703
let last_span = self.last_span;
4688-
self.span_err(last_span, "expected item after attributes");
4704+
self.span_err(last_span,
4705+
Parser::expected_item_err(attrs_remaining.as_slice()));
46894706
}
46904707

46914708
ast::Mod {
@@ -4919,10 +4936,10 @@ impl<'a> Parser<'a> {
49194936
items: _,
49204937
foreign_items: foreign_items
49214938
} = self.parse_foreign_items(first_item_attrs, true);
4922-
if ! attrs_remaining.is_empty() {
4939+
if !attrs_remaining.is_empty() {
49234940
let last_span = self.last_span;
49244941
self.span_err(last_span,
4925-
"expected item after attributes");
4942+
Parser::expected_item_err(attrs_remaining.as_slice()));
49264943
}
49274944
assert!(self.token == token::RBRACE);
49284945
ast::ForeignMod {

Diff for: src/test/compile-fail/attr-before-eof.rs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#[deriving(Show)] //~ERROR expected item after attributes

Diff for: src/test/compile-fail/doc-before-attr.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
/// hi
12+
#[deriving(Show)] //~ERROR expected item after attributes

Diff for: src/test/compile-fail/doc-before-eof.rs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
/// hi //~ERROR expected item after doc comment

Diff for: src/test/compile-fail/doc-before-extern-rbrace.rs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
extern {
12+
/// hi
13+
}
14+
//~^^ ERROR expected item after doc comment

Diff for: src/test/compile-fail/doc-before-macro.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
/// hi
13+
println!("hi");
14+
//~^^ ERROR expected item after doc comment
15+
}

Diff for: src/test/compile-fail/doc-before-rbrace.rs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
println!("Hi"); /// hi
13+
//~^ ERROR expected item after doc comment
14+
}

Diff for: src/test/compile-fail/doc-before-semi.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
/// hi
13+
;
14+
//~^^ ERROR expected item after doc comment
15+
}

0 commit comments

Comments
 (0)