diff options
-rw-r--r-- | crates/ra_hir_ty/src/diagnostics/expr.rs | 38 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/lib.rs | 2 |
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#" | ||
554 | fn 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, .. } => { |