]> git.lizzy.rs Git - rust.git/commitdiff
rustc: Add crate-level attribute lint
authorklutzy <klutzytheklutzy@gmail.com>
Mon, 25 Nov 2013 15:22:40 +0000 (00:22 +0900)
committerklutzy <klutzytheklutzy@gmail.com>
Tue, 26 Nov 2013 05:07:48 +0000 (14:07 +0900)
src/librustc/middle/lint.rs
src/test/compile-fail/lint-unknown-attr.rs

index 42dbe3f6d9ecb0da47fd0660903223b2874ba4fc..d67677f07835b9fb6f25d61036b85df0eccd8911 100644 (file)
@@ -798,43 +798,55 @@ fn check_heap_item(cx: &Context, it: &ast::item) {
     }
 }
 
+static crate_attrs: &'static [&'static str] = &[
+    "crate_type", "link", "feature", "no_uv", "no_main", "no_std",
+    "desc", "comment", "license", "copyright", // not used in rustc now
+];
+
+
+static obsolete_attrs: &'static [(&'static str, &'static str)] = &[
+    ("abi", "Use `extern \"abi\" fn` instead"),
+    ("auto_encode", "Use `#[deriving(Encodable)]` instead"),
+    ("auto_decode", "Use `#[deriving(Decodable)]` instead"),
+    ("fast_ffi", "Remove it"),
+    ("fixed_stack_segment", "Remove it"),
+    ("rust_stack", "Remove it"),
+];
+
+static other_attrs: &'static [&'static str] = &[
+    // item-level
+    "address_insignificant", // can be crate-level too
+    "allow", "deny", "forbid", "warn", // lint options
+    "deprecated", "experimental", "unstable", "stable", "locked", "frozen", //item stability
+    "crate_map", "cfg", "doc", "export_name", "link_section", "no_freeze",
+    "no_mangle", "no_send", "static_assert", "unsafe_no_drop_flag",
+    "packed", "simd", "repr", "deriving", "unsafe_destructor",
+
+    //mod-level
+    "path", "link_name", "link_args", "nolink", "macro_escape", "no_implicit_prelude",
+
+    // fn-level
+    "test", "bench", "should_fail", "ignore", "inline", "lang", "main", "start",
+    "no_split_stack", "cold",
+
+    // internal attribute: bypass privacy inside items
+    "!resolve_unexported",
+];
+
+fn check_crate_attrs_usage(cx: &Context, attrs: &[ast::Attribute]) {
+
+    for attr in attrs.iter() {
+        let name = attr.node.value.name();
+        let mut iter = crate_attrs.iter().chain(other_attrs.iter());
+        if !iter.any(|other_attr| { name.equiv(other_attr) }) {
+            cx.span_lint(attribute_usage, attr.span, "unknown crate attribute");
+        }
+    }
+}
+
 fn check_attrs_usage(cx: &Context, attrs: &[ast::Attribute]) {
     // check if element has crate-level, obsolete, or any unknown attributes.
 
-    let crate_attrs = [
-        "crate_type", "link", "feature", "no_uv", "no_main", "no_std",
-        "comment", "license", "copyright", // not used in rustc now
-    ];
-
-    let obsolete_attrs = [
-        ("abi", "Use `extern \"abi\" fn` instead"),
-        ("auto_encode", "Use `#[deriving(Encodable)]` instead"),
-        ("auto_decode", "Use `#[deriving(Decodable)]` instead"),
-        ("fast_ffi", "Remove it"),
-        ("fixed_stack_segment", "Remove it"),
-        ("rust_stack", "Remove it"),
-    ];
-
-    let other_attrs = [
-        // item-level
-        "address_insignificant", // can be crate-level too
-        "allow", "deny", "forbid", "warn", // lint options
-        "deprecated", "experimental", "unstable", "stable", "locked", "frozen", //item stability
-        "crate_map", "cfg", "doc", "export_name", "link_section", "no_freeze",
-        "no_mangle", "no_send", "static_assert", "unsafe_no_drop_flag",
-        "packed", "simd", "repr", "deriving", "unsafe_destructor",
-
-        // mod-level
-        "path", "link_name", "link_args", "nolink", "macro_escape", "no_implicit_prelude",
-
-        // fn-level
-        "test", "bench", "should_fail", "ignore", "inline", "lang", "main", "start",
-        "no_split_stack", "cold",
-
-        // internal attribute: bypass privacy inside items
-        "!resolve_unexported",
-    ];
-
     for attr in attrs.iter() {
         let name = attr.node.value.name();
         for crate_attr in crate_attrs.iter() {
@@ -1349,6 +1361,9 @@ pub fn check_crate(tcx: ty::ctxt,
             v.visited_outermost = true;
             visit::walk_crate(v, crate, ());
         }
+
+        check_crate_attrs_usage(cx, crate.attrs);
+
         visit::walk_crate(cx, crate, ());
     }
 
index 2ec7706addfed8826878982cc24846d7a9e9bf88..ce83ba464c06eb3773da3faa2afb618867335f6f 100644 (file)
@@ -13,6 +13,8 @@
 
 #[deny(attribute_usage)];
 
+#[mutable_doc]; //~ ERROR: unknown crate attribute
+
 #[dance] mod a {} //~ ERROR: unknown attribute
 
 #[dance] fn main() {} //~ ERROR: unknown attribute