Skip to content

Commit

Permalink
improve unused doc comment diagnostic reporting
Browse files Browse the repository at this point in the history
Report all unused attributes on a given doc comment instead of just the
first one, and extend the span of sugared doc comments to encompass the
whole comment.
  • Loading branch information
euclio committed Mar 8, 2019
1 parent 2a65cbe commit 018d4d2
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 15 deletions.
41 changes: 32 additions & 9 deletions src/librustc_lint/builtin.rs
Expand Up @@ -802,27 +802,50 @@ impl LintPass for UnusedDocComment {
}

impl UnusedDocComment {
fn warn_if_doc<'a, 'tcx,
I: Iterator<Item=&'a ast::Attribute>,
C: LintContext<'tcx>>(&self, mut attrs: I, cx: &C) {
if let Some(attr) = attrs.find(|a| a.is_value_str() && a.check_name("doc")) {
cx.struct_span_lint(UNUSED_DOC_COMMENTS, attr.span, "doc comment not used by rustdoc")
.emit();
fn warn_if_doc(&self, cx: &EarlyContext, attrs: &[ast::Attribute]) {
let mut attrs = attrs.into_iter().peekable();

// Accumulate a single span for sugared doc comments.
let mut sugared_span: Option<Span> = None;

while let Some(attr) = attrs.next() {
if attr.is_sugared_doc {
sugared_span = Some(
sugared_span.map_or_else(
|| attr.span,
|span| span.with_hi(attr.span.hi()),
),
);
}

if attrs.peek().map(|next_attr| next_attr.is_sugared_doc).unwrap_or_default() {
continue;
}

let span = sugared_span.take().unwrap_or_else(|| attr.span);

if attr.name() == "doc" {
cx.struct_span_lint(
UNUSED_DOC_COMMENTS,
span,
"doc comment not used by rustdoc",
).emit();
}
}
}
}

impl EarlyLintPass for UnusedDocComment {
fn check_local(&mut self, cx: &EarlyContext<'_>, decl: &ast::Local) {
self.warn_if_doc(decl.attrs.iter(), cx);
self.warn_if_doc(cx, &decl.attrs);
}

fn check_arm(&mut self, cx: &EarlyContext<'_>, arm: &ast::Arm) {
self.warn_if_doc(arm.attrs.iter(), cx);
self.warn_if_doc(cx, &arm.attrs);
}

fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {
self.warn_if_doc(expr.attrs.iter(), cx);
self.warn_if_doc(cx, &expr.attrs);
}
}

Expand Down
8 changes: 7 additions & 1 deletion src/test/ui/useless_comment.rs
Expand Up @@ -4,7 +4,9 @@ fn foo() {
/// a //~ ERROR doc comment not used by rustdoc
let x = 12;

/// b //~ doc comment not used by rustdoc
/// multi-line //~ doc comment not used by rustdoc
/// doc comment
/// that is unused
match x {
/// c //~ ERROR doc comment not used by rustdoc
1 => {},
Expand All @@ -13,6 +15,10 @@ fn foo() {

/// foo //~ ERROR doc comment not used by rustdoc
unsafe {}

#[doc = "foo"] //~ ERROR doc comment not used by rustdoc
#[doc = "bar"] //~ ERROR doc comment not used by rustdoc
3;
}

fn main() {
Expand Down
24 changes: 19 additions & 5 deletions src/test/ui/useless_comment.stderr
Expand Up @@ -13,20 +13,34 @@ LL | #![deny(unused_doc_comments)]
error: doc comment not used by rustdoc
--> $DIR/useless_comment.rs:7:5
|
LL | /// b //~ doc comment not used by rustdoc
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | / /// multi-line //~ doc comment not used by rustdoc
LL | | /// doc comment
LL | | /// that is unused
| |______________________^

error: doc comment not used by rustdoc
--> $DIR/useless_comment.rs:9:9
--> $DIR/useless_comment.rs:11:9
|
LL | /// c //~ ERROR doc comment not used by rustdoc
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: doc comment not used by rustdoc
--> $DIR/useless_comment.rs:14:5
--> $DIR/useless_comment.rs:16:5
|
LL | /// foo //~ ERROR doc comment not used by rustdoc
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 4 previous errors
error: doc comment not used by rustdoc
--> $DIR/useless_comment.rs:19:5
|
LL | #[doc = "foo"] //~ ERROR doc comment not used by rustdoc
| ^^^^^^^^^^^^^^

error: doc comment not used by rustdoc
--> $DIR/useless_comment.rs:20:5
|
LL | #[doc = "bar"] //~ ERROR doc comment not used by rustdoc
| ^^^^^^^^^^^^^^

error: aborting due to 6 previous errors

0 comments on commit 018d4d2

Please sign in to comment.