about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-12-05 23:41:19 -0800
committerbors <bors@rust-lang.org>2013-12-05 23:41:19 -0800
commit2eb22ae2b400c99966dad07145a541ce8c2586fb (patch)
treeea67cf212c1370b85690003bc4dec5904c06e2a8
parentf9aecdb22ad95c7be37c6e2e45dce2242f6a59d9 (diff)
parent30a5612830a430e8534f32a9ea14bc3dfdc0e55d (diff)
downloadrust-2eb22ae2b400c99966dad07145a541ce8c2586fb.tar.gz
rust-2eb22ae2b400c99966dad07145a541ce8c2586fb.zip
auto merge of #10665 : cmr/rust/doc_lint, r=alexcrichton
Because the root module isn't actually an item, we need to do some hackish
handling of it.

Closes #10656.
-rw-r--r--src/librustc/middle/lint.rs26
-rw-r--r--src/libsyntax/visit.rs1
-rw-r--r--src/test/compile-fail/issue-10656.rs14
-rw-r--r--src/test/compile-fail/lint-missing-doc.rs3
4 files changed, 34 insertions, 10 deletions
diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs
index b01ea851a1e..942d9b957ae 100644
--- a/src/librustc/middle/lint.rs
+++ b/src/librustc/middle/lint.rs
@@ -1048,7 +1048,7 @@ fn check_unnecessary_allocation(cx: &Context, e: &ast::Expr) {
 }
 
 fn check_missing_doc_attrs(cx: &Context,
-                           id: ast::NodeId,
+                           id: Option<ast::NodeId>,
                            attrs: &[ast::Attribute],
                            sp: Span,
                            desc: &'static str) {
@@ -1059,9 +1059,12 @@ fn check_missing_doc_attrs(cx: &Context,
     // `#[doc(hidden)]` disables missing_doc check.
     if cx.is_doc_hidden { return }
 
-    // Only check publicly-visible items, using the result from the
-    // privacy pass.
-    if !cx.exported_items.contains(&id) { return }
+    // Only check publicly-visible items, using the result from the privacy pass. It's an option so
+    // the crate root can also use this function (it doesn't have a NodeId).
+    match id {
+        Some(ref id) if !cx.exported_items.contains(id) => return,
+        _ => ()
+    }
 
     if !attrs.iter().any(|a| a.node.is_sugared_doc) {
         cx.span_lint(missing_doc, sp,
@@ -1069,7 +1072,7 @@ fn check_missing_doc_attrs(cx: &Context,
     }
 }
 
-fn check_missing_doc_item(cx: &mut Context, it: &ast::item) { // XXX doesn't need to be mut
+fn check_missing_doc_item(cx: &Context, it: &ast::item) {
     let desc = match it.node {
         ast::item_fn(..) => "a function",
         ast::item_mod(..) => "a module",
@@ -1078,7 +1081,7 @@ fn check_missing_doc_item(cx: &mut Context, it: &ast::item) { // XXX doesn't nee
         ast::item_trait(..) => "a trait",
         _ => return
     };
-    check_missing_doc_attrs(cx, it.id, it.attrs, it.span, desc);
+    check_missing_doc_attrs(cx, Some(it.id), it.attrs, it.span, desc);
 }
 
 fn check_missing_doc_method(cx: &Context, m: &ast::method) {
@@ -1104,24 +1107,24 @@ fn check_missing_doc_method(cx: &Context, m: &ast::method) {
             }
         }
     }
-    check_missing_doc_attrs(cx, m.id, m.attrs, m.span, "a method");
+    check_missing_doc_attrs(cx, Some(m.id), m.attrs, m.span, "a method");
 }
 
 fn check_missing_doc_ty_method(cx: &Context, tm: &ast::TypeMethod) {
-    check_missing_doc_attrs(cx, tm.id, tm.attrs, tm.span, "a type method");
+    check_missing_doc_attrs(cx, Some(tm.id), tm.attrs, tm.span, "a type method");
 }
 
 fn check_missing_doc_struct_field(cx: &Context, sf: &ast::struct_field) {
     match sf.node.kind {
         ast::named_field(_, vis) if vis != ast::private =>
-            check_missing_doc_attrs(cx, cx.cur_struct_def_id, sf.node.attrs,
+            check_missing_doc_attrs(cx, Some(cx.cur_struct_def_id), sf.node.attrs,
                                     sf.span, "a struct field"),
         _ => {}
     }
 }
 
 fn check_missing_doc_variant(cx: &Context, v: &ast::variant) {
-    check_missing_doc_attrs(cx, v.node.id, v.node.attrs, v.span, "a variant");
+    check_missing_doc_attrs(cx, Some(v.node.id), v.node.attrs, v.span, "a variant");
 }
 
 /// Checks for use of items with #[deprecated], #[experimental] and
@@ -1372,6 +1375,9 @@ pub fn check_crate(tcx: ty::ctxt,
         });
 
         check_crate_attrs_usage(cx, crate.attrs);
+        // since the root module isn't visited as an item (because it isn't an item), warn for it
+        // here.
+        check_missing_doc_attrs(cx, None, crate.attrs, crate.span, "crate");
 
         visit::walk_crate(cx, crate, ());
     });
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index f19a99ffcee..985dcd27271 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -130,6 +130,7 @@ pub fn walk_mod<E:Clone, V:Visitor<E>>(visitor: &mut V, module: &_mod, env: E) {
     for view_item in module.view_items.iter() {
         visitor.visit_view_item(view_item, env.clone())
     }
+
     for item in module.items.iter() {
         visitor.visit_item(*item, env.clone())
     }
diff --git a/src/test/compile-fail/issue-10656.rs b/src/test/compile-fail/issue-10656.rs
new file mode 100644
index 00000000000..ca88c260e93
--- /dev/null
+++ b/src/test/compile-fail/issue-10656.rs
@@ -0,0 +1,14 @@
+// Copyright 2013 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.
+
+// error-pattern: missing documentation for crate
+
+#[deny(missing_doc)];
+#[crate_type="lib"];
diff --git a/src/test/compile-fail/lint-missing-doc.rs b/src/test/compile-fail/lint-missing-doc.rs
index 10c27adde22..12d9cbe0dbc 100644
--- a/src/test/compile-fail/lint-missing-doc.rs
+++ b/src/test/compile-fail/lint-missing-doc.rs
@@ -14,6 +14,9 @@
 #[feature(globs)];
 #[deny(missing_doc)];
 
+//! Some garbage docs for the crate here
+#[doc="More garbage"];
+
 struct Foo {
     a: int,
     priv b: int,