Mismatched arg count works for lambdas

This commit is contained in:
Aleksey Kladov 2020-07-17 10:52:18 +02:00
parent 7e932f3339
commit f88a737a43
2 changed files with 30 additions and 10 deletions

View file

@ -158,28 +158,32 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
} }
let is_method_call = matches!(expr, Expr::MethodCall { .. }); let is_method_call = matches!(expr, Expr::MethodCall { .. });
let (callee, args) = match expr { let (sig, args) = match expr {
Expr::Call { callee, args } => { Expr::Call { callee, args } => {
let callee = &self.infer.type_of_expr[*callee]; let callee = &self.infer.type_of_expr[*callee];
let (callable, _) = callee.as_callable()?; let sig = callee.callable_sig(db)?;
(sig, args.clone())
(callable, args.clone())
} }
Expr::MethodCall { receiver, args, .. } => { Expr::MethodCall { receiver, args, .. } => {
let callee = self.infer.method_resolution(call_id)?;
let mut args = args.clone(); let mut args = args.clone();
args.insert(0, *receiver); args.insert(0, *receiver);
(callee.into(), args)
// FIXME: note that we erase information about substs here. This
// is not right, but, luckily, doesn't matter as we care only
// about the number of params
let callee = self.infer.method_resolution(call_id)?;
let sig = db.callable_item_signature(callee.into()).value;
(sig, args)
} }
_ => return None, _ => return None,
}; };
let sig = db.callable_item_signature(callee); if sig.is_varargs {
if sig.value.is_varargs {
return None; return None;
} }
let params = sig.value.params(); let params = sig.params();
let mut param_count = params.len(); let mut param_count = params.len();
let mut arg_count = args.len(); let mut arg_count = args.len();
@ -542,4 +546,20 @@ fn f() {
"#, "#,
) )
} }
#[test]
fn arg_count_lambda() {
check_diagnostics(
r#"
fn main() {
let f = |()| ();
f();
//^^^ Expected 1 argument, found 0
f(());
f((), ());
//^^^^^^^^^ Expected 1 argument, found 2
}
"#,
)
}
} }

View file

@ -807,7 +807,7 @@ impl Ty {
} }
} }
fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> { pub(crate) fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> {
match self { match self {
Ty::Apply(a_ty) => match a_ty.ctor { Ty::Apply(a_ty) => match a_ty.ctor {
TypeCtor::FnPtr { is_varargs, .. } => { TypeCtor::FnPtr { is_varargs, .. } => {