@@ -296,13 +296,18 @@ impl<'a> InferenceContext<'a> {
296296 break ;
297297 }
298298 }
299+ // if the function is unresolved, we use is_varargs=true to
300+ // suppress the arg count diagnostic here
301+ let is_varargs =
302+ derefed_callee. callable_sig ( self . db ) . map_or ( false , |sig| sig. is_varargs )
303+ || res. is_none ( ) ;
299304 let ( param_tys, ret_ty) = match res {
300305 Some ( res) => {
301306 let adjustments = auto_deref_adjust_steps ( & derefs) ;
302307 self . write_expr_adj ( * callee, adjustments) ;
303308 res
304309 }
305- None => ( Vec :: new ( ) , self . err_ty ( ) ) ,
310+ None => ( Vec :: new ( ) , self . err_ty ( ) ) , // FIXME diagnostic
306311 } ;
307312 let indices_to_skip = self . check_legacy_const_generics ( derefed_callee, args) ;
308313 self . register_obligations_for_call ( & callee_ty) ;
@@ -313,7 +318,14 @@ impl<'a> InferenceContext<'a> {
313318 param_tys. clone ( ) ,
314319 ) ;
315320
316- self . check_call_arguments ( args, & expected_inputs, & param_tys, & indices_to_skip) ;
321+ self . check_call_arguments (
322+ tgt_expr,
323+ args,
324+ & expected_inputs,
325+ & param_tys,
326+ & indices_to_skip,
327+ is_varargs,
328+ ) ;
317329 self . normalize_associated_types_in ( ret_ty)
318330 }
319331 Expr :: MethodCall { receiver, args, method_name, generic_args } => self
@@ -948,22 +960,28 @@ impl<'a> InferenceContext<'a> {
948960 } ;
949961 let method_ty = method_ty. substitute ( Interner , & substs) ;
950962 self . register_obligations_for_call ( & method_ty) ;
951- let ( formal_receiver_ty, param_tys, ret_ty) = match method_ty. callable_sig ( self . db ) {
952- Some ( sig) => {
953- if !sig. params ( ) . is_empty ( ) {
954- ( sig. params ( ) [ 0 ] . clone ( ) , sig. params ( ) [ 1 ..] . to_vec ( ) , sig. ret ( ) . clone ( ) )
955- } else {
956- ( self . err_ty ( ) , Vec :: new ( ) , sig. ret ( ) . clone ( ) )
963+ let ( formal_receiver_ty, param_tys, ret_ty, is_varargs) =
964+ match method_ty. callable_sig ( self . db ) {
965+ Some ( sig) => {
966+ if !sig. params ( ) . is_empty ( ) {
967+ (
968+ sig. params ( ) [ 0 ] . clone ( ) ,
969+ sig. params ( ) [ 1 ..] . to_vec ( ) ,
970+ sig. ret ( ) . clone ( ) ,
971+ sig. is_varargs ,
972+ )
973+ } else {
974+ ( self . err_ty ( ) , Vec :: new ( ) , sig. ret ( ) . clone ( ) , sig. is_varargs )
975+ }
957976 }
958- }
959- None => ( self . err_ty ( ) , Vec :: new ( ) , self . err_ty ( ) ) ,
960- } ;
977+ None => ( self . err_ty ( ) , Vec :: new ( ) , self . err_ty ( ) , true ) ,
978+ } ;
961979 self . unify ( & formal_receiver_ty, & receiver_ty) ;
962980
963981 let expected_inputs =
964982 self . expected_inputs_for_expected_output ( expected, ret_ty. clone ( ) , param_tys. clone ( ) ) ;
965983
966- self . check_call_arguments ( args, & expected_inputs, & param_tys, & [ ] ) ;
984+ self . check_call_arguments ( tgt_expr , args, & expected_inputs, & param_tys, & [ ] , is_varargs ) ;
967985 self . normalize_associated_types_in ( ret_ty)
968986 }
969987
@@ -996,11 +1014,21 @@ impl<'a> InferenceContext<'a> {
9961014
9971015 fn check_call_arguments (
9981016 & mut self ,
1017+ expr : ExprId ,
9991018 args : & [ ExprId ] ,
10001019 expected_inputs : & [ Ty ] ,
10011020 param_tys : & [ Ty ] ,
10021021 skip_indices : & [ u32 ] ,
1022+ is_varargs : bool ,
10031023 ) {
1024+ if args. len ( ) != param_tys. len ( ) + skip_indices. len ( ) && !is_varargs {
1025+ self . push_diagnostic ( InferenceDiagnostic :: MismatchedArgCount {
1026+ call_expr : expr,
1027+ expected : param_tys. len ( ) + skip_indices. len ( ) ,
1028+ found : args. len ( ) ,
1029+ } ) ;
1030+ }
1031+
10041032 // Quoting https://github.com/rust-lang/rust/blob/6ef275e6c3cb1384ec78128eceeb4963ff788dca/src/librustc_typeck/check/mod.rs#L3325 --
10051033 // We do this in a pretty awful way: first we type-check any arguments
10061034 // that are not closures, then we type-check the closures. This is so
@@ -1188,7 +1216,15 @@ impl<'a> InferenceContext<'a> {
11881216
11891217 // only use legacy const generics if the param count matches with them
11901218 if data. params . len ( ) + data. legacy_const_generics_indices . len ( ) != args. len ( ) {
1191- return Vec :: new ( ) ;
1219+ if args. len ( ) <= data. params . len ( ) {
1220+ return Vec :: new ( ) ;
1221+ } else {
1222+ // there are more parameters than there should be without legacy
1223+ // const params; use them
1224+ let mut indices = data. legacy_const_generics_indices . clone ( ) ;
1225+ indices. sort ( ) ;
1226+ return indices;
1227+ }
11921228 }
11931229
11941230 // check legacy const parameters
0 commit comments