Skip to content

Commit 18c863d

Browse files
committed
Improve help message
1 parent d8bacf0 commit 18c863d

File tree

1 file changed

+26
-61
lines changed

1 file changed

+26
-61
lines changed

clippy_lints/src/trailing_zero_sized_array_without_repr.rs

Lines changed: 26 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@ use clippy_utils::{
22
diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lint_and_then},
33
source::{indent_of, snippet},
44
};
5-
use rustc_ast::Attribute;
65
use rustc_errors::Applicability;
76
use rustc_hir::{HirId, Item, ItemKind};
87
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};
119
use rustc_session::{declare_lint_pass, declare_tool_lint};
1210
use rustc_span::sym;
1311

@@ -43,18 +41,28 @@ declare_lint_pass!(TrailingZeroSizedArrayWithoutRepr => [TRAILING_ZERO_SIZED_ARR
4341
impl<'tcx> LateLintPass<'tcx> for TrailingZeroSizedArrayWithoutRepr {
4442
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
4543
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+
);
5866
}
5967
}
6068
}
@@ -83,52 +91,9 @@ fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'tcx>, item: &'tcx
8391
}
8492
}
8593

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 {
8795
// 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;
8997
// 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))
13499
}

0 commit comments

Comments
 (0)