@@ -2548,7 +2548,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
2548
2548
/// Return `Some` only if we are sure this type does *not*
2549
2549
/// allow zero initialization.
2550
2550
fn ty_find_init_error < ' tcx > (
2551
- tcx : TyCtxt < ' tcx > ,
2551
+ cx : & LateContext < ' tcx > ,
2552
2552
ty : Ty < ' tcx > ,
2553
2553
init : InitKind ,
2554
2554
) -> Option < InitError > {
@@ -2575,7 +2575,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
2575
2575
Adt ( adt_def, substs) if !adt_def. is_union ( ) => {
2576
2576
// First check if this ADT has a layout attribute (like `NonNull` and friends).
2577
2577
use std:: ops:: Bound ;
2578
- match tcx. layout_scalar_valid_range ( adt_def. did ( ) ) {
2578
+ match cx . tcx . layout_scalar_valid_range ( adt_def. did ( ) ) {
2579
2579
// We exploit here that `layout_scalar_valid_range` will never
2580
2580
// return `Bound::Excluded`. (And we have tests checking that we
2581
2581
// handle the attribute correctly.)
@@ -2603,12 +2603,12 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
2603
2603
// Proceed recursively, check all fields.
2604
2604
let variant = & adt_def. variant ( VariantIdx :: from_u32 ( 0 ) ) ;
2605
2605
variant. fields . iter ( ) . find_map ( |field| {
2606
- ty_find_init_error ( tcx , field. ty ( tcx, substs) , init) . map (
2606
+ ty_find_init_error ( cx , field. ty ( cx . tcx , substs) , init) . map (
2607
2607
|( mut msg, span) | {
2608
2608
if span. is_none ( ) {
2609
2609
// Point to this field, should be helpful for figuring
2610
2610
// out where the source of the error is.
2611
- let span = tcx. def_span ( field. did ) ;
2611
+ let span = cx . tcx . def_span ( field. did ) ;
2612
2612
write ! (
2613
2613
& mut msg,
2614
2614
" (in this {} field)" ,
@@ -2627,7 +2627,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
2627
2627
// Multi-variant enum.
2628
2628
_ => {
2629
2629
if init == InitKind :: Uninit && is_multi_variant ( * adt_def) {
2630
- let span = tcx. def_span ( adt_def. did ( ) ) ;
2630
+ let span = cx . tcx . def_span ( adt_def. did ( ) ) ;
2631
2631
Some ( (
2632
2632
"enums have to be initialized to a variant" . to_string ( ) ,
2633
2633
Some ( span) ,
@@ -2642,7 +2642,16 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
2642
2642
}
2643
2643
Tuple ( ..) => {
2644
2644
// Proceed recursively, check all fields.
2645
- ty. tuple_fields ( ) . iter ( ) . find_map ( |field| ty_find_init_error ( tcx, field, init) )
2645
+ ty. tuple_fields ( ) . iter ( ) . find_map ( |field| ty_find_init_error ( cx, field, init) )
2646
+ }
2647
+ Array ( ty, len) => {
2648
+ if matches ! ( len. try_eval_usize( cx. tcx, cx. param_env) , Some ( v) if v > 0 ) {
2649
+ // Array length known at array non-empty -- recurse.
2650
+ ty_find_init_error ( cx, * ty, init)
2651
+ } else {
2652
+ // Empty array or size unknown.
2653
+ None
2654
+ }
2646
2655
}
2647
2656
// Conservative fallback.
2648
2657
_ => None ,
@@ -2655,7 +2664,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
2655
2664
// We are extremely conservative with what we warn about.
2656
2665
let conjured_ty = cx. typeck_results ( ) . expr_ty ( expr) ;
2657
2666
if let Some ( ( msg, span) ) =
2658
- with_no_trimmed_paths ! ( ty_find_init_error( cx. tcx , conjured_ty, init) )
2667
+ with_no_trimmed_paths ! ( ty_find_init_error( cx, conjured_ty, init) )
2659
2668
{
2660
2669
cx. struct_span_lint ( INVALID_VALUE , expr. span , |lint| {
2661
2670
let mut err = lint. build ( & format ! (
0 commit comments