@@ -739,12 +739,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
739739 compatibility_diagonal,
740740 formal_and_expected_inputs,
741741 provided_args,
742- fn_sig_kind. c_variadic ( ) ,
743742 err_code,
744743 fn_def_id,
745744 call_span,
746745 call_expr,
747746 tuple_arguments,
747+ fn_sig_kind,
748748 ) ;
749749 }
750750 }
@@ -769,14 +769,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
769769 compatibility_diagonal : IndexVec < ProvidedIdx , Compatibility < ' tcx > > ,
770770 formal_and_expected_inputs : IndexVec < ExpectedIdx , ( Ty < ' tcx > , Ty < ' tcx > ) > ,
771771 provided_args : IndexVec < ProvidedIdx , & ' tcx hir:: Expr < ' tcx > > ,
772- // FIXME(splat): when the feature design is settled, replace this with FnSigKind, and
773- // improve the errors here
774- c_variadic : bool ,
775772 err_code : ErrCode ,
776773 fn_def_id : Option < DefId > ,
777774 call_span : Span ,
778775 call_expr : & ' tcx hir:: Expr < ' tcx > ,
779776 tuple_arguments : TupleArgumentsFlag ,
777+ // FIXME(splat): when the feature design is settled, improve the errors here
778+ fn_sig_kind : FnSigKind ,
780779 ) -> ErrorGuaranteed {
781780 // Next, let's construct the error
782781
@@ -785,12 +784,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
785784 compatibility_diagonal,
786785 formal_and_expected_inputs,
787786 provided_args,
788- c_variadic,
789787 err_code,
790788 fn_def_id,
791789 call_span,
792790 call_expr,
793791 tuple_arguments,
792+ fn_sig_kind,
794793 ) ;
795794
796795 // First, check if we just need to wrap some arguments in a tuple.
@@ -870,6 +869,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
870869 & fn_call_diag_ctxt. formal_and_expected_inputs ,
871870 fn_call_diag_ctxt. call_metadata . is_method ,
872871 tuple_arguments,
872+ fn_sig_kind,
873873 ) ;
874874
875875 // And add a suggestion block for all of the parameters
@@ -1548,6 +1548,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15481548 formal_and_expected_inputs : & IndexVec < ExpectedIdx , ( Ty < ' tcx > , Ty < ' tcx > ) > ,
15491549 is_method : bool ,
15501550 tuple_arguments : TupleArgumentsFlag ,
1551+ fn_sig_kind : FnSigKind ,
15511552 ) {
15521553 let Some ( mut def_id) = callable_def_id else {
15531554 return ;
@@ -1648,22 +1649,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16481649 debug_assert_eq ! ( params_with_generics. len( ) , matched_inputs. len( ) ) ;
16491650 // Gather all mismatched parameters with generics.
16501651 let mut mismatched_params = Vec :: < MismatchedParam < ' _ > > :: new ( ) ;
1652+ let mut use_splat_fallback = false ;
16511653 if let Some ( expected_idx) = expected_idx {
16521654 let expected_idx = ExpectedIdx :: from_usize ( expected_idx) ;
1653- let & ( expected_generic, ref expected_param) =
1654- & params_with_generics[ expected_idx] ;
1655- if let Some ( expected_generic) = expected_generic {
1656- mismatched_params. push ( MismatchedParam {
1657- idx : expected_idx,
1658- generic : expected_generic,
1659- param : expected_param,
1660- deps : SmallVec :: new ( ) ,
1661- } ) ;
1662- } else {
1663- // Still mark the mismatched parameter
1664- spans. push_span_label ( expected_param. span ( ) , "" ) ;
1665- }
1666- } else {
1655+ match params_with_generics. get ( expected_idx) {
1656+ Some ( & ( Some ( expected_generic) , ref expected_param) ) => mismatched_params
1657+ . push ( MismatchedParam {
1658+ idx : expected_idx,
1659+ generic : expected_generic,
1660+ param : expected_param,
1661+ deps : SmallVec :: new ( ) ,
1662+ } ) ,
1663+ Some ( ( None , expected_param) ) => {
1664+ // Still mark the mismatched parameter
1665+ spans. push_span_label ( expected_param. span ( ) , "" ) ;
1666+ }
1667+ None => {
1668+ if fn_sig_kind. splatted ( ) . is_none ( ) {
1669+ // FIXME(splat): when the arg is splatted, adjust its index
1670+ use_splat_fallback = true ;
1671+ } else {
1672+ span_bug ! (
1673+ self . tcx. def_span( def_id) ,
1674+ "arg index {} out of bounds for method with {} inputs" ,
1675+ expected_idx. as_usize( ) ,
1676+ params_with_generics. len( ) ,
1677+ ) ;
1678+ }
1679+ }
1680+ } ;
1681+ }
1682+
1683+ if expected_idx. is_none ( ) || use_splat_fallback {
16671684 mismatched_params. extend (
16681685 params_with_generics. iter_enumerated ( ) . zip ( matched_inputs) . filter_map (
16691686 |( ( idx, & ( generic, ref param) ) , matched_idx) | {
@@ -2107,24 +2124,24 @@ impl<'a, 'tcx> FnCallDiagCtxt<'a, 'tcx> {
21072124 compatibility_diagonal : IndexVec < ProvidedIdx , Compatibility < ' tcx > > ,
21082125 formal_and_expected_inputs : IndexVec < ExpectedIdx , ( Ty < ' tcx > , Ty < ' tcx > ) > ,
21092126 provided_args : IndexVec < ProvidedIdx , & ' tcx Expr < ' tcx > > ,
2110- c_variadic : bool ,
21112127 err_code : ErrCode ,
21122128 fn_def_id : Option < DefId > ,
21132129 call_span : Span ,
21142130 call_expr : & ' tcx Expr < ' tcx > ,
21152131 tuple_arguments : TupleArgumentsFlag ,
2132+ fn_sig_kind : FnSigKind ,
21162133 ) -> Self {
21172134 let arg_matching_ctxt = ArgMatchingCtxt :: new (
21182135 arg,
21192136 compatibility_diagonal,
21202137 formal_and_expected_inputs,
21212138 provided_args,
2122- c_variadic,
21232139 err_code,
21242140 fn_def_id,
21252141 call_span,
21262142 call_expr,
21272143 tuple_arguments,
2144+ fn_sig_kind,
21282145 ) ;
21292146
21302147 // The algorithm here is inspired by levenshtein distance and longest common subsequence.
@@ -2207,7 +2224,7 @@ impl<'a, 'tcx> FnCallDiagCtxt<'a, 'tcx> {
22072224 self . arg_matching_ctxt . args_ctxt . call_metadata . full_call_span ,
22082225 format ! (
22092226 "{call_name} takes {}{} but {} {} supplied" ,
2210- if self . c_variadic { "at least " } else { "" } ,
2227+ if self . fn_sig_kind . c_variadic( ) { "at least " } else { "" } ,
22112228 potentially_plural_count(
22122229 self . formal_and_expected_inputs. len( ) ,
22132230 "argument"
@@ -2237,6 +2254,7 @@ impl<'a, 'tcx> FnCallDiagCtxt<'a, 'tcx> {
22372254 & self . formal_and_expected_inputs ,
22382255 self . call_metadata . is_method ,
22392256 self . tuple_arguments ,
2257+ self . fn_sig_kind ,
22402258 ) ;
22412259 self . suggest_confusable ( & mut err) ;
22422260 Some ( err. emit ( ) )
@@ -2402,6 +2420,7 @@ impl<'a, 'tcx> FnCallDiagCtxt<'a, 'tcx> {
24022420 & self . formal_and_expected_inputs ,
24032421 self . call_metadata . is_method ,
24042422 self . tuple_arguments ,
2423+ self . fn_sig_kind ,
24052424 ) ;
24062425 self . arg_matching_ctxt . suggest_confusable ( & mut err) ;
24072426 self . detect_dotdot ( & mut err, provided_ty, self . provided_args [ provided_idx] ) ;
@@ -2440,7 +2459,7 @@ impl<'a, 'tcx> FnCallDiagCtxt<'a, 'tcx> {
24402459 format ! (
24412460 "this {} takes {}{} but {} {} supplied" ,
24422461 self . call_metadata. call_name,
2443- if self . c_variadic { "at least " } else { "" } ,
2462+ if self . fn_sig_kind . c_variadic( ) { "at least " } else { "" } ,
24442463 potentially_plural_count( self . formal_and_expected_inputs. len( ) , "argument" ) ,
24452464 potentially_plural_count( self . provided_args. len( ) , "argument" ) ,
24462465 pluralize!( "was" , self . provided_args. len( ) )
@@ -3004,24 +3023,24 @@ impl<'a, 'tcx> ArgMatchingCtxt<'a, 'tcx> {
30043023 compatibility_diagonal : IndexVec < ProvidedIdx , Compatibility < ' tcx > > ,
30053024 formal_and_expected_inputs : IndexVec < ExpectedIdx , ( Ty < ' tcx > , Ty < ' tcx > ) > ,
30063025 provided_args : IndexVec < ProvidedIdx , & ' tcx Expr < ' tcx > > ,
3007- c_variadic : bool ,
30083026 err_code : ErrCode ,
30093027 fn_def_id : Option < DefId > ,
30103028 call_span : Span ,
30113029 call_expr : & ' tcx Expr < ' tcx > ,
30123030 tuple_arguments : TupleArgumentsFlag ,
3031+ fn_sig_kind : FnSigKind ,
30133032 ) -> Self {
30143033 let args_ctxt = ArgsCtxt :: new (
30153034 arg,
30163035 compatibility_diagonal,
30173036 formal_and_expected_inputs,
30183037 provided_args,
3019- c_variadic,
30203038 err_code,
30213039 fn_def_id,
30223040 call_span,
30233041 call_expr,
30243042 tuple_arguments,
3043+ fn_sig_kind,
30253044 ) ;
30263045 let provided_arg_tys = args_ctxt. provided_arg_tys ( ) ;
30273046
@@ -3151,24 +3170,24 @@ impl<'a, 'tcx> ArgsCtxt<'a, 'tcx> {
31513170 compatibility_diagonal : IndexVec < ProvidedIdx , Compatibility < ' tcx > > ,
31523171 formal_and_expected_inputs : IndexVec < ExpectedIdx , ( Ty < ' tcx > , Ty < ' tcx > ) > ,
31533172 provided_args : IndexVec < ProvidedIdx , & ' tcx Expr < ' tcx > > ,
3154- c_variadic : bool ,
31553173 err_code : ErrCode ,
31563174 fn_def_id : Option < DefId > ,
31573175 call_span : Span ,
31583176 call_expr : & ' tcx Expr < ' tcx > ,
31593177 tuple_arguments : TupleArgumentsFlag ,
3178+ fn_sig_kind : FnSigKind ,
31603179 ) -> Self {
31613180 let call_ctxt: CallCtxt < ' _ , ' _ > = CallCtxt :: new (
31623181 arg,
31633182 compatibility_diagonal,
31643183 formal_and_expected_inputs,
31653184 provided_args,
3166- c_variadic,
31673185 err_code,
31683186 fn_def_id,
31693187 call_span,
31703188 call_expr,
31713189 tuple_arguments,
3190+ fn_sig_kind,
31723191 ) ;
31733192
31743193 let call_metadata = call_ctxt. call_metadata ( ) ;
@@ -3270,12 +3289,12 @@ struct CallCtxt<'a, 'tcx> {
32703289 compatibility_diagonal : IndexVec < ProvidedIdx , Compatibility < ' tcx > > ,
32713290 formal_and_expected_inputs : IndexVec < ExpectedIdx , ( Ty < ' tcx > , Ty < ' tcx > ) > ,
32723291 provided_args : IndexVec < ProvidedIdx , & ' tcx hir:: Expr < ' tcx > > ,
3273- c_variadic : bool ,
32743292 err_code : ErrCode ,
32753293 fn_def_id : Option < DefId > ,
32763294 call_span : Span ,
32773295 call_expr : & ' tcx hir:: Expr < ' tcx > ,
32783296 tuple_arguments : TupleArgumentsFlag ,
3297+ fn_sig_kind : FnSigKind ,
32793298 callee_expr : Option < & ' tcx Expr < ' tcx > > ,
32803299 callee_ty : Option < Ty < ' tcx > > ,
32813300}
@@ -3294,12 +3313,12 @@ impl<'a, 'tcx> CallCtxt<'a, 'tcx> {
32943313 compatibility_diagonal : IndexVec < ProvidedIdx , Compatibility < ' tcx > > ,
32953314 formal_and_expected_inputs : IndexVec < ExpectedIdx , ( Ty < ' tcx > , Ty < ' tcx > ) > ,
32963315 provided_args : IndexVec < ProvidedIdx , & ' tcx hir:: Expr < ' tcx > > ,
3297- c_variadic : bool ,
32983316 err_code : ErrCode ,
32993317 fn_def_id : Option < DefId > ,
33003318 call_span : Span ,
33013319 call_expr : & ' tcx hir:: Expr < ' tcx > ,
33023320 tuple_arguments : TupleArgumentsFlag ,
3321+ fn_sig_kind : FnSigKind ,
33033322 ) -> CallCtxt < ' a , ' tcx > {
33043323 let callee_expr = match & call_expr. peel_blocks ( ) . kind {
33053324 hir:: ExprKind :: Call ( callee, _) => Some ( * callee) ,
@@ -3326,12 +3345,12 @@ impl<'a, 'tcx> CallCtxt<'a, 'tcx> {
33263345 compatibility_diagonal,
33273346 formal_and_expected_inputs,
33283347 provided_args,
3329- c_variadic,
33303348 err_code,
33313349 fn_def_id,
33323350 call_span,
33333351 call_expr,
33343352 tuple_arguments,
3353+ fn_sig_kind,
33353354 callee_expr,
33363355 callee_ty,
33373356 }
0 commit comments