diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-07-09 17:28:35 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-07-09 17:28:35 +0100 |
commit | 7f991d80699844cdc38f61970cbbd73044506676 (patch) | |
tree | def218466a0889571c5422ab39e5e0d3b9def085 /crates/ra_hir_ty | |
parent | 89c7c559953f103f224caacad6c9497d36660c76 (diff) | |
parent | 74aa0ab9f79490c862e48a4e6b3dad9e4073817f (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.rs | 51 |
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 | } |