@@ -35,6 +35,8 @@ use crate::{
35
35
} ;
36
36
37
37
mod allow {
38
+ pub ( super ) const BAD_STYLE : & str = "bad_style" ;
39
+ pub ( super ) const NONSTANDARD_STYLE : & str = "nonstandard_style" ;
38
40
pub ( super ) const NON_SNAKE_CASE : & str = "non_snake_case" ;
39
41
pub ( super ) const NON_UPPER_CASE_GLOBAL : & str = "non_upper_case_globals" ;
40
42
pub ( super ) const NON_CAMEL_CASE_TYPES : & str = "non_camel_case_types" ;
@@ -83,10 +85,39 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
83
85
}
84
86
85
87
/// Checks whether not following the convention is allowed for this item.
86
- ///
87
- /// Currently this method doesn't check parent attributes.
88
- fn allowed ( & self , id : AttrDefId , allow_name : & str ) -> bool {
89
- self . db . attrs ( id) . by_key ( "allow" ) . tt_values ( ) . any ( |tt| tt. to_string ( ) . contains ( allow_name) )
88
+ fn allowed ( & self , id : AttrDefId , allow_name : & str , recursing : bool ) -> bool {
89
+ let is_allowed = |def_id| {
90
+ let attrs = self . db . attrs ( def_id) ;
91
+ // don't bug the user about directly no_mangle annotated stuff, they can't do anything about it
92
+ ( !recursing && attrs. by_key ( "no_mangle" ) . exists ( ) )
93
+ || attrs. by_key ( "allow" ) . tt_values ( ) . any ( |tt| {
94
+ let allows = tt. to_string ( ) ;
95
+ allows. contains ( allow_name)
96
+ || allows. contains ( allow:: BAD_STYLE )
97
+ || allows. contains ( allow:: NONSTANDARD_STYLE )
98
+ } )
99
+ } ;
100
+
101
+ is_allowed ( id)
102
+ // go upwards one step or give up
103
+ || match id {
104
+ AttrDefId :: ModuleId ( m) => m. containing_module ( self . db . upcast ( ) ) . map ( |v| v. into ( ) ) ,
105
+ AttrDefId :: FunctionId ( f) => Some ( f. lookup ( self . db . upcast ( ) ) . container . into ( ) ) ,
106
+ AttrDefId :: StaticId ( sid) => Some ( sid. lookup ( self . db . upcast ( ) ) . container . into ( ) ) ,
107
+ AttrDefId :: ConstId ( cid) => Some ( cid. lookup ( self . db . upcast ( ) ) . container . into ( ) ) ,
108
+ AttrDefId :: TraitId ( tid) => Some ( tid. lookup ( self . db . upcast ( ) ) . container . into ( ) ) ,
109
+ AttrDefId :: ImplId ( iid) => Some ( iid. lookup ( self . db . upcast ( ) ) . container . into ( ) ) ,
110
+ // These warnings should not explore macro definitions at all
111
+ AttrDefId :: MacroDefId ( _) => None ,
112
+ // Will never occur under an enum/struct/union/type alias
113
+ AttrDefId :: AdtId ( _) => None ,
114
+ AttrDefId :: FieldId ( _) => None ,
115
+ AttrDefId :: EnumVariantId ( _) => None ,
116
+ AttrDefId :: TypeAliasId ( _) => None ,
117
+ AttrDefId :: GenericParamId ( _) => None ,
118
+ }
119
+ . map ( |mid| self . allowed ( mid, allow_name, true ) )
120
+ . unwrap_or ( false )
90
121
}
91
122
92
123
fn validate_func ( & mut self , func : FunctionId ) {
@@ -109,7 +140,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
109
140
}
110
141
111
142
// Check whether non-snake case identifiers are allowed for this function.
112
- if self . allowed ( func. into ( ) , allow:: NON_SNAKE_CASE ) {
143
+ if self . allowed ( func. into ( ) , allow:: NON_SNAKE_CASE , false ) {
113
144
return ;
114
145
}
115
146
@@ -328,8 +359,9 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
328
359
fn validate_struct ( & mut self , struct_id : StructId ) {
329
360
let data = self . db . struct_data ( struct_id) ;
330
361
331
- let non_camel_case_allowed = self . allowed ( struct_id. into ( ) , allow:: NON_CAMEL_CASE_TYPES ) ;
332
- let non_snake_case_allowed = self . allowed ( struct_id. into ( ) , allow:: NON_SNAKE_CASE ) ;
362
+ let non_camel_case_allowed =
363
+ self . allowed ( struct_id. into ( ) , allow:: NON_CAMEL_CASE_TYPES , false ) ;
364
+ let non_snake_case_allowed = self . allowed ( struct_id. into ( ) , allow:: NON_SNAKE_CASE , false ) ;
333
365
334
366
// Check the structure name.
335
367
let struct_name = data. name . to_string ( ) ;
@@ -461,7 +493,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
461
493
let data = self . db . enum_data ( enum_id) ;
462
494
463
495
// Check whether non-camel case names are allowed for this enum.
464
- if self . allowed ( enum_id. into ( ) , allow:: NON_CAMEL_CASE_TYPES ) {
496
+ if self . allowed ( enum_id. into ( ) , allow:: NON_CAMEL_CASE_TYPES , false ) {
465
497
return ;
466
498
}
467
499
@@ -584,7 +616,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
584
616
fn validate_const ( & mut self , const_id : ConstId ) {
585
617
let data = self . db . const_data ( const_id) ;
586
618
587
- if self . allowed ( const_id. into ( ) , allow:: NON_UPPER_CASE_GLOBAL ) {
619
+ if self . allowed ( const_id. into ( ) , allow:: NON_UPPER_CASE_GLOBAL , false ) {
588
620
return ;
589
621
}
590
622
@@ -632,7 +664,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
632
664
return ;
633
665
}
634
666
635
- if self . allowed ( static_id. into ( ) , allow:: NON_UPPER_CASE_GLOBAL ) {
667
+ if self . allowed ( static_id. into ( ) , allow:: NON_UPPER_CASE_GLOBAL , false ) {
636
668
return ;
637
669
}
638
670
@@ -869,10 +901,36 @@ fn main() {
869
901
r#"
870
902
#[allow(non_snake_case)]
871
903
fn NonSnakeCaseName(SOME_VAR: u8) -> u8{
904
+ // cov_flags generated output from elsewhere in this file
905
+ extern "C" {
906
+ #[no_mangle]
907
+ static lower_case: u8;
908
+ }
909
+
872
910
let OtherVar = SOME_VAR + 1;
873
911
OtherVar
874
912
}
875
913
914
+ #[allow(nonstandard_style)]
915
+ mod CheckNonstandardStyle {
916
+ fn HiImABadFnName() {}
917
+ }
918
+
919
+ #[allow(bad_style)]
920
+ mod CheckBadStyle {
921
+ fn HiImABadFnName() {}
922
+ }
923
+
924
+ mod F {
925
+ #![allow(non_snake_case)]
926
+ fn CheckItWorksWithModAttr(BAD_NAME_HI: u8) {}
927
+ }
928
+
929
+ trait BAD_TRAIT {
930
+ fn BAD_FUNCTION();
931
+ fn BadFunction();
932
+ }
933
+
876
934
#[allow(non_snake_case, non_camel_case_types)]
877
935
pub struct some_type {
878
936
SOME_FIELD: u8,
@@ -888,6 +946,60 @@ fn main() {
888
946
) ;
889
947
}
890
948
949
+ #[ test]
950
+ fn allow_attributes_crate_attr ( ) {
951
+ check_diagnostics (
952
+ r#"
953
+ #![allow(non_snake_case)]
954
+
955
+ mod F {
956
+ fn CheckItWorksWithCrateAttr(BAD_NAME_HI: u8) {}
957
+ }
958
+
959
+ "# ,
960
+ ) ;
961
+ }
962
+
963
+ #[ test]
964
+ #[ ignore]
965
+ fn bug_trait_inside_fn ( ) {
966
+ // FIXME:
967
+ // This is broken, and in fact, should not even be looked at by this
968
+ // lint in the first place. There's weird stuff going on in the
969
+ // collection phase.
970
+ // It's currently being brought in by:
971
+ // * validate_func on `a` recursing into modules
972
+ // * then it finds the trait and then the function while iterating
973
+ // through modules
974
+ // * then validate_func is called on Dirty
975
+ // * ... which then proceeds to look at some unknown module taking no
976
+ // attrs from either the impl or the fn a, and then finally to the root
977
+ // module
978
+ //
979
+ // It should find the attribute on the trait, but it *doesn't even see
980
+ // the trait* as far as I can tell.
981
+
982
+ check_diagnostics (
983
+ r#"
984
+ trait T { fn a(); }
985
+ struct U {}
986
+ impl T for U {
987
+ fn a() {
988
+ // this comes out of bitflags, mostly
989
+ #[allow(non_snake_case)]
990
+ trait __BitFlags {
991
+ const HiImAlsoBad: u8 = 2;
992
+ #[inline]
993
+ fn Dirty(&self) -> bool {
994
+ false
995
+ }
996
+ }
997
+
998
+ }
999
+ }"# ,
1000
+ ) ;
1001
+ }
1002
+
891
1003
#[ test]
892
1004
fn ignores_extern_items ( ) {
893
1005
cov_mark:: check!( extern_func_incorrect_case_ignored) ;
0 commit comments