Skip to content

Commit 523b013

Browse files
committed
Implement getting an array of attributes!
1 parent 7ee8e7a commit 523b013

File tree

1 file changed

+46
-27
lines changed

1 file changed

+46
-27
lines changed

clippy_lints/src/trailing_zero_sized_array_without_repr_c.rs

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use rustc_errors::Applicability;
55
use rustc_hir::{Item, ItemKind, TyKind, VariantData};
66
use rustc_lint::{LateContext, LateLintPass};
77
use rustc_session::{declare_lint_pass, declare_tool_lint};
8+
use rustc_span::sym;
89

910
declare_clippy_lint! {
1011
/// ### What it does
@@ -43,9 +44,8 @@ declare_lint_pass!(TrailingZeroSizedArrayWithoutReprC => [TRAILING_ZERO_SIZED_AR
4344

4445
impl<'tcx> LateLintPass<'tcx> for TrailingZeroSizedArrayWithoutReprC {
4546
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) {
4949
// span_lint_and_sugg(
5050
// cx,
5151
// todo!(),
@@ -61,33 +61,52 @@ impl<'tcx> LateLintPass<'tcx> for TrailingZeroSizedArrayWithoutReprC {
6161
}
6262

6363
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+
}
8685
}
8786
}
87+
// dbg!(aconst);
88+
eprintln!("trailing: false");
89+
false
8890
}
8991

9092
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+
}
93112
}

0 commit comments

Comments
 (0)