summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorklutzy <klutzytheklutzy@gmail.com>2013-11-05 00:35:56 +0900
committerklutzy <klutzytheklutzy@gmail.com>2013-11-26 13:13:17 +0900
commit6ff697d3933754bf9ec5ee5875f487f02a7d087d (patch)
treedd79082747c9ef9ca841dc6c41a02db997cc25f9 /src
parentffaee0fd96b5d23ae9668605d1425111f4210c58 (diff)
downloadrust-6ff697d3933754bf9ec5ee5875f487f02a7d087d.tar.gz
rust-6ff697d3933754bf9ec5ee5875f487f02a7d087d.zip
rustc: Add lint for misplaced crate attributes
Diffstat (limited to 'src')
-rw-r--r--src/etc/extract-tests.py1
-rw-r--r--src/librustc/middle/lint.rs30
2 files changed, 31 insertions, 0 deletions
diff --git a/src/etc/extract-tests.py b/src/etc/extract-tests.py
index 736292337ad..5904e10a08d 100644
--- a/src/etc/extract-tests.py
+++ b/src/etc/extract-tests.py
@@ -63,6 +63,7 @@ while cur < len(lines):
 #[ allow(unused_variable) ];\n
 #[ allow(dead_assignment) ];\n
 #[ allow(unused_mut) ];\n
+#[ allow(attribute_usage) ];\n
 #[ feature(macro_rules, globs, struct_variant, managed_boxes) ];\n
 """ + block
             if xfail:
diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs
index 473b7025cbf..7ce560055a3 100644
--- a/src/librustc/middle/lint.rs
+++ b/src/librustc/middle/lint.rs
@@ -76,6 +76,7 @@ pub enum lint {
     type_overflow,
     unused_unsafe,
     unsafe_block,
+    attribute_usage,
 
     managed_heap_memory,
     owned_heap_memory,
@@ -244,6 +245,13 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[
         default: allow
     }),
 
+    ("attribute_usage",
+     LintSpec {
+        lint: attribute_usage,
+        desc: "detects bad use of attributes",
+        default: warn
+    }),
+
     ("unused_variable",
      LintSpec {
         lint: unused_variable,
@@ -790,6 +798,27 @@ fn check_heap_item(cx: &Context, it: &ast::item) {
     }
 }
 
+// check if crate-level attribute is used on item,
+// since it is usually caused by mistake of semicolon omission.
+// also make error on obsolete attributes for less confusion.
+fn check_item_attribute_usage(cx: &Context, it: &ast::item) {
+    let crate_attrs = ["crate_type", "link", "feature", "no_uv", "no_main", "no_std"];
+
+    for attr in it.attrs.iter() {
+        let name = attr.node.value.name();
+        for crate_attr in crate_attrs.iter() {
+            if name.equiv(crate_attr) {
+                let msg = match attr.node.style {
+                    ast::AttrOuter  => "crate-level attribute should be an inner attribute: \
+                                   add semicolon at end",
+                    ast::AttrInner => "crate-level attribute should be in the root module",
+                };
+                cx.span_lint(attribute_usage, attr.span, msg);
+            }
+        }
+    }
+}
+
 fn check_heap_expr(cx: &Context, e: &ast::Expr) {
     let ty = ty::expr_ty(cx.tcx, e);
     check_heap_type(cx, e.span, ty);
@@ -1110,6 +1139,7 @@ impl<'self> Visitor<()> for Context<'self> {
             check_item_non_uppercase_statics(cx, it);
             check_heap_item(cx, it);
             check_missing_doc_item(cx, it);
+            check_item_attribute_usage(cx, it);
 
             do cx.visit_ids |v| {
                 v.visit_item(it, ());