@@ -1491,8 +1491,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1491
1491
expr : & ' tcx hir:: Expr < ' tcx > ,
1492
1492
) -> Ty < ' tcx > {
1493
1493
let tcx = self . tcx ;
1494
- let count = self . lower_array_length ( count) ;
1495
- if let Some ( count) = count. try_eval_target_usize ( tcx, self . param_env ) {
1494
+ let count_span = count. span ( ) ;
1495
+ let count = self . try_structurally_resolve_const ( count_span, self . lower_array_length ( count) ) ;
1496
+
1497
+ if let Some ( count) = count. try_to_target_usize ( tcx) {
1496
1498
self . suggest_array_len ( expr, count) ;
1497
1499
}
1498
1500
@@ -1520,19 +1522,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1520
1522
return Ty :: new_error ( tcx, guar) ;
1521
1523
}
1522
1524
1523
- self . check_repeat_element_needs_copy_bound ( element, count, element_ty) ;
1525
+ // If the length is 0, we don't create any elements, so we don't copy any.
1526
+ // If the length is 1, we don't copy that one element, we move it. Only check
1527
+ // for `Copy` if the length is larger, or unevaluated.
1528
+ // FIXME(min_const_generic_exprs): We could perhaps defer this check so that
1529
+ // we don't require `<?0t as Tr>::CONST` doesn't unnecessarily require `Copy`.
1530
+ if count. try_to_target_usize ( tcx) . is_none_or ( |x| x > 1 ) {
1531
+ self . enforce_repeat_element_needs_copy_bound ( element, element_ty) ;
1532
+ }
1524
1533
1525
1534
let ty = Ty :: new_array_with_const_len ( tcx, t, count) ;
1526
-
1527
1535
self . register_wf_obligation ( ty. into ( ) , expr. span , ObligationCauseCode :: WellFormed ( None ) ) ;
1528
-
1529
1536
ty
1530
1537
}
1531
1538
1532
- fn check_repeat_element_needs_copy_bound (
1539
+ /// Requires that `element_ty` is `Copy` (unless it's a const expression itself).
1540
+ fn enforce_repeat_element_needs_copy_bound (
1533
1541
& self ,
1534
1542
element : & hir:: Expr < ' _ > ,
1535
- count : ty:: Const < ' tcx > ,
1536
1543
element_ty : Ty < ' tcx > ,
1537
1544
) {
1538
1545
let tcx = self . tcx ;
@@ -1565,27 +1572,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1565
1572
_ => traits:: IsConstable :: No ,
1566
1573
} ;
1567
1574
1568
- // If the length is 0, we don't create any elements, so we don't copy any. If the length is 1, we
1569
- // don't copy that one element, we move it. Only check for Copy if the length is larger.
1570
- if count. try_eval_target_usize ( tcx, self . param_env ) . is_none_or ( |len| len > 1 ) {
1571
- let lang_item = self . tcx . require_lang_item ( LangItem :: Copy , None ) ;
1572
- let code = traits:: ObligationCauseCode :: RepeatElementCopy {
1573
- is_constable,
1574
- elt_type : element_ty,
1575
- elt_span : element. span ,
1576
- elt_stmt_span : self
1577
- . tcx
1578
- . hir ( )
1579
- . parent_iter ( element. hir_id )
1580
- . find_map ( |( _, node) | match node {
1581
- hir:: Node :: Item ( it) => Some ( it. span ) ,
1582
- hir:: Node :: Stmt ( stmt) => Some ( stmt. span ) ,
1583
- _ => None ,
1584
- } )
1585
- . expect ( "array repeat expressions must be inside an item or statement" ) ,
1586
- } ;
1587
- self . require_type_meets ( element_ty, element. span , code, lang_item) ;
1588
- }
1575
+ let lang_item = self . tcx . require_lang_item ( LangItem :: Copy , None ) ;
1576
+ let code = traits:: ObligationCauseCode :: RepeatElementCopy {
1577
+ is_constable,
1578
+ elt_type : element_ty,
1579
+ elt_span : element. span ,
1580
+ elt_stmt_span : self
1581
+ . tcx
1582
+ . hir ( )
1583
+ . parent_iter ( element. hir_id )
1584
+ . find_map ( |( _, node) | match node {
1585
+ hir:: Node :: Item ( it) => Some ( it. span ) ,
1586
+ hir:: Node :: Stmt ( stmt) => Some ( stmt. span ) ,
1587
+ _ => None ,
1588
+ } )
1589
+ . expect ( "array repeat expressions must be inside an item or statement" ) ,
1590
+ } ;
1591
+ self . require_type_meets ( element_ty, element. span , code, lang_item) ;
1589
1592
}
1590
1593
1591
1594
fn check_expr_tuple (
@@ -2800,9 +2803,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2800
2803
len : ty:: Const < ' tcx > ,
2801
2804
) {
2802
2805
err. span_label ( field. span , "unknown field" ) ;
2803
- if let ( Some ( len) , Ok ( user_index) ) =
2804
- ( len. try_eval_target_usize ( self . tcx , self . param_env ) , field. as_str ( ) . parse :: < u64 > ( ) )
2805
- {
2806
+ if let ( Some ( len) , Ok ( user_index) ) = (
2807
+ self . try_structurally_resolve_const ( base. span , len) . try_to_target_usize ( self . tcx ) ,
2808
+ field. as_str ( ) . parse :: < u64 > ( ) ,
2809
+ ) {
2806
2810
let help = "instead of using tuple indexing, use array indexing" ;
2807
2811
let applicability = if len < user_index {
2808
2812
Applicability :: MachineApplicable
0 commit comments