about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/middle/lint.rs71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs
index d156457ca88..50d127869e5 100644
--- a/src/librustc/middle/lint.rs
+++ b/src/librustc/middle/lint.rs
@@ -82,6 +82,9 @@ pub enum lint {
     dead_assignment,
     unused_mut,
     unnecessary_allocation,
+
+    missing_struct_doc,
+    missing_trait_doc,
 }
 
 pub fn level_to_str(lv: level) -> &'static str {
@@ -252,6 +255,20 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[
         desc: "detects unnecessary allocations that can be eliminated",
         default: warn
     }),
+
+    ("missing_struct_doc",
+     LintSpec {
+        lint: missing_struct_doc,
+        desc: "detects missing documentation for structs",
+        default: allow
+    }),
+
+    ("missing_trait_doc",
+     LintSpec {
+        lint: missing_trait_doc,
+        desc: "detects missing documentation for traits",
+        default: allow
+    }),
 ];
 
 /*
@@ -952,6 +969,58 @@ fn lint_unnecessary_allocations(cx: @mut Context) -> visit::vt<()> {
     })
 }
 
+fn lint_missing_struct_doc(cx: @mut Context) -> visit::vt<()> {
+    visit::mk_simple_visitor(@visit::SimpleVisitor {
+        visit_struct_field: |field| {
+            let mut has_doc = false;
+            for field.node.attrs.each |attr| {
+                if attr.node.is_sugared_doc {
+                    has_doc = true;
+                    break;
+                }
+            }
+            if !has_doc {
+                cx.span_lint(missing_struct_doc, field.span, "missing documentation \
+                                                              for a field.");
+            }
+        },
+        .. *visit::default_simple_visitor()
+    })
+}
+
+fn lint_missing_trait_doc(cx: @mut Context) -> visit::vt<()> {
+    visit::mk_simple_visitor(@visit::SimpleVisitor {
+        visit_trait_method: |method| {
+            let mut has_doc = false;
+            let span = match copy *method {
+                ast::required(m) => {
+                    for m.attrs.each |attr| {
+                        if attr.node.is_sugared_doc {
+                            has_doc = true;
+                            break;
+                        }
+                    }
+                    m.span
+                },
+                ast::provided(m) => {
+                    for m.attrs.each |attr| {
+                        if attr.node.is_sugared_doc {
+                            has_doc = true;
+                            break;
+                        }
+                    }
+                    m.span
+                }
+            };
+            if !has_doc {
+                cx.span_lint(missing_trait_doc, span, "missing documentation \
+                                                        for a method.");
+            }
+        },
+        .. *visit::default_simple_visitor()
+    })
+}
+
 pub fn check_crate(tcx: ty::ctxt, crate: @ast::crate) {
     let cx = @mut Context {
         dict: @get_lint_dict(),
@@ -980,6 +1049,8 @@ pub fn check_crate(tcx: ty::ctxt, crate: @ast::crate) {
     cx.add_lint(lint_unused_mut(cx));
     cx.add_lint(lint_session(cx));
     cx.add_lint(lint_unnecessary_allocations(cx));
+    cx.add_lint(lint_missing_struct_doc(cx));
+    cx.add_lint(lint_missing_trait_doc(cx));
 
     // type inference doesn't like this being declared below, we need to tell it
     // what the type of this first function is...