aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/_match.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-04-16 13:57:31 +0100
committerGitHub <[email protected]>2020-04-16 13:57:31 +0100
commit0390d621681f80ab4bd3a872de0eed73f3e6e1fa (patch)
treeb9d23e3ff52657c15f0da7a831308b44cc8755d3 /crates/ra_hir_ty/src/_match.rs
parent7d60a446fca0923f698c4b8d10236ae246012f4e (diff)
parent360bdf653b91f5232a5584c7f4b13960caa48dda (diff)
Merge #3979
3979: fix missing match arm false positive for enum with no variants r=flodiebold a=JoshMcguigan fixes #3974 Co-authored-by: Josh Mcguigan <[email protected]>
Diffstat (limited to 'crates/ra_hir_ty/src/_match.rs')
-rw-r--r--crates/ra_hir_ty/src/_match.rs42
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};
194use crate::{ 194use 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};
199use hir_def::{adt::VariantData, EnumVariantId, VariantId}; 199use hir_def::{adt::VariantData, AdtId, EnumVariantId, VariantId};
200use 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
514pub struct MatchCheckCtx<'a> { 515pub 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)]