diff options
Diffstat (limited to 'crates/ra_hir_ty/src/_match.rs')
-rw-r--r-- | crates/ra_hir_ty/src/_match.rs | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/crates/ra_hir_ty/src/_match.rs b/crates/ra_hir_ty/src/_match.rs index a64be9848..688026a04 100644 --- a/crates/ra_hir_ty/src/_match.rs +++ b/crates/ra_hir_ty/src/_match.rs | |||
@@ -194,9 +194,10 @@ use smallvec::{smallvec, SmallVec}; | |||
194 | use crate::{ | 194 | use crate::{ |
195 | db::HirDatabase, | 195 | db::HirDatabase, |
196 | expr::{Body, Expr, Literal, Pat, PatId}, | 196 | expr::{Body, Expr, Literal, Pat, PatId}, |
197 | InferenceResult, | 197 | ApplicationTy, InferenceResult, Ty, TypeCtor, |
198 | }; | 198 | }; |
199 | use hir_def::{adt::VariantData, EnumVariantId, VariantId}; | 199 | use hir_def::{adt::VariantData, AdtId, EnumVariantId, VariantId}; |
200 | use ra_arena::Idx; | ||
200 | 201 | ||
201 | #[derive(Debug, Clone, Copy)] | 202 | #[derive(Debug, Clone, Copy)] |
202 | /// Either a pattern from the source code being analyzed, represented as | 203 | /// Either a pattern from the source code being analyzed, represented as |
@@ -512,6 +513,7 @@ pub enum Usefulness { | |||
512 | } | 513 | } |
513 | 514 | ||
514 | pub struct MatchCheckCtx<'a> { | 515 | pub struct MatchCheckCtx<'a> { |
516 | pub match_expr: Idx<Expr>, | ||
515 | pub body: Arc<Body>, | 517 | pub body: Arc<Body>, |
516 | pub infer: Arc<InferenceResult>, | 518 | pub infer: Arc<InferenceResult>, |
517 | pub db: &'a dyn HirDatabase, | 519 | pub db: &'a dyn HirDatabase, |
@@ -530,6 +532,16 @@ pub(crate) fn is_useful( | |||
530 | matrix: &Matrix, | 532 | matrix: &Matrix, |
531 | v: &PatStack, | 533 | v: &PatStack, |
532 | ) -> MatchCheckResult<Usefulness> { | 534 | ) -> MatchCheckResult<Usefulness> { |
535 | // Handle the special case of enums with no variants. In that case, no match | ||
536 | // arm is useful. | ||
537 | if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(AdtId::EnumId(enum_id)), .. }) = | ||
538 | cx.infer[cx.match_expr].strip_references() | ||
539 | { | ||
540 | if cx.db.enum_data(*enum_id).variants.is_empty() { | ||
541 | return Ok(Usefulness::NotUseful); | ||
542 | } | ||
543 | } | ||
544 | |||
533 | if v.is_empty() { | 545 | if v.is_empty() { |
534 | let result = if matrix.is_empty() { Usefulness::Useful } else { Usefulness::NotUseful }; | 546 | let result = if matrix.is_empty() { Usefulness::Useful } else { Usefulness::NotUseful }; |
535 | 547 | ||
@@ -1618,6 +1630,32 @@ mod tests { | |||
1618 | 1630 | ||
1619 | check_no_diagnostic(content); | 1631 | check_no_diagnostic(content); |
1620 | } | 1632 | } |
1633 | |||
1634 | #[test] | ||
1635 | fn enum_never() { | ||
1636 | let content = r" | ||
1637 | enum Never {} | ||
1638 | |||
1639 | fn test_fn(never: Never) { | ||
1640 | match never {} | ||
1641 | } | ||
1642 | "; | ||
1643 | |||
1644 | check_no_diagnostic(content); | ||
1645 | } | ||
1646 | |||
1647 | #[test] | ||
1648 | fn enum_never_ref() { | ||
1649 | let content = r" | ||
1650 | enum Never {} | ||
1651 | |||
1652 | fn test_fn(never: &Never) { | ||
1653 | match never {} | ||
1654 | } | ||
1655 | "; | ||
1656 | |||
1657 | check_no_diagnostic(content); | ||
1658 | } | ||
1621 | } | 1659 | } |
1622 | 1660 | ||
1623 | #[cfg(test)] | 1661 | #[cfg(test)] |