diff options
| author | Nathaniel Hamovitz <18648574+nhamovitz@users.noreply.github.com> | 2021-10-18 17:18:07 -0700 |
|---|---|---|
| committer | Nathaniel Hamovitz <18648574+nhamovitz@users.noreply.github.com> | 2021-10-18 17:18:07 -0700 |
| commit | 6303d2d075131641ef325344124c71052d2bd3eb (patch) | |
| tree | d2c045970508bdfad709872d1fe8ad5eac585896 | |
| parent | d85f903c91d909534003ee2ff0e16316b20687dc (diff) | |
| download | rust-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.rs | 55 | ||||
| -rw-r--r-- | tests/ui/trailing_zero_sized_array_without_repr.rs | 8 |
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], |
