aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-07-17 09:52:18 +0100
committerAleksey Kladov <[email protected]>2020-07-17 09:52:18 +0100
commitf88a737a439f7801b7521c66c124ea5a44736e13 (patch)
tree02010047cd9d144c73f0c90a6d47ac8021b43d0a /crates/ra_hir_ty
parent7e932f33391bd78a43a06d275a4d2f93fe3d7e8d (diff)
Mismatched arg count works for lambdas
Diffstat (limited to 'crates/ra_hir_ty')
-rw-r--r--crates/ra_hir_ty/src/diagnostics/expr.rs38
-rw-r--r--crates/ra_hir_ty/src/lib.rs2
2 files changed, 30 insertions, 10 deletions
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> {
158 } 158 }
159 159
160 let is_method_call = matches!(expr, Expr::MethodCall { .. }); 160 let is_method_call = matches!(expr, Expr::MethodCall { .. });
161 let (callee, args) = match expr { 161 let (sig, args) = match expr {
162 Expr::Call { callee, args } => { 162 Expr::Call { callee, args } => {
163 let callee = &self.infer.type_of_expr[*callee]; 163 let callee = &self.infer.type_of_expr[*callee];
164 let (callable, _) = callee.as_callable()?; 164 let sig = callee.callable_sig(db)?;
165 165 (sig, args.clone())
166 (callable, args.clone())
167 } 166 }
168 Expr::MethodCall { receiver, args, .. } => { 167 Expr::MethodCall { receiver, args, .. } => {
169 let callee = self.infer.method_resolution(call_id)?;
170 let mut args = args.clone(); 168 let mut args = args.clone();
171 args.insert(0, *receiver); 169 args.insert(0, *receiver);
172 (callee.into(), args) 170
171 // FIXME: note that we erase information about substs here. This
172 // is not right, but, luckily, doesn't matter as we care only
173 // about the number of params
174 let callee = self.infer.method_resolution(call_id)?;
175 let sig = db.callable_item_signature(callee.into()).value;
176
177 (sig, args)
173 } 178 }
174 _ => return None, 179 _ => return None,
175 }; 180 };
176 181
177 let sig = db.callable_item_signature(callee); 182 if sig.is_varargs {
178 if sig.value.is_varargs {
179 return None; 183 return None;
180 } 184 }
181 185
182 let params = sig.value.params(); 186 let params = sig.params();
183 187
184 let mut param_count = params.len(); 188 let mut param_count = params.len();
185 let mut arg_count = args.len(); 189 let mut arg_count = args.len();
@@ -542,4 +546,20 @@ fn f() {
542 "#, 546 "#,
543 ) 547 )
544 } 548 }
549
550 #[test]
551 fn arg_count_lambda() {
552 check_diagnostics(
553 r#"
554fn main() {
555 let f = |()| ();
556 f();
557 //^^^ Expected 1 argument, found 0
558 f(());
559 f((), ());
560 //^^^^^^^^^ Expected 1 argument, found 2
561}
562"#,
563 )
564 }
545} 565}
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 {
807 } 807 }
808 } 808 }
809 809
810 fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> { 810 pub(crate) fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> {
811 match self { 811 match self {
812 Ty::Apply(a_ty) => match a_ty.ctor { 812 Ty::Apply(a_ty) => match a_ty.ctor {
813 TypeCtor::FnPtr { is_varargs, .. } => { 813 TypeCtor::FnPtr { is_varargs, .. } => {