Skip to content

Commit d85f903

Browse files
committed
!: this is the commit that demonstrates the ICE
1 parent 48cf9c2 commit d85f903

File tree

2 files changed

+29
-34
lines changed

2 files changed

+29
-34
lines changed

clippy_lints/src/trailing_zero_sized_array_without_repr.rs

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
1-
use clippy_utils::{
2-
diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lint_and_then},
3-
source::{indent_of, snippet},
4-
};
5-
use rustc_errors::Applicability;
1+
use clippy_utils::{consts::miri_to_const, consts::Constant, diagnostics::span_lint_and_help};
62
use rustc_hir::{HirId, Item, ItemKind};
73
use rustc_lint::{LateContext, LateLintPass};
8-
use rustc_middle::ty::{Const, TyS};
94
use rustc_session::{declare_lint_pass, declare_tool_lint};
105
use rustc_span::sym;
116

@@ -42,27 +37,15 @@ impl<'tcx> LateLintPass<'tcx> for TrailingZeroSizedArrayWithoutRepr {
4237
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
4338
dbg!(item.ident);
4439
if is_struct_with_trailing_zero_sized_array(cx, item) && !has_repr_attr(cx, item.hir_id()) {
45-
let help_msg = format!(
46-
"consider annotating {} with `#[repr(C)]` or another `repr` attribute",
47-
cx.tcx
48-
.type_of(item.def_id)
49-
.ty_adt_def()
50-
.map(|adt_def| cx.tcx.def_path_str(adt_def.did))
51-
.unwrap_or_else(
52-
// I don't think this will ever be the case, since we made it through
53-
// `is_struct_with_trailing_zero_sized_array`, but I don't feel comfortable putting an `unwrap`
54-
|| "the struct definition".to_string()
55-
)
56-
);
57-
58-
span_lint_and_help(
59-
cx,
60-
TRAILING_ZERO_SIZED_ARRAY_WITHOUT_REPR,
61-
item.span,
62-
"trailing zero-sized array in a struct which is not marked with a `repr` attribute",
63-
None,
64-
&help_msg,
65-
);
40+
// span_lint_and_help(
41+
// cx,
42+
// TRAILING_ZERO_SIZED_ARRAY_WITHOUT_REPR,
43+
// item.span,
44+
// "trailing zero-sized array in a struct which is not marked with a `repr` attribute",
45+
// None,
46+
// "",
47+
// );
48+
eprintln!("consider yourself linted 😎");
6649
}
6750
}
6851
}
@@ -75,11 +58,19 @@ fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'tcx>, item: &'tcx
7558
if let ItemKind::Struct(data, _) = &item.kind {
7659
if let Some(last_field) = data.fields().last() {
7760
if let rustc_hir::TyKind::Array(_, length) = last_field.ty.kind {
78-
// Then check if that that array zero-sized
79-
let length_ldid = cx.tcx.hir().local_def_id(length.hir_id);
80-
let length = Const::from_anon_const(cx.tcx, length_ldid);
81-
let length = length.try_eval_usize(cx.tcx, cx.param_env);
82-
length == Some(0)
61+
let length_did = cx.tcx.hir().body_owner_def_id(length.body).to_def_id();
62+
let ty = cx.tcx.type_of(length_did);
63+
let length = cx
64+
.tcx
65+
// ICE happens in `const_eval_poly` according to my backtrace
66+
.const_eval_poly(length_did)
67+
.ok()
68+
.map(|val| rustc_middle::ty::Const::from_value(cx.tcx, val, ty));
69+
if let Some(Constant::Int(length)) = length.and_then(miri_to_const){
70+
length == 0
71+
} else {
72+
false
73+
}
8374
} else {
8475
false
8576
}

tests/ui/trailing_zero_sized_array_without_repr.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#![warn(clippy::trailing_zero_sized_array_without_repr)]
22
#![feature(const_generics_defaults)]
33

4+
// ICE note: All of these are fine
5+
46
// Do lint:
57

68
struct RarelyUseful {
@@ -23,8 +25,6 @@ struct OnlyAnotherAttribute {
2325
last: [usize; 0],
2426
}
2527

26-
// NOTE: Unfortunately the attribute isn't included in the lint output. I'm not sure how to make it
27-
// show up.
2828
#[derive(Debug)]
2929
struct OnlyADeriveAttribute {
3030
field: i32,
@@ -150,12 +150,16 @@ struct TupleStructReprC(i32, [usize; 0]);
150150

151151
type NamedTuple = (i32, [usize; 0]);
152152

153+
// ICE note: and then this one crashes
154+
153155
#[rustfmt::skip] // [rustfmt#4995](https://github.com/rust-lang/rustfmt/issues/4995)
154156
struct ConstParamZeroDefault<const N: usize = 0> {
155157
field: i32,
156158
last: [usize; N],
157159
}
158160

161+
// ICE notes: presumably these as well but I'm not sure
162+
159163
struct ConstParamNoDefault<const N: usize> {
160164
field: i32,
161165
last: [usize; N],

0 commit comments

Comments
 (0)