@@ -76,6 +76,7 @@ pub enum lint {
76
76
type_overflow,
77
77
unused_unsafe,
78
78
unsafe_block,
79
+ attribute_usage,
79
80
80
81
managed_heap_memory,
81
82
owned_heap_memory,
@@ -244,6 +245,13 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[
244
245
default : allow
245
246
} ) ,
246
247
248
+ ( "attribute_usage" ,
249
+ LintSpec {
250
+ lint : attribute_usage,
251
+ desc : "detects bad use of attributes" ,
252
+ default : warn
253
+ } ) ,
254
+
247
255
( "unused_variable" ,
248
256
LintSpec {
249
257
lint : unused_variable,
@@ -790,6 +798,27 @@ fn check_heap_item(cx: &Context, it: &ast::item) {
790
798
}
791
799
}
792
800
801
+ // check if crate-level attribute is used on item,
802
+ // since it is usually caused by mistake of semicolon omission.
803
+ // also make error on obsolete attributes for less confusion.
804
+ fn check_item_attribute_usage ( cx : & Context , it : & ast:: item ) {
805
+ let crate_attrs = [ "crate_type" , "link" , "feature" , "no_uv" , "no_main" , "no_std" ] ;
806
+
807
+ for attr in it. attrs . iter ( ) {
808
+ let name = attr. node . value . name ( ) ;
809
+ for crate_attr in crate_attrs. iter ( ) {
810
+ if name. equiv ( crate_attr) {
811
+ let msg = match attr. node . style {
812
+ ast:: AttrOuter => "crate-level attribute should be an inner attribute: \
813
+ add semicolon at end",
814
+ ast:: AttrInner => "crate-level attribute should be in the root module" ,
815
+ } ;
816
+ cx. span_lint ( attribute_usage, attr. span , msg) ;
817
+ }
818
+ }
819
+ }
820
+ }
821
+
793
822
fn check_heap_expr ( cx : & Context , e : & ast:: Expr ) {
794
823
let ty = ty:: expr_ty ( cx. tcx , e) ;
795
824
check_heap_type ( cx, e. span , ty) ;
@@ -1110,6 +1139,7 @@ impl<'self> Visitor<()> for Context<'self> {
1110
1139
check_item_non_uppercase_statics ( cx, it) ;
1111
1140
check_heap_item ( cx, it) ;
1112
1141
check_missing_doc_item ( cx, it) ;
1142
+ check_item_attribute_usage ( cx, it) ;
1113
1143
1114
1144
do cx. visit_ids |v| {
1115
1145
v. visit_item ( it, ( ) ) ;
0 commit comments