@@ -5,6 +5,7 @@ use rustc_errors::Applicability;
5
5
use rustc_hir:: { Item , ItemKind , TyKind , VariantData } ;
6
6
use rustc_lint:: { LateContext , LateLintPass } ;
7
7
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
8
+ use rustc_span:: sym;
8
9
9
10
declare_clippy_lint ! {
10
11
/// ### What it does
@@ -43,9 +44,8 @@ declare_lint_pass!(TrailingZeroSizedArrayWithoutReprC => [TRAILING_ZERO_SIZED_AR
43
44
44
45
impl < ' tcx > LateLintPass < ' tcx > for TrailingZeroSizedArrayWithoutReprC {
45
46
fn check_item ( & mut self , cx : & LateContext < ' tcx > , item : & ' tcx Item < ' tcx > ) {
46
- if is_struct_with_trailing_zero_sized_array ( cx, item)
47
- /* && !has_repr_c(cx, item) */
48
- {
47
+ dbg ! ( item. ident) ;
48
+ if is_struct_with_trailing_zero_sized_array ( cx, item) && !has_repr_c ( cx, item) {
49
49
// span_lint_and_sugg(
50
50
// cx,
51
51
// todo!(),
@@ -61,33 +61,52 @@ impl<'tcx> LateLintPass<'tcx> for TrailingZeroSizedArrayWithoutReprC {
61
61
}
62
62
63
63
fn is_struct_with_trailing_zero_sized_array ( cx : & LateContext < ' tcx > , item : & ' tcx Item < ' tcx > ) -> bool {
64
- dbg ! ( item. ident) ;
65
- if_chain ! {
66
- if let ItemKind :: Struct ( data, _generics) = & item. kind;
67
- if let VariantData :: Struct ( field_defs, _) = data;
68
- if let Some ( last_field) = field_defs. last( ) ;
69
- if let TyKind :: Array ( _, aconst) = last_field. ty. kind;
70
- let aconst_def_id = cx. tcx. hir( ) . body_owner_def_id( aconst. body) . to_def_id( ) ;
71
- let ty = cx. tcx. type_of( aconst_def_id) ;
72
- let constant = cx
73
- . tcx
74
- . const_eval_poly( aconst_def_id) // NOTE: maybe const_eval_resolve? seems especially cursed to be using a const expr which resolves to 0 to create a zero-sized array, tho
75
- . ok( )
76
- . map( |val| rustc_middle:: ty:: Const :: from_value( cx. tcx, val, ty) ) ;
77
- if let Some ( Constant :: Int ( val) ) = constant. and_then( miri_to_const) ;
78
- if val == 0 ;
79
- then {
80
- eprintln!( "true" ) ;
81
- true
82
- } else {
83
- // dbg!(aconst);
84
- eprintln!( "false" ) ;
85
- false
64
+ if let ItemKind :: Struct ( data, _generics) = & item. kind {
65
+ if let VariantData :: Struct ( field_defs, _) = data {
66
+ if let Some ( last_field) = field_defs. last ( ) {
67
+ if let TyKind :: Array ( _, aconst) = last_field. ty . kind {
68
+ let aconst_def_id = cx. tcx . hir ( ) . body_owner_def_id ( aconst. body ) . to_def_id ( ) ;
69
+ let ty = cx. tcx . type_of ( aconst_def_id) ;
70
+ let constant = cx
71
+ . tcx
72
+ // NOTE: maybe const_eval_resolve? seems especially cursed to be using a const expr which
73
+ // resolves to 0 to create a zero-sized array, tho
74
+ . const_eval_poly ( aconst_def_id)
75
+ . ok ( )
76
+ . map ( |val| rustc_middle:: ty:: Const :: from_value ( cx. tcx , val, ty) ) ;
77
+ if let Some ( Constant :: Int ( val) ) = constant. and_then ( miri_to_const) {
78
+ if val == 0 {
79
+ eprintln ! ( "trailing: true" ) ;
80
+ return true ;
81
+ }
82
+ }
83
+ }
84
+ }
86
85
}
87
86
}
87
+ // dbg!(aconst);
88
+ eprintln ! ( "trailing: false" ) ;
89
+ false
88
90
}
89
91
90
92
fn has_repr_c ( cx : & LateContext < ' tcx > , item : & ' tcx Item < ' tcx > ) -> bool {
91
- // todo!()
92
- true
93
+ // let hir_id2 = if let Some(body) = cx.enclosing_body {
94
+ // body.hir_id
95
+ // } else {
96
+ // todo!();
97
+ // };
98
+
99
+ let hir_id = cx. tcx . hir ( ) . local_def_id_to_hir_id ( item. def_id ) ;
100
+ let attrs = cx. tcx . hir ( ) . attrs ( hir_id) ;
101
+ // NOTE: Can there ever be more than one `repr` attribute?
102
+ // other `repr` syms: repr, repr128, repr_align, repr_align_enum, repr_no_niche, repr_packed,
103
+ // repr_simd, repr_transparent
104
+
105
+ if let Some ( repr_attr) = attrs. iter ( ) . find ( |attr| attr. has_name ( sym:: repr) ) {
106
+ eprintln ! ( "repr: true" ) ;
107
+ true
108
+ } else {
109
+ eprintln ! ( "repr: false" ) ;
110
+ false
111
+ }
93
112
}
0 commit comments