@@ -2,12 +2,10 @@ use clippy_utils::{
2
2
diagnostics:: { span_lint_and_help, span_lint_and_sugg, span_lint_and_then} ,
3
3
source:: { indent_of, snippet} ,
4
4
} ;
5
- use rustc_ast:: Attribute ;
6
5
use rustc_errors:: Applicability ;
7
6
use rustc_hir:: { HirId , Item , ItemKind } ;
8
7
use rustc_lint:: { LateContext , LateLintPass } ;
9
- use rustc_middle:: dep_graph:: DepContext ;
10
- use rustc_middle:: ty:: { self as ty_mod, Const , ReprFlags } ;
8
+ use rustc_middle:: ty:: { Const , TyS } ;
11
9
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
12
10
use rustc_span:: sym;
13
11
@@ -43,18 +41,28 @@ declare_lint_pass!(TrailingZeroSizedArrayWithoutRepr => [TRAILING_ZERO_SIZED_ARR
43
41
impl < ' tcx > LateLintPass < ' tcx > for TrailingZeroSizedArrayWithoutRepr {
44
42
fn check_item ( & mut self , cx : & LateContext < ' tcx > , item : & ' tcx Item < ' tcx > ) {
45
43
dbg ! ( item. ident) ;
46
- if is_struct_with_trailing_zero_sized_array ( cx, item) && !has_repr_attr ( cx, item) {
47
- eprintln ! ( "consider yourself linted 😎" ) ;
48
- // span_lint_and_help(
49
- // cx,
50
- // TRAILING_ZERO_SIZED_ARRAY_WITHOUT_REPR,
51
- // item.span,
52
- // "trailing zero-sized array in a struct which is not marked with a `repr`
53
- // attribute",
54
- // None,
55
- // "consider annotating the struct definition with `#[repr(C)]` or another
56
- // `repr` attribute",
57
- // );
44
+ if is_struct_with_trailing_zero_sized_array ( cx, item) && !has_repr_attr ( cx, item. hir_id ( ) ) {
45
+ let help_msg = format ! (
46
+ "consider annotating {} with `#[repr(C)]` or another `repr` attribute" ,
47
+ cx. tcx
48
+ . type_of( item. def_id)
49
+ . ty_adt_def( )
50
+ . map( |adt_def| cx. tcx. def_path_str( adt_def. did) )
51
+ . unwrap_or_else(
52
+ // I don't think this will ever be the case, since we made it through
53
+ // `is_struct_with_trailing_zero_sized_array`, but I don't feel comfortable putting an `unwrap`
54
+ || "the struct definition" . to_string( )
55
+ )
56
+ ) ;
57
+
58
+ span_lint_and_help (
59
+ cx,
60
+ TRAILING_ZERO_SIZED_ARRAY_WITHOUT_REPR ,
61
+ item. span ,
62
+ "trailing zero-sized array in a struct which is not marked with a `repr` attribute" ,
63
+ None ,
64
+ & help_msg,
65
+ ) ;
58
66
}
59
67
}
60
68
}
@@ -83,52 +91,9 @@ fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'tcx>, item: &'tcx
83
91
}
84
92
}
85
93
86
- fn has_repr_attr ( cx : & LateContext < ' tcx > , item : & ' tcx Item < ' tcx > ) -> bool {
94
+ fn has_repr_attr ( cx : & LateContext < ' tcx > , hir_id : HirId ) -> bool {
87
95
// NOTE: there's at least four other ways to do this but I liked this one the best. (All five agreed
88
- // on all testcases (when i wrote this comment. I added a few since then) .) Happy to use another;
96
+ // on all testcases.) Happy to use another;
89
97
// they're in the commit history if you want to look (or I can go find them).
90
-
91
- let attrs1 = cx. tcx . hir ( ) . attrs ( item. hir_id ( ) ) ;
92
- let attrs2 = cx. tcx . get_attrs ( item. def_id . to_def_id ( ) ) ;
93
-
94
- let res11 = {
95
- let sess = cx. tcx . sess ( ) ; // are captured values in closures evaluated once or every time?
96
- attrs1
97
- . iter ( )
98
- . any ( |attr| !rustc_attr:: find_repr_attrs ( sess, attr) . is_empty ( ) )
99
- } ;
100
- let res12 = { attrs1. iter ( ) . any ( |attr| attr. has_name ( sym:: repr) ) } ;
101
-
102
- let res21 = {
103
- let sess = cx. tcx . sess ( ) ; // are captured values in closures evaluated once or every time?
104
- attrs2
105
- . iter ( )
106
- . any ( |attr| !rustc_attr:: find_repr_attrs ( sess, attr) . is_empty ( ) )
107
- } ;
108
- let res22 = { attrs2. iter ( ) . any ( |attr| attr. has_name ( sym:: repr) ) } ;
109
-
110
- let res_adt = {
111
- let ty = cx. tcx . type_of ( item. def_id . to_def_id ( ) ) ;
112
- if let ty_mod:: Adt ( adt, _) = ty. kind ( ) {
113
- if adt. is_struct ( ) {
114
- let repr = adt. repr ;
115
- let repr_attr = ReprFlags :: IS_C | ReprFlags :: IS_TRANSPARENT | ReprFlags :: IS_SIMD | ReprFlags :: IS_LINEAR ;
116
- repr. int . is_some ( ) || repr. align . is_some ( ) || repr. pack . is_some ( ) || repr. flags . intersects ( repr_attr)
117
- } else {
118
- false
119
- }
120
- } else {
121
- false
122
- }
123
- } ;
124
-
125
- let all_same = ( res11 && res12 && res21 && res22 && res_adt) || ( !res11 && !res12 && !res21 && !res22 && !res_adt) ;
126
-
127
-
128
- dbg ! ( (
129
- ( res11, res12, res21, res22, res_adt) ,
130
- all_same,
131
- ) ) ;
132
-
133
- res12
98
+ cx. tcx . hir ( ) . attrs ( hir_id) . iter ( ) . any ( |attr| attr. has_name ( sym:: repr) )
134
99
}
0 commit comments