about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNathaniel Hamovitz <18648574+nhamovitz@users.noreply.github.com>2021-10-18 17:18:07 -0700
committerNathaniel Hamovitz <18648574+nhamovitz@users.noreply.github.com>2021-10-18 17:18:07 -0700
commit6303d2d075131641ef325344124c71052d2bd3eb (patch)
treed2c045970508bdfad709872d1fe8ad5eac585896
parentd85f903c91d909534003ee2ff0e16316b20687dc (diff)
downloadrust-6303d2d075131641ef325344124c71052d2bd3eb.tar.gz
rust-6303d2d075131641ef325344124c71052d2bd3eb.zip
Revert "!: this is the commit that demonstrates the ICE"
This reverts commit d85f903c91d909534003ee2ff0e16316b20687dc.
-rw-r--r--clippy_lints/src/trailing_zero_sized_array_without_repr.rs55
-rw-r--r--tests/ui/trailing_zero_sized_array_without_repr.rs8
2 files changed, 34 insertions, 29 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 ac4bbded127..0c9066fda82 100644
--- a/clippy_lints/src/trailing_zero_sized_array_without_repr.rs
+++ b/clippy_lints/src/trailing_zero_sized_array_without_repr.rs
@@ -1,6 +1,11 @@
-use clippy_utils::{consts::miri_to_const, consts::Constant, diagnostics::span_lint_and_help};
+use clippy_utils::{
+    diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lint_and_then},
+    source::{indent_of, snippet},
+};
+use rustc_errors::Applicability;
 use rustc_hir::{HirId, Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty::{Const, TyS};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::sym;
 
@@ -37,15 +42,27 @@ 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.hir_id()) {
-            // 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,
-            //     "",
-            // );
-            eprintln!("consider yourself linted 😎");
+            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,
+            );
         }
     }
 }
@@ -58,19 +75,11 @@ fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'tcx>, item: &'tcx
     if let ItemKind::Struct(data, _) = &item.kind {
         if let Some(last_field) = data.fields().last() {
             if let rustc_hir::TyKind::Array(_, length) = last_field.ty.kind {
-                let length_did = cx.tcx.hir().body_owner_def_id(length.body).to_def_id();
-                let ty = cx.tcx.type_of(length_did);
-                let length = cx
-                    .tcx
-                    // ICE happens in `const_eval_poly` according to my backtrace
-                    .const_eval_poly(length_did)
-                    .ok()
-                    .map(|val| rustc_middle::ty::Const::from_value(cx.tcx, val, ty));
-                if let Some(Constant::Int(length)) = length.and_then(miri_to_const){
-                    length == 0
-                } else {
-                    false
-                }
+                // Then check if that that array zero-sized
+                let length_ldid = cx.tcx.hir().local_def_id(length.hir_id);
+                let length = Const::from_anon_const(cx.tcx, length_ldid);
+                let length = length.try_eval_usize(cx.tcx, cx.param_env);
+                length == Some(0)
             } else {
                 false
             }
diff --git a/tests/ui/trailing_zero_sized_array_without_repr.rs b/tests/ui/trailing_zero_sized_array_without_repr.rs
index c00a772d2fe..52966c64db7 100644
--- a/tests/ui/trailing_zero_sized_array_without_repr.rs
+++ b/tests/ui/trailing_zero_sized_array_without_repr.rs
@@ -1,8 +1,6 @@
 #![warn(clippy::trailing_zero_sized_array_without_repr)]
 #![feature(const_generics_defaults)]
 
-// ICE note: All of these are fine
-
 // Do lint:
 
 struct RarelyUseful {
@@ -25,6 +23,8 @@ struct OnlyAnotherAttribute {
     last: [usize; 0],
 }
 
+// NOTE: Unfortunately the attribute isn't included in the lint output. I'm not sure how to make it
+// show up.
 #[derive(Debug)]
 struct OnlyADeriveAttribute {
     field: i32,
@@ -150,16 +150,12 @@ struct TupleStructReprC(i32, [usize; 0]);
 
 type NamedTuple = (i32, [usize; 0]);
 
-// ICE note: and then this one crashes
-
 #[rustfmt::skip] // [rustfmt#4995](https://github.com/rust-lang/rustfmt/issues/4995)
 struct ConstParamZeroDefault<const N: usize = 0> {
     field: i32,
     last: [usize; N],
 }
 
-// ICE notes: presumably these as well but I'm not sure
-
 struct ConstParamNoDefault<const N: usize> {
     field: i32,
     last: [usize; N],