aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-07-09 17:28:35 +0100
committerGitHub <[email protected]>2020-07-09 17:28:35 +0100
commit7f991d80699844cdc38f61970cbbd73044506676 (patch)
treedef218466a0889571c5422ab39e5e0d3b9def085 /crates/ra_hir_ty
parent89c7c559953f103f224caacad6c9497d36660c76 (diff)
parent74aa0ab9f79490c862e48a4e6b3dad9e4073817f (diff)
Merge #5283
5283: Arg count mismatch diagnostic: Handle tuple struct/variant ctors r=jonas-schievink a=jonas-schievink I didn't know `callable_item_signature` was a thing, that makes this really easy. bors r+ Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates/ra_hir_ty')
-rw-r--r--crates/ra_hir_ty/src/expr.rs51
1 files changed, 34 insertions, 17 deletions
diff --git a/crates/ra_hir_ty/src/expr.rs b/crates/ra_hir_ty/src/expr.rs
index 6f34aaf17..72577d114 100644
--- a/crates/ra_hir_ty/src/expr.rs
+++ b/crates/ra_hir_ty/src/expr.rs
@@ -13,7 +13,7 @@ use crate::{
13 MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkInTailExpr, MissingPatFields, 13 MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkInTailExpr, MissingPatFields,
14 }, 14 },
15 utils::variant_data, 15 utils::variant_data,
16 ApplicationTy, CallableDef, InferenceResult, Ty, TypeCtor, 16 ApplicationTy, InferenceResult, Ty, TypeCtor,
17 _match::{is_useful, MatchCheckCtx, Matrix, PatStack, Usefulness}, 17 _match::{is_useful, MatchCheckCtx, Matrix, PatStack, Usefulness},
18}; 18};
19 19
@@ -162,35 +162,24 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
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 (callable, _) = callee.as_callable()?;
165 let callee = match callable {
166 CallableDef::FunctionId(func) => func,
167 165
168 // FIXME: Handle tuple struct/variant constructor calls. 166 (callable, args.clone())
169 _ => return None,
170 };
171
172 (callee, args.clone())
173 } 167 }
174 Expr::MethodCall { receiver, args, .. } => { 168 Expr::MethodCall { receiver, args, .. } => {
175 let callee = self.infer.method_resolution(call_id)?; 169 let callee = self.infer.method_resolution(call_id)?;
176 let mut args = args.clone(); 170 let mut args = args.clone();
177 args.insert(0, *receiver); 171 args.insert(0, *receiver);
178 (callee, args) 172 (callee.into(), args)
179 } 173 }
180 _ => return None, 174 _ => return None,
181 }; 175 };
182 176
183 let loc = callee.lookup(db.upcast()); 177 let sig = db.callable_item_signature(callee);
184 let ast = loc.source(db.upcast()); 178 let params = sig.value.params();
185 let params = ast.value.param_list()?;
186 179
187 let mut param_count = params.params().count(); 180 let mut param_count = params.len();
188 let mut arg_count = args.len(); 181 let mut arg_count = args.len();
189 182
190 if params.self_param().is_some() {
191 param_count += 1;
192 }
193
194 if arg_count != param_count { 183 if arg_count != param_count {
195 let (_, source_map) = db.body_with_source_map(self.func.into()); 184 let (_, source_map) = db.body_with_source_map(self.func.into());
196 if let Ok(source_ptr) = source_map.expr_syntax(call_id) { 185 if let Ok(source_ptr) = source_map.expr_syntax(call_id) {
@@ -501,4 +490,32 @@ mod tests {
501 ", 490 ",
502 ); 491 );
503 } 492 }
493
494 #[test]
495 fn tuple_struct() {
496 check_diagnostic(
497 r"
498 struct Tup(u8, u16);
499 fn f() {
500 Tup(0);
501 }
502 ",
503 expect![["\"Tup(0)\": Expected 2 arguments, found 1\n"]],
504 )
505 }
506
507 #[test]
508 fn enum_variant() {
509 check_diagnostic(
510 r"
511 enum En {
512 Variant(u8, u16),
513 }
514 fn f() {
515 En::Variant(0);
516 }
517 ",
518 expect![["\"En::Variant(0)\": Expected 2 arguments, found 1\n"]],
519 )
520 }
504} 521}