about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2019-05-16 18:31:53 +0200
committerGuillaume Gomez <guillaume1.gomez@gmail.com>2019-05-18 12:45:29 +0200
commitb5d4bd2a07218a6cd61bace73d7910a3f1a117c4 (patch)
tree67d32e298d1c6b37f4fdec0fa0df93a7dd527cf6
parent548add7f61bfcbe3bea3f5ccefb53c84da8fefe4 (diff)
downloadrust-b5d4bd2a07218a6cd61bace73d7910a3f1a117c4.tar.gz
rust-b5d4bd2a07218a6cd61bace73d7910a3f1a117c4.zip
Fix lints handling in rustdoc
-rw-r--r--src/librustc/lint/mod.rs3
-rw-r--r--src/librustdoc/clean/mod.rs7
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs34
-rw-r--r--src/librustdoc/passes/mod.rs19
-rw-r--r--src/test/rustdoc-ui/lint-missing-doc-code-example.rs39
-rw-r--r--src/test/rustdoc-ui/lint-missing-doc-code-example.stderr0
6 files changed, 85 insertions, 17 deletions
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 68b65f9b4a1..9c4683e0946 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -778,6 +778,9 @@ fn lint_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum)
 
     let push = builder.levels.push(&krate.attrs);
     builder.levels.register_id(hir::CRATE_HIR_ID);
+    for macro_def in &krate.exported_macros {
+       builder.levels.register_id(macro_def.hir_id);
+    }
     intravisit::walk_crate(&mut builder, krate);
     builder.levels.pop(push);
 
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index e9ccc61280b..7fe3aecca10 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -3405,6 +3405,7 @@ pub struct Span {
     pub locol: usize,
     pub hiline: usize,
     pub hicol: usize,
+    pub original: syntax_pos::Span,
 }
 
 impl Span {
@@ -3413,8 +3414,13 @@ impl Span {
             filename: FileName::Anon(0),
             loline: 0, locol: 0,
             hiline: 0, hicol: 0,
+            original: syntax_pos::DUMMY_SP,
         }
     }
+
+    pub fn span(&self) -> syntax_pos::Span {
+        self.original
+    }
 }
 
 impl Clean<Span> for syntax_pos::Span {
@@ -3433,6 +3439,7 @@ impl Clean<Span> for syntax_pos::Span {
             locol: lo.col.to_usize(),
             hiline: hi.line,
             hicol: hi.col.to_usize(),
+            original: *self,
         }
     }
 }
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 9e108e605c8..2c382a1c175 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -321,7 +321,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
                         if let Ok(res) = self.resolve(path_str, ns, &current_item, parent_node) {
                             res
                         } else {
-                            resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
+                            resolution_failure(cx, &item, path_str, &dox, link_range);
                             // This could just be a normal link or a broken link
                             // we could potentially check if something is
                             // "intra-doc-link-like" and warn in that case.
@@ -332,7 +332,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
                         if let Ok(res) = self.resolve(path_str, ns, &current_item, parent_node) {
                             res
                         } else {
-                            resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
+                            resolution_failure(cx, &item, path_str, &dox, link_range);
                             // This could just be a normal link.
                             continue;
                         }
@@ -357,7 +357,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
                         };
 
                         if candidates.is_empty() {
-                            resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
+                            resolution_failure(cx, &item, path_str, &dox, link_range);
                             // this could just be a normal link
                             continue;
                         }
@@ -368,7 +368,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
                         } else {
                             ambiguity_error(
                                 cx,
-                                &item.attrs,
+                                &item,
                                 path_str,
                                 &dox,
                                 link_range,
@@ -381,7 +381,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
                         if let Some(res) = macro_resolve(cx, path_str) {
                             (res, None)
                         } else {
-                            resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
+                            resolution_failure(cx, &item, path_str, &dox, link_range);
                             continue
                         }
                     }
@@ -452,16 +452,24 @@ fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option<Res> {
 /// line containing the failure as a note as well.
 fn resolution_failure(
     cx: &DocContext<'_>,
-    attrs: &Attributes,
+    item: &Item,
     path_str: &str,
     dox: &str,
     link_range: Option<Range<usize>>,
 ) {
+    let hir_id = match cx.as_local_hir_id(item.def_id) {
+        Some(hir_id) => hir_id,
+        None => {
+            // If non-local, no need to check anything.
+            return;
+        }
+    };
+    let attrs = &item.attrs;
     let sp = span_of_attrs(attrs);
 
     let mut diag = cx.tcx.struct_span_lint_hir(
         lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
-        hir::CRATE_HIR_ID,
+        hir_id,
         sp,
         &format!("`[{}]` cannot be resolved, ignoring it...", path_str),
     );
@@ -495,12 +503,20 @@ fn resolution_failure(
 
 fn ambiguity_error(
     cx: &DocContext<'_>,
-    attrs: &Attributes,
+    item: &Item,
     path_str: &str,
     dox: &str,
     link_range: Option<Range<usize>>,
     candidates: PerNS<Option<Res>>,
 ) {
+    let hir_id = match cx.as_local_hir_id(item.def_id) {
+        Some(hir_id) => hir_id,
+        None => {
+            // If non-local, no need to check anything.
+            return;
+        }
+    };
+    let attrs = &item.attrs;
     let sp = span_of_attrs(attrs);
 
     let mut msg = format!("`{}` is ", path_str);
@@ -532,7 +548,7 @@ fn ambiguity_error(
 
     let mut diag = cx.tcx.struct_span_lint_hir(
         lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
-        hir::CRATE_HIR_ID,
+        hir_id,
         sp,
         &msg,
     );
diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs
index 99aca063471..d9af33ac5b6 100644
--- a/src/librustdoc/passes/mod.rs
+++ b/src/librustdoc/passes/mod.rs
@@ -1,7 +1,6 @@
 //! Contains information about "passes", used to modify crate information during the documentation
 //! process.
 
-use rustc::hir;
 use rustc::hir::def_id::DefId;
 use rustc::lint as lint;
 use rustc::middle::privacy::AccessLevels;
@@ -314,10 +313,13 @@ pub fn look_for_tests<'tcx>(
     item: &Item,
     check_missing_code: bool,
 ) {
-    if cx.as_local_hir_id(item.def_id).is_none() {
-        // If non-local, no need to check anything.
-        return;
-    }
+    let hir_id = match cx.as_local_hir_id(item.def_id) {
+        Some(hir_id) => hir_id,
+        None => {
+            // If non-local, no need to check anything.
+            return;
+        }
+    };
 
     struct Tests {
         found_tests: usize,
@@ -336,10 +338,11 @@ pub fn look_for_tests<'tcx>(
     find_testable_code(&dox, &mut tests, ErrorCodes::No);
 
     if check_missing_code == true && tests.found_tests == 0 {
+        let sp = span_of_attrs(&item.attrs).substitute_dummy(item.source.span());
         let mut diag = cx.tcx.struct_span_lint_hir(
             lint::builtin::MISSING_DOC_CODE_EXAMPLES,
-            hir::CRATE_HIR_ID,
-            span_of_attrs(&item.attrs),
+            hir_id,
+            sp,
             "Missing code example in this documentation");
         diag.emit();
     } else if check_missing_code == false &&
@@ -347,7 +350,7 @@ pub fn look_for_tests<'tcx>(
               !cx.renderinfo.borrow().access_levels.is_doc_reachable(item.def_id) {
         let mut diag = cx.tcx.struct_span_lint_hir(
             lint::builtin::PRIVATE_DOC_TESTS,
-            hir::CRATE_HIR_ID,
+            hir_id,
             span_of_attrs(&item.attrs),
             "Documentation test in private item");
         diag.emit();
diff --git a/src/test/rustdoc-ui/lint-missing-doc-code-example.rs b/src/test/rustdoc-ui/lint-missing-doc-code-example.rs
new file mode 100644
index 00000000000..3bb1a2b7bef
--- /dev/null
+++ b/src/test/rustdoc-ui/lint-missing-doc-code-example.rs
@@ -0,0 +1,39 @@
+#![deny(missing_docs)]
+#![deny(missing_doc_code_examples)]
+
+//! crate level doc
+//! ```
+//! println!("hello"):
+//! ```
+
+
+/// doc
+///
+/// ```
+/// println!("hello");
+/// ```
+fn test() {
+}
+
+#[allow(missing_docs)]
+mod module1 {
+}
+
+#[allow(missing_doc_code_examples)]
+/// doc
+mod module2 {
+
+  /// doc
+  pub fn test() {}
+}
+
+/// doc
+///
+/// ```
+/// println!("hello");
+/// ```
+pub mod module3 {
+
+  /// doc
+  pub fn test() {}
+}
diff --git a/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr b/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr