aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs')
-rw-r--r--crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs25
1 files changed, 14 insertions, 11 deletions
diff --git a/crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs b/crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs
index 15ec5cf45..a47082617 100644
--- a/crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs
+++ b/crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs
@@ -632,10 +632,7 @@ impl Fields {
632 } 632 }
633 633
634 /// Convenience; internal use. 634 /// Convenience; internal use.
635 fn wildcards_from_tys<'a>( 635 fn wildcards_from_tys(cx: &MatchCheckCtx<'_>, tys: impl IntoIterator<Item = Ty>) -> Self {
636 cx: &MatchCheckCtx<'_>,
637 tys: impl IntoIterator<Item = &'a Ty>,
638 ) -> Self {
639 let wilds = tys.into_iter().map(Pat::wildcard_from_ty); 636 let wilds = tys.into_iter().map(Pat::wildcard_from_ty);
640 let pats = wilds.map(|pat| cx.alloc_pat(pat)).collect(); 637 let pats = wilds.map(|pat| cx.alloc_pat(pat)).collect();
641 Fields::Vec(pats) 638 Fields::Vec(pats)
@@ -645,13 +642,13 @@ impl Fields {
645 pub(crate) fn wildcards(pcx: PatCtxt<'_>, constructor: &Constructor) -> Self { 642 pub(crate) fn wildcards(pcx: PatCtxt<'_>, constructor: &Constructor) -> Self {
646 let ty = pcx.ty; 643 let ty = pcx.ty;
647 let cx = pcx.cx; 644 let cx = pcx.cx;
648 let wildcard_from_ty = |ty| cx.alloc_pat(Pat::wildcard_from_ty(ty)); 645 let wildcard_from_ty = |ty: &Ty| cx.alloc_pat(Pat::wildcard_from_ty(ty.clone()));
649 646
650 let ret = match constructor { 647 let ret = match constructor {
651 Single | Variant(_) => match ty.kind(&Interner) { 648 Single | Variant(_) => match ty.kind(&Interner) {
652 TyKind::Tuple(_, substs) => { 649 TyKind::Tuple(_, substs) => {
653 let tys = substs.iter(&Interner).map(|ty| ty.assert_ty_ref(&Interner)); 650 let tys = substs.iter(&Interner).map(|ty| ty.assert_ty_ref(&Interner));
654 Fields::wildcards_from_tys(cx, tys) 651 Fields::wildcards_from_tys(cx, tys.cloned())
655 } 652 }
656 TyKind::Ref(.., rty) => Fields::from_single_pattern(wildcard_from_ty(rty)), 653 TyKind::Ref(.., rty) => Fields::from_single_pattern(wildcard_from_ty(rty)),
657 &TyKind::Adt(AdtId(adt), ref substs) => { 654 &TyKind::Adt(AdtId(adt), ref substs) => {
@@ -666,14 +663,20 @@ impl Fields {
666 // Whether we must not match the fields of this variant exhaustively. 663 // Whether we must not match the fields of this variant exhaustively.
667 let is_non_exhaustive = 664 let is_non_exhaustive =
668 is_field_list_non_exhaustive(variant_id, cx) && !adt_is_local; 665 is_field_list_non_exhaustive(variant_id, cx) && !adt_is_local;
669 let field_ty_arena = cx.db.field_types(variant_id); 666
670 let field_tys = 667 cov_mark::hit!(match_check_wildcard_expanded_to_substitutions);
671 || field_ty_arena.iter().map(|(_, binders)| binders.skip_binders()); 668 let field_ty_data = cx.db.field_types(variant_id);
669 let field_tys = || {
670 field_ty_data
671 .iter()
672 .map(|(_, binders)| binders.clone().substitute(&Interner, substs))
673 };
674
672 // In the following cases, we don't need to filter out any fields. This is 675 // In the following cases, we don't need to filter out any fields. This is
673 // the vast majority of real cases, since uninhabited fields are uncommon. 676 // the vast majority of real cases, since uninhabited fields are uncommon.
674 let has_no_hidden_fields = (matches!(adt, hir_def::AdtId::EnumId(_)) 677 let has_no_hidden_fields = (matches!(adt, hir_def::AdtId::EnumId(_))
675 && !is_non_exhaustive) 678 && !is_non_exhaustive)
676 || !field_tys().any(|ty| cx.is_uninhabited(ty)); 679 || !field_tys().any(|ty| cx.is_uninhabited(&ty));
677 680
678 if has_no_hidden_fields { 681 if has_no_hidden_fields {
679 Fields::wildcards_from_tys(cx, field_tys()) 682 Fields::wildcards_from_tys(cx, field_tys())
@@ -759,7 +762,7 @@ impl Fields {
759 FloatRange(..) => UNHANDLED, 762 FloatRange(..) => UNHANDLED,
760 Constructor::IntRange(_) => UNHANDLED, 763 Constructor::IntRange(_) => UNHANDLED,
761 NonExhaustive => PatKind::Wild, 764 NonExhaustive => PatKind::Wild,
762 Wildcard => return Pat::wildcard_from_ty(pcx.ty), 765 Wildcard => return Pat::wildcard_from_ty(pcx.ty.clone()),
763 Opaque => pcx.cx.bug("we should not try to apply an opaque constructor"), 766 Opaque => pcx.cx.bug("we should not try to apply an opaque constructor"),
764 Missing => pcx.cx.bug( 767 Missing => pcx.cx.bug(
765 "trying to apply the `Missing` constructor;\ 768 "trying to apply the `Missing` constructor;\