@@ -1491,8 +1491,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14911491 expr : & ' tcx hir:: Expr < ' tcx > ,
14921492 ) -> Ty < ' tcx > {
14931493 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) {
14961498 self . suggest_array_len ( expr, count) ;
14971499 }
14981500
@@ -1520,19 +1522,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15201522 return Ty :: new_error ( tcx, guar) ;
15211523 }
15221524
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+ }
15241533
15251534 let ty = Ty :: new_array_with_const_len ( tcx, t, count) ;
1526-
15271535 self . register_wf_obligation ( ty. into ( ) , expr. span , ObligationCauseCode :: WellFormed ( None ) ) ;
1528-
15291536 ty
15301537 }
15311538
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 (
15331541 & self ,
15341542 element : & hir:: Expr < ' _ > ,
1535- count : ty:: Const < ' tcx > ,
15361543 element_ty : Ty < ' tcx > ,
15371544 ) {
15381545 let tcx = self . tcx ;
@@ -1565,27 +1572,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15651572 _ => traits:: IsConstable :: No ,
15661573 } ;
15671574
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) ;
15891592 }
15901593
15911594 fn check_expr_tuple (
@@ -2800,9 +2803,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
28002803 len : ty:: Const < ' tcx > ,
28012804 ) {
28022805 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+ ) {
28062810 let help = "instead of using tuple indexing, use array indexing" ;
28072811 let applicability = if len < user_index {
28082812 Applicability :: MachineApplicable
0 commit comments