Skip to content

Commit e53a4da

Browse files
committed
it works i think (incl some dbgs)
1 parent 523b013 commit e53a4da

File tree

2 files changed

+82
-50
lines changed

2 files changed

+82
-50
lines changed

clippy_lints/src/trailing_zero_sized_array_without_repr_c.rs

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
22
// use clippy_utils::is_integer_const;
33
use clippy_utils::consts::{miri_to_const, Constant};
44
use rustc_errors::Applicability;
5-
use rustc_hir::{Item, ItemKind, TyKind, VariantData};
5+
use rustc_hir::{HirId, Item, ItemKind, TyKind, VariantData};
66
use rustc_lint::{LateContext, LateLintPass};
77
use rustc_session::{declare_lint_pass, declare_tool_lint};
88
use rustc_span::sym;
@@ -45,17 +45,29 @@ declare_lint_pass!(TrailingZeroSizedArrayWithoutReprC => [TRAILING_ZERO_SIZED_AR
4545
impl<'tcx> LateLintPass<'tcx> for TrailingZeroSizedArrayWithoutReprC {
4646
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
4747
dbg!(item.ident);
48-
if is_struct_with_trailing_zero_sized_array(cx, item) && !has_repr_c(cx, item) {
49-
// span_lint_and_sugg(
50-
// cx,
51-
// todo!(),
52-
// todo!(),
53-
// todo!(),
54-
// "try",
55-
// "`#[repr(C)]`".to_string(),
56-
// Applicability::MachineApplicable,
57-
// );
58-
// println!("consider yourself linted 😎");
48+
49+
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(item.def_id);
50+
let hir_id2 = item.hir_id();
51+
dbg!(hir_id);
52+
dbg!(hir_id2);
53+
dbg!(hir_id == hir_id2);
54+
55+
let span1 = cx.tcx.hir().span(hir_id);
56+
let span2 = item.span;
57+
dbg!(span1);
58+
dbg!(span2);
59+
dbg!(span1 == span2);
60+
61+
if is_struct_with_trailing_zero_sized_array(cx, item) && !has_repr_c(cx, hir_id) {
62+
span_lint_and_sugg(
63+
cx,
64+
TRAILING_ZERO_SIZED_ARRAY_WITHOUT_REPR_C,
65+
span2,
66+
"trailing zero-sized array in a struct which isn't marked `#[repr(C)]`",
67+
"try",
68+
"#[repr(C)]".to_string(),
69+
Applicability::MaybeIncorrect,
70+
);
5971
}
6072
}
6173
}
@@ -76,7 +88,7 @@ fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'tcx>, item: &'tcx
7688
.map(|val| rustc_middle::ty::Const::from_value(cx.tcx, val, ty));
7789
if let Some(Constant::Int(val)) = constant.and_then(miri_to_const) {
7890
if val == 0 {
79-
eprintln!("trailing: true");
91+
// eprintln!("trailing: true");
8092
return true;
8193
}
8294
}
@@ -85,28 +97,21 @@ fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'tcx>, item: &'tcx
8597
}
8698
}
8799
// dbg!(aconst);
88-
eprintln!("trailing: false");
100+
// eprintln!("trailing: false");
89101
false
90102
}
91103

92-
fn has_repr_c(cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) -> bool {
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);
104+
fn has_repr_c(cx: &LateContext<'tcx>, hir_id: HirId) -> bool {
100105
let attrs = cx.tcx.hir().attrs(hir_id);
101106
// NOTE: Can there ever be more than one `repr` attribute?
102107
// other `repr` syms: repr, repr128, repr_align, repr_align_enum, repr_no_niche, repr_packed,
103108
// repr_simd, repr_transparent
104109

105110
if let Some(repr_attr) = attrs.iter().find(|attr| attr.has_name(sym::repr)) {
106-
eprintln!("repr: true");
111+
// eprintln!("repr: true");
107112
true
108113
} else {
109-
eprintln!("repr: false");
114+
// eprintln!("repr: false");
110115
false
111116
}
112117
}

tests/ui/trailing_zero_sized_array_without_repr_c.rs

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,35 +15,62 @@ struct OnlyFieldIsZeroSizeArray {
1515
first_and_last: [usize; 0],
1616
}
1717

18-
struct GenericArrayType<T> {
19-
field: i32,
20-
last: [T; 0],
21-
}
18+
// struct GenericArrayType<T> {
19+
// field: i32,
20+
// last: [T; 0],
21+
// }
2222

23-
struct SizedArray {
24-
field: i32,
25-
last: [usize; 1],
26-
}
23+
// struct SizedArray {
24+
// field: i32,
25+
// last: [usize; 1],
26+
// }
2727

28-
const ZERO: usize = 0;
29-
struct ZeroSizedFromExternalConst {
30-
field: i32,
31-
last: [usize; ZERO],
32-
}
28+
// const ZERO: usize = 0;
29+
// struct ZeroSizedFromExternalConst {
30+
// field: i32,
31+
// last: [usize; ZERO],
32+
// }
3333

34-
const ONE: usize = 1;
35-
struct NonZeroSizedFromExternalConst {
36-
field: i32,
37-
last: [usize; ONE],
38-
}
34+
// const ONE: usize = 1;
35+
// struct NonZeroSizedFromExternalConst {
36+
// field: i32,
37+
// last: [usize; ONE],
38+
// }
3939

40-
#[allow(clippy::eq_op)] // lmao im impressed
41-
const fn compute_zero() -> usize {
42-
(4 + 6) - (2 * 5)
43-
}
44-
struct UsingFunction {
45-
field: i32,
46-
last: [usize; compute_zero()],
47-
}
40+
// #[allow(clippy::eq_op)] // lmao im impressed
41+
// const fn compute_zero() -> usize {
42+
// (4 + 6) - (2 * 5)
43+
// }
44+
// struct UsingFunction {
45+
// field: i32,
46+
// last: [usize; compute_zero()],
47+
// }
48+
49+
// // TODO: same
50+
// #[repr(packed)]
51+
// struct ReprPacked {
52+
// small: u8,
53+
// medium: i32,
54+
// weird: [u64; 0],
55+
// }
56+
57+
// // TODO: actually, uh,,
58+
// #[repr(align(64))]
59+
// struct ReprAlign {
60+
// field: i32,
61+
// last: [usize; 0],
62+
// }
63+
// #[repr(C, align(64))]
64+
// struct ReprCAlign {
65+
// field: i32,
66+
// last: [usize; 0],
67+
// }
68+
69+
// #[repr(C)]
70+
// enum DontLintAnonymousStructsFromDesuraging {
71+
// A(u32),
72+
// B(f32, [u64; 0]),
73+
// C { x: u32, y: [u64; 0] },
74+
// }
4875

4976
fn main() {}

0 commit comments

Comments
 (0)