@@ -2548,7 +2548,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
25482548 /// Return `Some` only if we are sure this type does *not*
25492549 /// allow zero initialization.
25502550 fn ty_find_init_error < ' tcx > (
2551- tcx : TyCtxt < ' tcx > ,
2551+ cx : & LateContext < ' tcx > ,
25522552 ty : Ty < ' tcx > ,
25532553 init : InitKind ,
25542554 ) -> Option < InitError > {
@@ -2575,7 +2575,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
25752575 Adt ( adt_def, substs) if !adt_def. is_union ( ) => {
25762576 // First check if this ADT has a layout attribute (like `NonNull` and friends).
25772577 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 ( ) ) {
25792579 // We exploit here that `layout_scalar_valid_range` will never
25802580 // return `Bound::Excluded`. (And we have tests checking that we
25812581 // handle the attribute correctly.)
@@ -2603,12 +2603,12 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
26032603 // Proceed recursively, check all fields.
26042604 let variant = & adt_def. variant ( VariantIdx :: from_u32 ( 0 ) ) ;
26052605 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 (
26072607 |( mut msg, span) | {
26082608 if span. is_none ( ) {
26092609 // Point to this field, should be helpful for figuring
26102610 // 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 ) ;
26122612 write ! (
26132613 & mut msg,
26142614 " (in this {} field)" ,
@@ -2627,7 +2627,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
26272627 // Multi-variant enum.
26282628 _ => {
26292629 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 ( ) ) ;
26312631 Some ( (
26322632 "enums have to be initialized to a variant" . to_string ( ) ,
26332633 Some ( span) ,
@@ -2642,7 +2642,16 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
26422642 }
26432643 Tuple ( ..) => {
26442644 // 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+ }
26462655 }
26472656 // Conservative fallback.
26482657 _ => None ,
@@ -2655,7 +2664,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
26552664 // We are extremely conservative with what we warn about.
26562665 let conjured_ty = cx. typeck_results ( ) . expr_ty ( expr) ;
26572666 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) )
26592668 {
26602669 cx. struct_span_lint ( INVALID_VALUE , expr. span , |lint| {
26612670 let mut err = lint. build ( & format ! (
0 commit comments