diff options
Diffstat (limited to 'crates/hir_ty/src/diagnostics/expr.rs')
-rw-r--r-- | crates/hir_ty/src/diagnostics/expr.rs | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs index a62f0fa4f..8f141a308 100644 --- a/crates/hir_ty/src/diagnostics/expr.rs +++ b/crates/hir_ty/src/diagnostics/expr.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | //! through the body using inference results: mismatched arg counts, missing | 2 | //! through the body using inference results: mismatched arg counts, missing |
3 | //! fields, etc. | 3 | //! fields, etc. |
4 | 4 | ||
5 | use std::sync::Arc; | 5 | use std::{cell::RefCell, sync::Arc}; |
6 | 6 | ||
7 | use hir_def::{expr::Statement, path::path, resolver::HasResolver, AssocItemId, DefWithBodyId}; | 7 | use hir_def::{expr::Statement, path::path, resolver::HasResolver, AssocItemId, DefWithBodyId}; |
8 | use hir_expand::name; | 8 | use hir_expand::name; |
@@ -26,7 +26,13 @@ pub(crate) use hir_def::{ | |||
26 | LocalFieldId, VariantId, | 26 | LocalFieldId, VariantId, |
27 | }; | 27 | }; |
28 | 28 | ||
29 | use super::ReplaceFilterMapNextWithFindMap; | 29 | use super::{ |
30 | pattern::{ | ||
31 | self, | ||
32 | usefulness::{expand_pattern, PatternArena}, | ||
33 | }, | ||
34 | ReplaceFilterMapNextWithFindMap, | ||
35 | }; | ||
30 | 36 | ||
31 | pub(super) struct ExprValidator<'a, 'b: 'a> { | 37 | pub(super) struct ExprValidator<'a, 'b: 'a> { |
32 | owner: DefWithBodyId, | 38 | owner: DefWithBodyId, |
@@ -380,7 +386,16 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
380 | }; | 386 | }; |
381 | // eprintln!("ExprValidator::validate_match2({:?})", _match_expr_ty.kind(&Interner)); | 387 | // eprintln!("ExprValidator::validate_match2({:?})", _match_expr_ty.kind(&Interner)); |
382 | 388 | ||
383 | let pattern_arena = usefulness::PatternArena::clone_from(&body.pats); | 389 | let pattern_arena = RefCell::new(PatternArena::new()); |
390 | |||
391 | let m_arms: Vec<_> = arms | ||
392 | .iter() | ||
393 | .map(|arm| usefulness::MatchArm { | ||
394 | pat: self.lower_pattern(arm.pat, &mut pattern_arena.borrow_mut(), db, &body), | ||
395 | has_guard: arm.guard.is_some(), | ||
396 | }) | ||
397 | .collect(); | ||
398 | |||
384 | let cx = usefulness::MatchCheckCtx { | 399 | let cx = usefulness::MatchCheckCtx { |
385 | module: self.owner.module(db.upcast()), | 400 | module: self.owner.module(db.upcast()), |
386 | match_expr, | 401 | match_expr, |
@@ -389,12 +404,6 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
389 | db, | 404 | db, |
390 | pattern_arena: &pattern_arena, | 405 | pattern_arena: &pattern_arena, |
391 | }; | 406 | }; |
392 | |||
393 | let m_arms: Vec<_> = arms | ||
394 | .iter() | ||
395 | .map(|arm| usefulness::MatchArm { pat: arm.pat, has_guard: arm.guard.is_some() }) | ||
396 | .collect(); | ||
397 | |||
398 | let report = usefulness::compute_match_usefulness(&cx, &m_arms); | 407 | let report = usefulness::compute_match_usefulness(&cx, &m_arms); |
399 | 408 | ||
400 | // TODO Report unreacheble arms | 409 | // TODO Report unreacheble arms |
@@ -427,6 +436,18 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
427 | } | 436 | } |
428 | } | 437 | } |
429 | 438 | ||
439 | fn lower_pattern( | ||
440 | &self, | ||
441 | pat: PatId, | ||
442 | pattern_arena: &mut PatternArena, | ||
443 | db: &dyn HirDatabase, | ||
444 | body: &Body, | ||
445 | ) -> pattern::PatId { | ||
446 | let mut patcx = pattern::PatCtxt::new(db, &self.infer, body); | ||
447 | let pattern = patcx.lower_pattern(pat); | ||
448 | pattern_arena.alloc(expand_pattern(pattern)) | ||
449 | } | ||
450 | |||
430 | fn validate_results_in_tail_expr(&mut self, body_id: ExprId, id: ExprId, db: &dyn HirDatabase) { | 451 | fn validate_results_in_tail_expr(&mut self, body_id: ExprId, id: ExprId, db: &dyn HirDatabase) { |
431 | // the mismatch will be on the whole block currently | 452 | // the mismatch will be on the whole block currently |
432 | let mismatch = match self.infer.type_mismatch_for_expr(body_id) { | 453 | let mismatch = match self.infer.type_mismatch_for_expr(body_id) { |