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 | |
parent | f46a42f73aa92ab66800c70d525ddc7e6529edd6 (diff) |
Box field detection; test #[non-exhaustive] attribute
Diffstat (limited to 'crates/hir_ty/src/diagnostics/match_check')
-rw-r--r-- | crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs | 22 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics/match_check/usefulness.rs | 4 |
2 files changed, 16 insertions, 10 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 | } | ||
diff --git a/crates/hir_ty/src/diagnostics/match_check/usefulness.rs b/crates/hir_ty/src/diagnostics/match_check/usefulness.rs index b01e3557c..44e08b6e9 100644 --- a/crates/hir_ty/src/diagnostics/match_check/usefulness.rs +++ b/crates/hir_ty/src/diagnostics/match_check/usefulness.rs | |||
@@ -293,7 +293,7 @@ pub(crate) struct MatchCheckCtx<'a> { | |||
293 | pub(crate) match_expr: ExprId, | 293 | pub(crate) match_expr: ExprId, |
294 | pub(crate) infer: &'a InferenceResult, | 294 | pub(crate) infer: &'a InferenceResult, |
295 | pub(crate) db: &'a dyn HirDatabase, | 295 | pub(crate) db: &'a dyn HirDatabase, |
296 | /// Lowered patterns from self.body.pats plus generated by the check. | 296 | /// Lowered patterns from arms plus generated by the check. |
297 | pub(crate) pattern_arena: &'a RefCell<PatternArena>, | 297 | pub(crate) pattern_arena: &'a RefCell<PatternArena>, |
298 | } | 298 | } |
299 | 299 | ||
@@ -315,7 +315,7 @@ impl<'a> MatchCheckCtx<'a> { | |||
315 | 315 | ||
316 | // Rust feature described as "Allows exhaustive pattern matching on types that contain uninhabited types." | 316 | // Rust feature described as "Allows exhaustive pattern matching on types that contain uninhabited types." |
317 | pub(super) fn feature_exhaustive_patterns(&self) -> bool { | 317 | pub(super) fn feature_exhaustive_patterns(&self) -> bool { |
318 | // TODO | 318 | // FIXME see MatchCheckCtx::is_uninhabited |
319 | false | 319 | false |
320 | } | 320 | } |
321 | 321 | ||