about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNathaniel Hamovitz <18648574+nhamovitz@users.noreply.github.com>2021-10-18 16:53:05 -0700
committerNathaniel Hamovitz <18648574+nhamovitz@users.noreply.github.com>2021-10-18 16:53:05 -0700
commit18c863dd0ef490d8f069dba6263d7d5d6f8b3e13 (patch)
tree3d67b12802973907c918db3ee567096825bf7259
parentd8bacf078a0c0d1dd3f15e6554338805f2d7256b (diff)
downloadrust-18c863dd0ef490d8f069dba6263d7d5d6f8b3e13.tar.gz
rust-18c863dd0ef490d8f069dba6263d7d5d6f8b3e13.zip
Improve help message
-rw-r--r--clippy_lints/src/trailing_zero_sized_array_without_repr.rs87
1 files changed, 26 insertions, 61 deletions
diff --git a/clippy_lints/src/trailing_zero_sized_array_without_repr.rs b/clippy_lints/src/trailing_zero_sized_array_without_repr.rs
index 10088ea55a9..0c9066fda82 100644
--- a/clippy_lints/src/trailing_zero_sized_array_without_repr.rs
+++ b/clippy_lints/src/trailing_zero_sized_array_without_repr.rs
@@ -2,12 +2,10 @@ use clippy_utils::{
     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 @@ declare_lint_pass!(TrailingZeroSizedArrayWithoutRepr => [TRAILING_ZERO_SIZED_ARR
 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))
 }