@@ -13,7 +13,7 @@ use crate::errors::{
13
13
YieldExprOutsideOfCoroutine ,
14
14
} ;
15
15
use crate :: fatally_break_rust;
16
- use crate :: method:: { MethodCallComponents , SelfSource } ;
16
+ use crate :: method:: SelfSource ;
17
17
use crate :: type_error_struct;
18
18
use crate :: Expectation :: { self , ExpectCastableToType , ExpectHasType , NoExpectation } ;
19
19
use crate :: {
@@ -512,7 +512,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
512
512
) -> Ty < ' tcx > {
513
513
let tcx = self . tcx ;
514
514
let ( res, opt_ty, segs) =
515
- self . resolve_ty_and_res_fully_qualified_call ( qpath, expr. hir_id , expr. span ) ;
515
+ self . resolve_ty_and_res_fully_qualified_call ( qpath, expr. hir_id , expr. span , Some ( args ) ) ;
516
516
let ty = match res {
517
517
Res :: Err => {
518
518
self . suggest_assoc_method_call ( segs) ;
@@ -1332,7 +1332,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1332
1332
segment. ident ,
1333
1333
SelfSource :: MethodCall ( rcvr) ,
1334
1334
error,
1335
- Some ( MethodCallComponents { receiver : rcvr , args, full_expr : expr } ) ,
1335
+ Some ( args) ,
1336
1336
expected,
1337
1337
false ,
1338
1338
) {
@@ -1551,21 +1551,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1551
1551
}
1552
1552
_ => { }
1553
1553
}
1554
- // If someone calls a const fn, they can extract that call out into a separate constant (or a const
1555
- // block in the future), so we check that to tell them that in the diagnostic. Does not affect typeck.
1556
- let is_const_fn = match element. kind {
1554
+ // If someone calls a const fn or constructs a const value, they can extract that
1555
+ // out into a separate constant (or a const block in the future), so we check that
1556
+ // to tell them that in the diagnostic. Does not affect typeck.
1557
+ let is_constable = match element. kind {
1557
1558
hir:: ExprKind :: Call ( func, _args) => match * self . node_ty ( func. hir_id ) . kind ( ) {
1558
- ty:: FnDef ( def_id, _) => tcx. is_const_fn ( def_id) ,
1559
- _ => false ,
1559
+ ty:: FnDef ( def_id, _) if tcx. is_const_fn ( def_id) => traits :: IsConstable :: Fn ,
1560
+ _ => traits :: IsConstable :: No ,
1560
1561
} ,
1561
- _ => false ,
1562
+ hir:: ExprKind :: Path ( qpath) => {
1563
+ match self . typeck_results . borrow ( ) . qpath_res ( & qpath, element. hir_id ) {
1564
+ Res :: Def ( DefKind :: Ctor ( _, CtorKind :: Const ) , _) => traits:: IsConstable :: Ctor ,
1565
+ _ => traits:: IsConstable :: No ,
1566
+ }
1567
+ }
1568
+ _ => traits:: IsConstable :: No ,
1562
1569
} ;
1563
1570
1564
1571
// If the length is 0, we don't create any elements, so we don't copy any. If the length is 1, we
1565
1572
// don't copy that one element, we move it. Only check for Copy if the length is larger.
1566
1573
if count. try_eval_target_usize ( tcx, self . param_env ) . map_or ( true , |len| len > 1 ) {
1567
1574
let lang_item = self . tcx . require_lang_item ( LangItem :: Copy , None ) ;
1568
- let code = traits:: ObligationCauseCode :: RepeatElementCopy { is_const_fn } ;
1575
+ let code = traits:: ObligationCauseCode :: RepeatElementCopy {
1576
+ is_constable,
1577
+ elt_type : element_ty,
1578
+ elt_span : element. span ,
1579
+ elt_stmt_span : self
1580
+ . tcx
1581
+ . hir ( )
1582
+ . parent_iter ( element. hir_id )
1583
+ . find_map ( |( _, node) | match node {
1584
+ hir:: Node :: Item ( it) => Some ( it. span ) ,
1585
+ hir:: Node :: Stmt ( stmt) => Some ( stmt. span ) ,
1586
+ _ => None ,
1587
+ } )
1588
+ . expect ( "array repeat expressions must be inside an item or statement" ) ,
1589
+ } ;
1569
1590
self . require_type_meets ( element_ty, element. span , code, lang_item) ;
1570
1591
}
1571
1592
}
0 commit comments