Improve help message
This commit is contained in:
parent
d8bacf078a
commit
18c863dd0e
@ -2,12 +2,10 @@
|
||||
diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lint_and_then},
|
||||
source::{indent_of, snippet},
|
||||
};
|
||||
use rustc_ast::Attribute;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{HirId, Item, ItemKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::dep_graph::DepContext;
|
||||
use rustc_middle::ty::{self as ty_mod, Const, ReprFlags};
|
||||
use rustc_middle::ty::{Const, TyS};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::sym;
|
||||
|
||||
@ -43,18 +41,28 @@
|
||||
impl<'tcx> LateLintPass<'tcx> for TrailingZeroSizedArrayWithoutRepr {
|
||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
|
||||
dbg!(item.ident);
|
||||
if is_struct_with_trailing_zero_sized_array(cx, item) && !has_repr_attr(cx, item) {
|
||||
eprintln!("consider yourself linted 😎");
|
||||
// span_lint_and_help(
|
||||
// cx,
|
||||
// TRAILING_ZERO_SIZED_ARRAY_WITHOUT_REPR,
|
||||
// item.span,
|
||||
// "trailing zero-sized array in a struct which is not marked with a `repr`
|
||||
// attribute",
|
||||
// None,
|
||||
// "consider annotating the struct definition with `#[repr(C)]` or another
|
||||
// `repr` attribute",
|
||||
// );
|
||||
if is_struct_with_trailing_zero_sized_array(cx, item) && !has_repr_attr(cx, item.hir_id()) {
|
||||
let help_msg = format!(
|
||||
"consider annotating {} with `#[repr(C)]` or another `repr` attribute",
|
||||
cx.tcx
|
||||
.type_of(item.def_id)
|
||||
.ty_adt_def()
|
||||
.map(|adt_def| cx.tcx.def_path_str(adt_def.did))
|
||||
.unwrap_or_else(
|
||||
// I don't think this will ever be the case, since we made it through
|
||||
// `is_struct_with_trailing_zero_sized_array`, but I don't feel comfortable putting an `unwrap`
|
||||
|| "the struct definition".to_string()
|
||||
)
|
||||
);
|
||||
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
TRAILING_ZERO_SIZED_ARRAY_WITHOUT_REPR,
|
||||
item.span,
|
||||
"trailing zero-sized array in a struct which is not marked with a `repr` attribute",
|
||||
None,
|
||||
&help_msg,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -83,52 +91,9 @@ fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'tcx>, item: &'tcx
|
||||
}
|
||||
}
|
||||
|
||||
fn has_repr_attr(cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) -> bool {
|
||||
fn has_repr_attr(cx: &LateContext<'tcx>, hir_id: HirId) -> bool {
|
||||
// NOTE: there's at least four other ways to do this but I liked this one the best. (All five agreed
|
||||
// on all testcases (when i wrote this comment. I added a few since then).) Happy to use another;
|
||||
// on all testcases.) Happy to use another;
|
||||
// they're in the commit history if you want to look (or I can go find them).
|
||||
|
||||
let attrs1 = cx.tcx.hir().attrs(item.hir_id());
|
||||
let attrs2 = cx.tcx.get_attrs(item.def_id.to_def_id());
|
||||
|
||||
let res11 = {
|
||||
let sess = cx.tcx.sess(); // are captured values in closures evaluated once or every time?
|
||||
attrs1
|
||||
.iter()
|
||||
.any(|attr| !rustc_attr::find_repr_attrs(sess, attr).is_empty())
|
||||
};
|
||||
let res12 = { attrs1.iter().any(|attr| attr.has_name(sym::repr)) };
|
||||
|
||||
let res21 = {
|
||||
let sess = cx.tcx.sess(); // are captured values in closures evaluated once or every time?
|
||||
attrs2
|
||||
.iter()
|
||||
.any(|attr| !rustc_attr::find_repr_attrs(sess, attr).is_empty())
|
||||
};
|
||||
let res22 = { attrs2.iter().any(|attr| attr.has_name(sym::repr)) };
|
||||
|
||||
let res_adt = {
|
||||
let ty = cx.tcx.type_of(item.def_id.to_def_id());
|
||||
if let ty_mod::Adt(adt, _) = ty.kind() {
|
||||
if adt.is_struct() {
|
||||
let repr = adt.repr;
|
||||
let repr_attr = ReprFlags::IS_C | ReprFlags::IS_TRANSPARENT | ReprFlags::IS_SIMD | ReprFlags::IS_LINEAR;
|
||||
repr.int.is_some() || repr.align.is_some() || repr.pack.is_some() || repr.flags.intersects(repr_attr)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
let all_same = (res11 && res12 && res21 && res22 && res_adt) || (!res11 && !res12 && !res21 && !res22 && !res_adt);
|
||||
|
||||
|
||||
dbg!((
|
||||
(res11, res12, res21, res22, res_adt),
|
||||
all_same,
|
||||
));
|
||||
|
||||
res12
|
||||
cx.tcx.hir().attrs(hir_id).iter().any(|attr| attr.has_name(sym::repr))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user