aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-07-17 12:01:52 +0100
committerGitHub <[email protected]>2020-07-17 12:01:52 +0100
commit9b5ac1d82fa3b9b810656e5b4a44d471b9923ce7 (patch)
treeed3930e18000f7ee5ebd7a3b81de2098fc595f7f /crates/ra_hir_ty
parent6ae6c1460e1e0524664af39fd0dbe3b1af3fac50 (diff)
parent393b7119bd5341bffb166e0dadcff9124e28b888 (diff)
Merge #5417
5417: Mismatched arg count works for lambdas r=jonas-schievink a=matklad Co-authored-by: Aleksey Kladov <[email protected]>
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.rs11
2 files changed, 30 insertions, 19 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..7698cb0d4 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -767,15 +767,6 @@ impl Ty {
767 } 767 }
768 } 768 }
769 769
770 pub fn as_callable(&self) -> Option<(CallableDefId, &Substs)> {
771 match self {
772 Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(callable_def), parameters }) => {
773 Some((*callable_def, parameters))
774 }
775 _ => None,
776 }
777 }
778
779 pub fn is_never(&self) -> bool { 770 pub fn is_never(&self) -> bool {
780 matches!(self, Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. })) 771 matches!(self, Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. }))
781 } 772 }
@@ -807,7 +798,7 @@ impl Ty {
807 } 798 }
808 } 799 }
809 800
810 fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> { 801 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> {
811 match self { 802 match self {
812 Ty::Apply(a_ty) => match a_ty.ctor { 803 Ty::Apply(a_ty) => match a_ty.ctor {
813 TypeCtor::FnPtr { is_varargs, .. } => { 804 TypeCtor::FnPtr { is_varargs, .. } => {