it works i think (incl some dbgs)

This commit is contained in:
Nathaniel Hamovitz 2021-10-16 00:51:09 -07:00
parent 523b013161
commit e53a4da4a1
2 changed files with 82 additions and 50 deletions

View file

@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
// use clippy_utils::is_integer_const;
use clippy_utils::consts::{miri_to_const, Constant};
use rustc_errors::Applicability;
use rustc_hir::{Item, ItemKind, TyKind, VariantData};
use rustc_hir::{HirId, Item, ItemKind, TyKind, VariantData};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
@ -45,17 +45,29 @@ declare_lint_pass!(TrailingZeroSizedArrayWithoutReprC => [TRAILING_ZERO_SIZED_AR
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_c(cx, item) {
// span_lint_and_sugg(
// cx,
// todo!(),
// todo!(),
// todo!(),
// "try",
// "`#[repr(C)]`".to_string(),
// Applicability::MachineApplicable,
// );
// println!("consider yourself linted 😎");
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(item.def_id);
let hir_id2 = item.hir_id();
dbg!(hir_id);
dbg!(hir_id2);
dbg!(hir_id == hir_id2);
let span1 = cx.tcx.hir().span(hir_id);
let span2 = item.span;
dbg!(span1);
dbg!(span2);
dbg!(span1 == span2);
if is_struct_with_trailing_zero_sized_array(cx, item) && !has_repr_c(cx, hir_id) {
span_lint_and_sugg(
cx,
TRAILING_ZERO_SIZED_ARRAY_WITHOUT_REPR_C,
span2,
"trailing zero-sized array in a struct which isn't marked `#[repr(C)]`",
"try",
"#[repr(C)]".to_string(),
Applicability::MaybeIncorrect,
);
}
}
}
@ -76,7 +88,7 @@ fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'tcx>, item: &'tcx
.map(|val| rustc_middle::ty::Const::from_value(cx.tcx, val, ty));
if let Some(Constant::Int(val)) = constant.and_then(miri_to_const) {
if val == 0 {
eprintln!("trailing: true");
// eprintln!("trailing: true");
return true;
}
}
@ -85,28 +97,21 @@ fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'tcx>, item: &'tcx
}
}
// dbg!(aconst);
eprintln!("trailing: false");
// eprintln!("trailing: false");
false
}
fn has_repr_c(cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) -> bool {
// let hir_id2 = if let Some(body) = cx.enclosing_body {
// body.hir_id
// } else {
// todo!();
// };
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(item.def_id);
fn has_repr_c(cx: &LateContext<'tcx>, hir_id: HirId) -> bool {
let attrs = cx.tcx.hir().attrs(hir_id);
// NOTE: Can there ever be more than one `repr` attribute?
// other `repr` syms: repr, repr128, repr_align, repr_align_enum, repr_no_niche, repr_packed,
// repr_simd, repr_transparent
if let Some(repr_attr) = attrs.iter().find(|attr| attr.has_name(sym::repr)) {
eprintln!("repr: true");
// eprintln!("repr: true");
true
} else {
eprintln!("repr: false");
// eprintln!("repr: false");
false
}
}

View file

@ -15,35 +15,62 @@ struct OnlyFieldIsZeroSizeArray {
first_and_last: [usize; 0],
}
struct GenericArrayType<T> {
field: i32,
last: [T; 0],
}
// struct GenericArrayType<T> {
// field: i32,
// last: [T; 0],
// }
struct SizedArray {
field: i32,
last: [usize; 1],
}
// struct SizedArray {
// field: i32,
// last: [usize; 1],
// }
const ZERO: usize = 0;
struct ZeroSizedFromExternalConst {
field: i32,
last: [usize; ZERO],
}
// const ZERO: usize = 0;
// struct ZeroSizedFromExternalConst {
// field: i32,
// last: [usize; ZERO],
// }
const ONE: usize = 1;
struct NonZeroSizedFromExternalConst {
field: i32,
last: [usize; ONE],
}
// const ONE: usize = 1;
// struct NonZeroSizedFromExternalConst {
// field: i32,
// last: [usize; ONE],
// }
#[allow(clippy::eq_op)] // lmao im impressed
const fn compute_zero() -> usize {
(4 + 6) - (2 * 5)
}
struct UsingFunction {
field: i32,
last: [usize; compute_zero()],
}
// #[allow(clippy::eq_op)] // lmao im impressed
// const fn compute_zero() -> usize {
// (4 + 6) - (2 * 5)
// }
// struct UsingFunction {
// field: i32,
// last: [usize; compute_zero()],
// }
// // TODO: same
// #[repr(packed)]
// struct ReprPacked {
// small: u8,
// medium: i32,
// weird: [u64; 0],
// }
// // TODO: actually, uh,,
// #[repr(align(64))]
// struct ReprAlign {
// field: i32,
// last: [usize; 0],
// }
// #[repr(C, align(64))]
// struct ReprCAlign {
// field: i32,
// last: [usize; 0],
// }
// #[repr(C)]
// enum DontLintAnonymousStructsFromDesuraging {
// A(u32),
// B(f32, [u64; 0]),
// C { x: u32, y: [u64; 0] },
// }
fn main() {}