about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNathaniel Hamovitz <18648574+nhamovitz@users.noreply.github.com>2021-10-18 17:07:51 -0700
committerNathaniel Hamovitz <18648574+nhamovitz@users.noreply.github.com>2021-10-18 17:07:51 -0700
commitd85f903c91d909534003ee2ff0e16316b20687dc (patch)
tree56f562721d92a1b55a4342b993766936e34e9788
parent48cf9c284ac858545cdd22ef2efec9096e6c6b06 (diff)
!: this is the commit that demonstrates the ICE
-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, 29 insertions, 34 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 0c9066fda82..ac4bbded127 100644
--- a/clippy_lints/src/trailing_zero_sized_array_without_repr.rs
+++ b/clippy_lints/src/trailing_zero_sized_array_without_repr.rs
@@ -1,11 +1,6 @@
-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 clippy_utils::{consts::miri_to_const, consts::Constant, diagnostics::span_lint_and_help};
 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;
 
@@ -42,27 +37,15 @@ 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()) {
-            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,
-            );
+            // 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 😎");
         }
     }
 }
@@ -75,11 +58,19 @@ 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 {
-                // 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)
+                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
+                }
             } 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 52966c64db7..c00a772d2fe 100644
--- a/tests/ui/trailing_zero_sized_array_without_repr.rs
+++ b/tests/ui/trailing_zero_sized_array_without_repr.rs
@@ -1,6 +1,8 @@
 #![warn(clippy::trailing_zero_sized_array_without_repr)]
 #![feature(const_generics_defaults)]
 
+// ICE note: All of these are fine
+
 // Do lint:
 
 struct RarelyUseful {
@@ -23,8 +25,6 @@ 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,12 +150,16 @@ 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],