From f88a737a439f7801b7521c66c124ea5a44736e13 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 17 Jul 2020 10:52:18 +0200 Subject: Mismatched arg count works for lambdas --- crates/ra_hir_ty/src/diagnostics/expr.rs | 38 ++++++++++++++++++++++++-------- crates/ra_hir_ty/src/lib.rs | 2 +- 2 files changed, 30 insertions(+), 10 deletions(-) (limited to 'crates/ra_hir_ty') diff --git a/crates/ra_hir_ty/src/diagnostics/expr.rs b/crates/ra_hir_ty/src/diagnostics/expr.rs index 557d01cdc..fd930eab1 100644 --- a/crates/ra_hir_ty/src/diagnostics/expr.rs +++ b/crates/ra_hir_ty/src/diagnostics/expr.rs @@ -158,28 +158,32 @@ impl<'a, 'b> ExprValidator<'a, 'b> { } let is_method_call = matches!(expr, Expr::MethodCall { .. }); - let (callee, args) = match expr { + let (sig, args) = match expr { Expr::Call { callee, args } => { let callee = &self.infer.type_of_expr[*callee]; - let (callable, _) = callee.as_callable()?; - - (callable, args.clone()) + let sig = callee.callable_sig(db)?; + (sig, args.clone()) } Expr::MethodCall { receiver, args, .. } => { - let callee = self.infer.method_resolution(call_id)?; let mut args = args.clone(); 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, }; - let sig = db.callable_item_signature(callee); - if sig.value.is_varargs { + if sig.is_varargs { return None; } - let params = sig.value.params(); + let params = sig.params(); let mut param_count = params.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 +} +"#, + ) + } } diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 0ef5ca78f..1f6626c46 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -807,7 +807,7 @@ impl Ty { } } - fn callable_sig(&self, db: &dyn HirDatabase) -> Option { + pub(crate) fn callable_sig(&self, db: &dyn HirDatabase) -> Option { match self { Ty::Apply(a_ty) => match a_ty.ctor { TypeCtor::FnPtr { is_varargs, .. } => { -- cgit v1.2.3 From 371c5aec1c4ad18f37e96b4bf85c49563fc4a01d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 17 Jul 2020 10:57:49 +0200 Subject: call_info works with closures --- crates/ra_hir_ty/src/lib.rs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'crates/ra_hir_ty') diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 1f6626c46..7698cb0d4 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -767,15 +767,6 @@ impl Ty { } } - pub fn as_callable(&self) -> Option<(CallableDefId, &Substs)> { - match self { - Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(callable_def), parameters }) => { - Some((*callable_def, parameters)) - } - _ => None, - } - } - pub fn is_never(&self) -> bool { matches!(self, Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. })) } @@ -807,7 +798,7 @@ impl Ty { } } - pub(crate) fn callable_sig(&self, db: &dyn HirDatabase) -> Option { + pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option { match self { Ty::Apply(a_ty) => match a_ty.ctor { TypeCtor::FnPtr { is_varargs, .. } => { -- cgit v1.2.3