intermediate step

This commit is contained in:
Nathaniel Hamovitz 2021-10-16 16:13:14 -07:00
parent 003972f428
commit 5fdf93415b
2 changed files with 31 additions and 28 deletions

View file

@ -1,8 +1,6 @@
use clippy_utils::consts::{miri_to_const, Constant};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet;
use clippy_utils::diagnostics::span_lint_and_help;
use rustc_ast::Attribute;
use rustc_errors::Applicability;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::{Item, ItemKind, VariantData};
use rustc_lint::{LateContext, LateLintPass};
@ -47,15 +45,15 @@ impl<'tcx> LateLintPass<'tcx> for TrailingZeroSizedArrayWithoutReprC {
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.def_id) {
span_lint_and_sugg(
cx,
TRAILING_ZERO_SIZED_ARRAY_WITHOUT_REPR_C,
item.span,
"trailing zero-sized array in a struct which is not marked `#[repr(C)]`",
"try annotating the struct definition with `#[repr(C)]` (or another `repr` attribute):",
format!("#[repr(C)]\n{}", snippet(cx, item.span, "..")),
Applicability::MaybeIncorrect,
);
// span_lint_and_help(
// cx,
// TRAILING_ZERO_SIZED_ARRAY_WITHOUT_REPR_C,
// item.span,
// "trailing zero-sized array in a struct which is not marked `#[repr(C)]`",
// None,
// "consider annotating the struct definition with `#[repr(C)]` (or another `repr` attribute)",
// );
eprintln!("— consider yourself linted — 🦀")
}
}
}
@ -87,15 +85,16 @@ fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'tcx>, item: &'tcx
fn has_repr_attr(cx: &LateContext<'tcx>, def_id: LocalDefId) -> bool {
let attrs_get_attrs = get_attrs_get_attrs(cx, def_id);
let attrs_hir_map = get_attrs_hir_map(cx, def_id);
let b11 = dbg!(includes_repr_attr_using_sym(attrs_get_attrs));
let b12 = dbg!(includes_repr_attr_using_sym(attrs_hir_map));
let b21 = dbg!(includes_repr_attr_using_helper(cx, attrs_get_attrs));
let b22 = dbg!(includes_repr_attr_using_helper(cx, attrs_hir_map));
let b3 = dbg!(has_repr_attr_using_adt(cx, def_id));
let all_same = b11 && b12 && b21 && b22 && b3;
let b11 = includes_repr_attr_using_sym(attrs_get_attrs);
let b12 = includes_repr_attr_using_sym(attrs_hir_map);
let b21 = includes_repr_attr_using_helper(cx, attrs_get_attrs);
let b22 = includes_repr_attr_using_helper(cx, attrs_hir_map);
let b3 = has_repr_attr_using_adt(cx, def_id);
let all_same = (b11 && b12 && b21 && b22 && b3) || (!b11 && !b12 && !b21 && !b22 && !b3);
dbg!(all_same);
b11
b21
}
fn get_attrs_get_attrs(cx: &LateContext<'tcx>, def_id: LocalDefId) -> &'tcx [Attribute] {
@ -108,7 +107,9 @@ fn get_attrs_hir_map(cx: &LateContext<'tcx>, def_id: LocalDefId) -> &'tcx [Attri
hir_map.attrs(hir_id)
}
// Don't like this because it's so dependent on the current list of `repr` flags and it would have to be manually updated if that ever expanded. idk if there's any mechanism in `bitflag!` or elsewhere for requiring that sort of exhaustiveness
// Don't like this because it's so dependent on the current list of `repr` flags and it would have
// to be manually updated if that ever expanded. idk if there's any mechanism in `bitflag!` or
// elsewhere for requiring that sort of exhaustiveness
fn has_repr_attr_using_adt(cx: &LateContext<'tcx>, def_id: LocalDefId) -> bool {
let ty = cx.tcx.type_of(def_id.to_def_id());
if let ty_mod::Adt(adt, _) = ty.kind() {
@ -129,5 +130,7 @@ fn includes_repr_attr_using_sym(attrs: &'tcx [Attribute]) -> bool {
}
fn includes_repr_attr_using_helper(cx: &LateContext<'tcx>, attrs: &'tcx [Attribute]) -> bool {
attrs.iter().any(|attr| !rustc_attr::find_repr_attrs(cx.tcx.sess(), attr).is_empty())
attrs
.iter()
.any(|attr| !rustc_attr::find_repr_attrs(cx.tcx.sess(), attr).is_empty())
}

View file

@ -1,5 +1,5 @@
#![warn(clippy::trailing_zero_sized_array_without_repr_c)]
// #![feature(const_generics_defaults)] // see below
#![feature(const_generics_defaults)] // see below
// Do lint:
@ -20,13 +20,13 @@ struct GenericArrayType<T> {
#[derive(Debug)]
struct PlayNiceWithOtherAttributesDerive {
field: i32,
last: [usize; 0]
last: [usize; 0],
}
#[must_use]
struct PlayNiceWithOtherAttributesMustUse {
field: i32,
last: [usize; 0]
last: [usize; 0],
}
const ZERO: usize = 0;
@ -72,7 +72,7 @@ struct GoodReason {
last: [usize; 0],
}
struct SizedArray {
struct NonZeroSizedArray {
field: i32,
last: [usize; 1],
}
@ -114,8 +114,8 @@ enum DontLintAnonymousStructsFromDesuraging {
C { x: u32, y: [u64; 0] },
}
// NOTE: including these (along with the required feature) triggers an ICE. Should make sure the
// const generics people are aware of that if they weren't already.
// NOTE: including these (along with the required feature) triggers an ICE. Not sure why. Should
// make sure the const generics people are aware of that if they weren't already.
// #[repr(C)]
// struct ConstParamOk<const N: usize = 0> {
@ -129,5 +129,5 @@ enum DontLintAnonymousStructsFromDesuraging {
// }
fn main() {
let _ = PlayNiceWithOtherAttributesMustUse {field: 0, last: []};
let _ = PlayNiceWithOtherAttributesMustUse { field: 0, last: [] };
}