]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_lint/builtin.rs
improve unused doc comment diagnostic reporting
[rust.git] / src / librustc_lint / builtin.rs
index 641adec82cdd9e11d3e849445bc1bf43adee7339..284bfcd4014911f68530c7847e7e670ae2bb53e6 100644 (file)
@@ -198,7 +198,7 @@ fn check_pat(&mut self, cx: &LateContext<'_, '_>, pat: &hir::Pat) {
                     // (Issue #49588)
                     continue;
                 }
-                if let PatKind::Binding(_, _, _, ident, None) = fieldpat.node.pat.node {
+                if let PatKind::Binding(_, _, ident, None) = fieldpat.node.pat.node {
                     if cx.tcx.find_field_index(ident, &variant) ==
                        Some(cx.tcx.field_index(fieldpat.node.hir_id, cx.tables)) {
                         let mut err = cx.struct_span_lint(NON_SHORTHAND_FIELD_PATTERNS,
@@ -458,8 +458,8 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
                 // If the trait is private, add the impl items to private_traits so they don't get
                 // reported for missing docs.
                 let real_trait = trait_ref.path.def.def_id();
-                if let Some(node_id) = cx.tcx.hir().as_local_node_id(real_trait) {
-                    match cx.tcx.hir().find(node_id) {
+                if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(real_trait) {
+                    match cx.tcx.hir().find_by_hir_id(hir_id) {
                         Some(Node::Item(item)) => {
                             if let hir::VisibilityKind::Inherited = item.vis.node {
                                 for impl_item_ref in impl_item_refs {
@@ -802,27 +802,50 @@ fn get_lints(&self) -> LintArray {
 }
 
 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);
     }
 }