@@ -13,7 +13,7 @@ use crate::errors::{
1313 YieldExprOutsideOfCoroutine ,
1414} ;
1515use crate :: fatally_break_rust;
16- use crate :: method:: { MethodCallComponents , SelfSource } ;
16+ use crate :: method:: SelfSource ;
1717use crate :: type_error_struct;
1818use crate :: Expectation :: { self , ExpectCastableToType , ExpectHasType , NoExpectation } ;
1919use crate :: {
@@ -512,7 +512,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
512512 ) -> Ty < ' tcx > {
513513 let tcx = self . tcx ;
514514 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 ) ) ;
516516 let ty = match res {
517517 Res :: Err => {
518518 self . suggest_assoc_method_call ( segs) ;
@@ -1332,7 +1332,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13321332 segment. ident ,
13331333 SelfSource :: MethodCall ( rcvr) ,
13341334 error,
1335- Some ( MethodCallComponents { receiver : rcvr , args, full_expr : expr } ) ,
1335+ Some ( args) ,
13361336 expected,
13371337 false ,
13381338 ) {
@@ -1551,21 +1551,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15511551 }
15521552 _ => { }
15531553 }
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 {
15571558 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 ,
15601561 } ,
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 ,
15621569 } ;
15631570
15641571 // If the length is 0, we don't create any elements, so we don't copy any. If the length is 1, we
15651572 // don't copy that one element, we move it. Only check for Copy if the length is larger.
15661573 if count. try_eval_target_usize ( tcx, self . param_env ) . map_or ( true , |len| len > 1 ) {
15671574 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+ } ;
15691590 self . require_type_meets ( element_ty, element. span , code, lang_item) ;
15701591 }
15711592 }
0 commit comments