@@ -740,12 +740,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
740740 compatibility_diagonal,
741741 formal_and_expected_inputs,
742742 provided_args,
743- fn_sig_kind. c_variadic ( ) ,
744743 err_code,
745744 fn_def_id,
746745 call_span,
747746 call_expr,
748747 tuple_arguments,
748+ fn_sig_kind,
749749 ) ;
750750 }
751751 }
@@ -770,14 +770,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
770770 compatibility_diagonal : IndexVec < ProvidedIdx , Compatibility < ' tcx > > ,
771771 formal_and_expected_inputs : IndexVec < ExpectedIdx , ( Ty < ' tcx > , Ty < ' tcx > ) > ,
772772 provided_args : IndexVec < ProvidedIdx , & ' tcx hir:: Expr < ' tcx > > ,
773- // FIXME(splat): when the feature design is settled, replace this with FnSigKind, and
774- // improve the errors here
775- c_variadic : bool ,
776773 err_code : ErrCode ,
777774 fn_def_id : Option < DefId > ,
778775 call_span : Span ,
779776 call_expr : & ' tcx hir:: Expr < ' tcx > ,
780777 tuple_arguments : TupleArgumentsFlag ,
778+ // FIXME(splat): when the feature design is settled, improve the errors here
779+ fn_sig_kind : FnSigKind ,
781780 ) -> ErrorGuaranteed {
782781 // Next, let's construct the error
783782
@@ -786,12 +785,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
786785 compatibility_diagonal,
787786 formal_and_expected_inputs,
788787 provided_args,
789- c_variadic,
790788 err_code,
791789 fn_def_id,
792790 call_span,
793791 call_expr,
794792 tuple_arguments,
793+ fn_sig_kind,
795794 ) ;
796795
797796 // First, check if we just need to wrap some arguments in a tuple.
@@ -871,6 +870,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
871870 & fn_call_diag_ctxt. formal_and_expected_inputs ,
872871 fn_call_diag_ctxt. call_metadata . is_method ,
873872 tuple_arguments,
873+ fn_sig_kind,
874874 ) ;
875875
876876 // And add a suggestion block for all of the parameters
@@ -1549,6 +1549,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15491549 formal_and_expected_inputs : & IndexVec < ExpectedIdx , ( Ty < ' tcx > , Ty < ' tcx > ) > ,
15501550 is_method : bool ,
15511551 tuple_arguments : TupleArgumentsFlag ,
1552+ fn_sig_kind : FnSigKind ,
15521553 ) {
15531554 let Some ( mut def_id) = callable_def_id else {
15541555 return ;
@@ -1649,22 +1650,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16491650 debug_assert_eq ! ( params_with_generics. len( ) , matched_inputs. len( ) ) ;
16501651 // Gather all mismatched parameters with generics.
16511652 let mut mismatched_params = Vec :: < MismatchedParam < ' _ > > :: new ( ) ;
1653+ let mut use_splat_fallback = false ;
16521654 if let Some ( expected_idx) = expected_idx {
16531655 let expected_idx = ExpectedIdx :: from_usize ( expected_idx) ;
1654- let & ( expected_generic, ref expected_param) =
1655- & params_with_generics[ expected_idx] ;
1656- if let Some ( expected_generic) = expected_generic {
1657- mismatched_params. push ( MismatchedParam {
1658- idx : expected_idx,
1659- generic : expected_generic,
1660- param : expected_param,
1661- deps : SmallVec :: new ( ) ,
1662- } ) ;
1663- } else {
1664- // Still mark the mismatched parameter
1665- spans. push_span_label ( expected_param. span ( ) , "" ) ;
1666- }
1667- } else {
1656+ match params_with_generics. get ( expected_idx) {
1657+ Some ( & ( Some ( expected_generic) , ref expected_param) ) => mismatched_params
1658+ . push ( MismatchedParam {
1659+ idx : expected_idx,
1660+ generic : expected_generic,
1661+ param : expected_param,
1662+ deps : SmallVec :: new ( ) ,
1663+ } ) ,
1664+ Some ( ( None , expected_param) ) => {
1665+ // Still mark the mismatched parameter
1666+ spans. push_span_label ( expected_param. span ( ) , "" ) ;
1667+ }
1668+ None => {
1669+ if fn_sig_kind. splatted ( ) . is_none ( ) {
1670+ // FIXME(splat): when the arg is splatted, adjust its index
1671+ use_splat_fallback = true ;
1672+ } else {
1673+ span_bug ! (
1674+ self . tcx. def_span( def_id) ,
1675+ "arg index {} out of bounds for method with {} inputs" ,
1676+ expected_idx. as_usize( ) ,
1677+ params_with_generics. len( ) ,
1678+ ) ;
1679+ }
1680+ }
1681+ } ;
1682+ }
1683+
1684+ if expected_idx. is_none ( ) || use_splat_fallback {
16681685 mismatched_params. extend (
16691686 params_with_generics. iter_enumerated ( ) . zip ( matched_inputs) . filter_map (
16701687 |( ( idx, & ( generic, ref param) ) , matched_idx) | {
@@ -2108,24 +2125,24 @@ impl<'a, 'tcx> FnCallDiagCtxt<'a, 'tcx> {
21082125 compatibility_diagonal : IndexVec < ProvidedIdx , Compatibility < ' tcx > > ,
21092126 formal_and_expected_inputs : IndexVec < ExpectedIdx , ( Ty < ' tcx > , Ty < ' tcx > ) > ,
21102127 provided_args : IndexVec < ProvidedIdx , & ' tcx Expr < ' tcx > > ,
2111- c_variadic : bool ,
21122128 err_code : ErrCode ,
21132129 fn_def_id : Option < DefId > ,
21142130 call_span : Span ,
21152131 call_expr : & ' tcx Expr < ' tcx > ,
21162132 tuple_arguments : TupleArgumentsFlag ,
2133+ fn_sig_kind : FnSigKind ,
21172134 ) -> Self {
21182135 let arg_matching_ctxt = ArgMatchingCtxt :: new (
21192136 arg,
21202137 compatibility_diagonal,
21212138 formal_and_expected_inputs,
21222139 provided_args,
2123- c_variadic,
21242140 err_code,
21252141 fn_def_id,
21262142 call_span,
21272143 call_expr,
21282144 tuple_arguments,
2145+ fn_sig_kind,
21292146 ) ;
21302147
21312148 // The algorithm here is inspired by levenshtein distance and longest common subsequence.
@@ -2208,7 +2225,7 @@ impl<'a, 'tcx> FnCallDiagCtxt<'a, 'tcx> {
22082225 self . arg_matching_ctxt . args_ctxt . call_metadata . full_call_span ,
22092226 format ! (
22102227 "{call_name} takes {}{} but {} {} supplied" ,
2211- if self . c_variadic { "at least " } else { "" } ,
2228+ if self . fn_sig_kind . c_variadic( ) { "at least " } else { "" } ,
22122229 potentially_plural_count(
22132230 self . formal_and_expected_inputs. len( ) ,
22142231 "argument"
@@ -2238,6 +2255,7 @@ impl<'a, 'tcx> FnCallDiagCtxt<'a, 'tcx> {
22382255 & self . formal_and_expected_inputs ,
22392256 self . call_metadata . is_method ,
22402257 self . tuple_arguments ,
2258+ self . fn_sig_kind ,
22412259 ) ;
22422260 self . suggest_confusable ( & mut err) ;
22432261 Some ( err. emit ( ) )
@@ -2403,6 +2421,7 @@ impl<'a, 'tcx> FnCallDiagCtxt<'a, 'tcx> {
24032421 & self . formal_and_expected_inputs ,
24042422 self . call_metadata . is_method ,
24052423 self . tuple_arguments ,
2424+ self . fn_sig_kind ,
24062425 ) ;
24072426 self . arg_matching_ctxt . suggest_confusable ( & mut err) ;
24082427 self . detect_dotdot ( & mut err, provided_ty, self . provided_args [ provided_idx] ) ;
@@ -2441,7 +2460,7 @@ impl<'a, 'tcx> FnCallDiagCtxt<'a, 'tcx> {
24412460 format ! (
24422461 "this {} takes {}{} but {} {} supplied" ,
24432462 self . call_metadata. call_name,
2444- if self . c_variadic { "at least " } else { "" } ,
2463+ if self . fn_sig_kind . c_variadic( ) { "at least " } else { "" } ,
24452464 potentially_plural_count( self . formal_and_expected_inputs. len( ) , "argument" ) ,
24462465 potentially_plural_count( self . provided_args. len( ) , "argument" ) ,
24472466 pluralize!( "was" , self . provided_args. len( ) )
@@ -3005,24 +3024,24 @@ impl<'a, 'tcx> ArgMatchingCtxt<'a, 'tcx> {
30053024 compatibility_diagonal : IndexVec < ProvidedIdx , Compatibility < ' tcx > > ,
30063025 formal_and_expected_inputs : IndexVec < ExpectedIdx , ( Ty < ' tcx > , Ty < ' tcx > ) > ,
30073026 provided_args : IndexVec < ProvidedIdx , & ' tcx Expr < ' tcx > > ,
3008- c_variadic : bool ,
30093027 err_code : ErrCode ,
30103028 fn_def_id : Option < DefId > ,
30113029 call_span : Span ,
30123030 call_expr : & ' tcx Expr < ' tcx > ,
30133031 tuple_arguments : TupleArgumentsFlag ,
3032+ fn_sig_kind : FnSigKind ,
30143033 ) -> Self {
30153034 let args_ctxt = ArgsCtxt :: new (
30163035 arg,
30173036 compatibility_diagonal,
30183037 formal_and_expected_inputs,
30193038 provided_args,
3020- c_variadic,
30213039 err_code,
30223040 fn_def_id,
30233041 call_span,
30243042 call_expr,
30253043 tuple_arguments,
3044+ fn_sig_kind,
30263045 ) ;
30273046 let provided_arg_tys = args_ctxt. provided_arg_tys ( ) ;
30283047
@@ -3152,24 +3171,24 @@ impl<'a, 'tcx> ArgsCtxt<'a, 'tcx> {
31523171 compatibility_diagonal : IndexVec < ProvidedIdx , Compatibility < ' tcx > > ,
31533172 formal_and_expected_inputs : IndexVec < ExpectedIdx , ( Ty < ' tcx > , Ty < ' tcx > ) > ,
31543173 provided_args : IndexVec < ProvidedIdx , & ' tcx Expr < ' tcx > > ,
3155- c_variadic : bool ,
31563174 err_code : ErrCode ,
31573175 fn_def_id : Option < DefId > ,
31583176 call_span : Span ,
31593177 call_expr : & ' tcx Expr < ' tcx > ,
31603178 tuple_arguments : TupleArgumentsFlag ,
3179+ fn_sig_kind : FnSigKind ,
31613180 ) -> Self {
31623181 let call_ctxt: CallCtxt < ' _ , ' _ > = CallCtxt :: new (
31633182 arg,
31643183 compatibility_diagonal,
31653184 formal_and_expected_inputs,
31663185 provided_args,
3167- c_variadic,
31683186 err_code,
31693187 fn_def_id,
31703188 call_span,
31713189 call_expr,
31723190 tuple_arguments,
3191+ fn_sig_kind,
31733192 ) ;
31743193
31753194 let call_metadata = call_ctxt. call_metadata ( ) ;
@@ -3271,12 +3290,12 @@ struct CallCtxt<'a, 'tcx> {
32713290 compatibility_diagonal : IndexVec < ProvidedIdx , Compatibility < ' tcx > > ,
32723291 formal_and_expected_inputs : IndexVec < ExpectedIdx , ( Ty < ' tcx > , Ty < ' tcx > ) > ,
32733292 provided_args : IndexVec < ProvidedIdx , & ' tcx hir:: Expr < ' tcx > > ,
3274- c_variadic : bool ,
32753293 err_code : ErrCode ,
32763294 fn_def_id : Option < DefId > ,
32773295 call_span : Span ,
32783296 call_expr : & ' tcx hir:: Expr < ' tcx > ,
32793297 tuple_arguments : TupleArgumentsFlag ,
3298+ fn_sig_kind : FnSigKind ,
32803299 callee_expr : Option < & ' tcx Expr < ' tcx > > ,
32813300 callee_ty : Option < Ty < ' tcx > > ,
32823301}
@@ -3295,12 +3314,12 @@ impl<'a, 'tcx> CallCtxt<'a, 'tcx> {
32953314 compatibility_diagonal : IndexVec < ProvidedIdx , Compatibility < ' tcx > > ,
32963315 formal_and_expected_inputs : IndexVec < ExpectedIdx , ( Ty < ' tcx > , Ty < ' tcx > ) > ,
32973316 provided_args : IndexVec < ProvidedIdx , & ' tcx hir:: Expr < ' tcx > > ,
3298- c_variadic : bool ,
32993317 err_code : ErrCode ,
33003318 fn_def_id : Option < DefId > ,
33013319 call_span : Span ,
33023320 call_expr : & ' tcx hir:: Expr < ' tcx > ,
33033321 tuple_arguments : TupleArgumentsFlag ,
3322+ fn_sig_kind : FnSigKind ,
33043323 ) -> CallCtxt < ' a , ' tcx > {
33053324 let callee_expr = match & call_expr. peel_blocks ( ) . kind {
33063325 hir:: ExprKind :: Call ( callee, _) => Some ( * callee) ,
@@ -3327,12 +3346,12 @@ impl<'a, 'tcx> CallCtxt<'a, 'tcx> {
33273346 compatibility_diagonal,
33283347 formal_and_expected_inputs,
33293348 provided_args,
3330- c_variadic,
33313349 err_code,
33323350 fn_def_id,
33333351 call_span,
33343352 call_expr,
33353353 tuple_arguments,
3354+ fn_sig_kind,
33363355 callee_expr,
33373356 callee_ty,
33383357 }
0 commit comments