diff options
author | Dawer <[email protected]> | 2021-05-12 07:04:56 +0100 |
---|---|---|
committer | Dawer <[email protected]> | 2021-05-31 20:49:44 +0100 |
commit | 4cce7a6407821f456741a8d512ae31da3128c84f (patch) | |
tree | e7baddfdf72bcef8477fe20de090590b34932a3c /crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs | |
parent | f46a42f73aa92ab66800c70d525ddc7e6529edd6 (diff) |
Box field detection; test #[non-exhaustive] attribute
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.rs | 22 |
1 files changed, 14 insertions, 8 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 9fa82a952..6711fbb4a 100644 --- a/crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs +++ b/crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs | |||
@@ -513,9 +513,7 @@ impl SplitWildcard { | |||
513 | if is_secretly_empty || is_declared_nonexhaustive { | 513 | if is_secretly_empty || is_declared_nonexhaustive { |
514 | smallvec![NonExhaustive] | 514 | smallvec![NonExhaustive] |
515 | } else if cx.feature_exhaustive_patterns() { | 515 | } else if cx.feature_exhaustive_patterns() { |
516 | // If `exhaustive_patterns` is enabled, we exclude variants known to be | 516 | unimplemented!() // see MatchCheckCtx.feature_exhaustive_patterns() |
517 | // uninhabited. | ||
518 | unhandled() | ||
519 | } else { | 517 | } else { |
520 | enum_data | 518 | enum_data |
521 | .variants | 519 | .variants |
@@ -643,6 +641,7 @@ impl Fields { | |||
643 | Fields::Vec(pats) | 641 | Fields::Vec(pats) |
644 | } | 642 | } |
645 | 643 | ||
644 | /// Creates a new list of wildcard fields for a given constructor. | ||
646 | pub(crate) fn wildcards(pcx: PatCtxt<'_>, constructor: &Constructor) -> Self { | 645 | pub(crate) fn wildcards(pcx: PatCtxt<'_>, constructor: &Constructor) -> Self { |
647 | let ty = pcx.ty; | 646 | let ty = pcx.ty; |
648 | let cx = pcx.cx; | 647 | let cx = pcx.cx; |
@@ -655,14 +654,13 @@ impl Fields { | |||
655 | Fields::wildcards_from_tys(cx, tys) | 654 | Fields::wildcards_from_tys(cx, tys) |
656 | } | 655 | } |
657 | TyKind::Ref(.., rty) => Fields::from_single_pattern(wildcard_from_ty(rty)), | 656 | TyKind::Ref(.., rty) => Fields::from_single_pattern(wildcard_from_ty(rty)), |
658 | TyKind::Adt(AdtId(adt), substs) => { | 657 | &TyKind::Adt(AdtId(adt), ref substs) => { |
659 | let adt_is_box = false; // TODO(iDawer): implement this | 658 | if adt_is_box(adt, cx) { |
660 | if adt_is_box { | ||
661 | // Use T as the sub pattern type of Box<T>. | 659 | // Use T as the sub pattern type of Box<T>. |
662 | let subst_ty = substs.at(&Interner, 0).assert_ty_ref(&Interner); | 660 | let subst_ty = substs.at(&Interner, 0).assert_ty_ref(&Interner); |
663 | Fields::from_single_pattern(wildcard_from_ty(subst_ty)) | 661 | Fields::from_single_pattern(wildcard_from_ty(subst_ty)) |
664 | } else { | 662 | } else { |
665 | let variant_id = constructor.variant_id_for_adt(*adt); | 663 | let variant_id = constructor.variant_id_for_adt(adt); |
666 | let adt_is_local = | 664 | let adt_is_local = |
667 | variant_id.module(cx.db.upcast()).krate() == cx.module.krate(); | 665 | variant_id.module(cx.db.upcast()).krate() == cx.module.krate(); |
668 | // Whether we must not match the fields of this variant exhaustively. | 666 | // Whether we must not match the fields of this variant exhaustively. |
@@ -680,7 +678,7 @@ impl Fields { | |||
680 | if has_no_hidden_fields { | 678 | if has_no_hidden_fields { |
681 | Fields::wildcards_from_tys(cx, field_tys()) | 679 | Fields::wildcards_from_tys(cx, field_tys()) |
682 | } else { | 680 | } else { |
683 | //FIXME(iDawer): see MatchCheckCtx::is_uninhabited | 681 | //FIXME(iDawer): see MatchCheckCtx::is_uninhabited, has_no_hidden_fields is always true |
684 | unimplemented!("exhaustive_patterns feature") | 682 | unimplemented!("exhaustive_patterns feature") |
685 | } | 683 | } |
686 | } | 684 | } |
@@ -892,3 +890,11 @@ fn is_field_list_non_exhaustive(variant_id: VariantId, cx: &MatchCheckCtx<'_>) - | |||
892 | }; | 890 | }; |
893 | cx.db.attrs(attr_def_id).by_key("non_exhaustive").exists() | 891 | cx.db.attrs(attr_def_id).by_key("non_exhaustive").exists() |
894 | } | 892 | } |
893 | |||
894 | fn adt_is_box(adt: hir_def::AdtId, cx: &MatchCheckCtx<'_>) -> bool { | ||
895 | use hir_def::lang_item::LangItemTarget; | ||
896 | match cx.db.lang_item(cx.module.krate(), "owned_box".into()) { | ||
897 | Some(LangItemTarget::StructId(box_id)) => adt == box_id.into(), | ||
898 | _ => false, | ||
899 | } | ||
900 | } | ||