From e53a4da4a142d3e90f8eb658a19466eca54901ea Mon Sep 17 00:00:00 2001 From: Nathaniel Hamovitz <18648574+nhamovitz@users.noreply.github.com> Date: Sat, 16 Oct 2021 00:51:09 -0700 Subject: [PATCH] it works i think (incl some `dbg`s) --- ...railing_zero_sized_array_without_repr_c.rs | 53 +++++++------ ...railing_zero_sized_array_without_repr_c.rs | 79 +++++++++++++------ 2 files changed, 82 insertions(+), 50 deletions(-) diff --git a/clippy_lints/src/trailing_zero_sized_array_without_repr_c.rs b/clippy_lints/src/trailing_zero_sized_array_without_repr_c.rs index 063dfb874cf1..62f8ecdc2163 100644 --- a/clippy_lints/src/trailing_zero_sized_array_without_repr_c.rs +++ b/clippy_lints/src/trailing_zero_sized_array_without_repr_c.rs @@ -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 } } diff --git a/tests/ui/trailing_zero_sized_array_without_repr_c.rs b/tests/ui/trailing_zero_sized_array_without_repr_c.rs index 5f844f16ba10..1e3683b2c259 100644 --- a/tests/ui/trailing_zero_sized_array_without_repr_c.rs +++ b/tests/ui/trailing_zero_sized_array_without_repr_c.rs @@ -15,35 +15,62 @@ struct OnlyFieldIsZeroSizeArray { first_and_last: [usize; 0], } -struct GenericArrayType { - field: i32, - last: [T; 0], -} +// struct GenericArrayType { +// 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() {}