@@ -296,13 +296,18 @@ impl<'a> InferenceContext<'a> {
296
296
break ;
297
297
}
298
298
}
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 ( ) ;
299
304
let ( param_tys, ret_ty) = match res {
300
305
Some ( res) => {
301
306
let adjustments = auto_deref_adjust_steps ( & derefs) ;
302
307
self . write_expr_adj ( * callee, adjustments) ;
303
308
res
304
309
}
305
- None => ( Vec :: new ( ) , self . err_ty ( ) ) ,
310
+ None => ( Vec :: new ( ) , self . err_ty ( ) ) , // FIXME diagnostic
306
311
} ;
307
312
let indices_to_skip = self . check_legacy_const_generics ( derefed_callee, args) ;
308
313
self . register_obligations_for_call ( & callee_ty) ;
@@ -313,7 +318,14 @@ impl<'a> InferenceContext<'a> {
313
318
param_tys. clone ( ) ,
314
319
) ;
315
320
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
+ ) ;
317
329
self . normalize_associated_types_in ( ret_ty)
318
330
}
319
331
Expr :: MethodCall { receiver, args, method_name, generic_args } => self
@@ -948,22 +960,28 @@ impl<'a> InferenceContext<'a> {
948
960
} ;
949
961
let method_ty = method_ty. substitute ( Interner , & substs) ;
950
962
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
+ }
957
976
}
958
- }
959
- None => ( self . err_ty ( ) , Vec :: new ( ) , self . err_ty ( ) ) ,
960
- } ;
977
+ None => ( self . err_ty ( ) , Vec :: new ( ) , self . err_ty ( ) , true ) ,
978
+ } ;
961
979
self . unify ( & formal_receiver_ty, & receiver_ty) ;
962
980
963
981
let expected_inputs =
964
982
self . expected_inputs_for_expected_output ( expected, ret_ty. clone ( ) , param_tys. clone ( ) ) ;
965
983
966
- self . check_call_arguments ( args, & expected_inputs, & param_tys, & [ ] ) ;
984
+ self . check_call_arguments ( tgt_expr , args, & expected_inputs, & param_tys, & [ ] , is_varargs ) ;
967
985
self . normalize_associated_types_in ( ret_ty)
968
986
}
969
987
@@ -996,11 +1014,21 @@ impl<'a> InferenceContext<'a> {
996
1014
997
1015
fn check_call_arguments (
998
1016
& mut self ,
1017
+ expr : ExprId ,
999
1018
args : & [ ExprId ] ,
1000
1019
expected_inputs : & [ Ty ] ,
1001
1020
param_tys : & [ Ty ] ,
1002
1021
skip_indices : & [ u32 ] ,
1022
+ is_varargs : bool ,
1003
1023
) {
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
+
1004
1032
// Quoting https://github.com/rust-lang/rust/blob/6ef275e6c3cb1384ec78128eceeb4963ff788dca/src/librustc_typeck/check/mod.rs#L3325 --
1005
1033
// We do this in a pretty awful way: first we type-check any arguments
1006
1034
// that are not closures, then we type-check the closures. This is so
@@ -1188,7 +1216,15 @@ impl<'a> InferenceContext<'a> {
1188
1216
1189
1217
// only use legacy const generics if the param count matches with them
1190
1218
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
+ }
1192
1228
}
1193
1229
1194
1230
// check legacy const parameters
0 commit comments