From 6ff697d3933754bf9ec5ee5875f487f02a7d087d Mon Sep 17 00:00:00 2001 From: klutzy Date: Tue, 5 Nov 2013 00:35:56 +0900 Subject: [PATCH] rustc: Add lint for misplaced crate attributes --- src/etc/extract-tests.py | 1 + src/librustc/middle/lint.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/etc/extract-tests.py b/src/etc/extract-tests.py index 736292337adc..5904e10a08db 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 473b7025cbf9..7ce560055a33 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, ());