diff options
Diffstat (limited to 'crates/ra_hir_ty/src/_match.rs')
-rw-r--r-- | crates/ra_hir_ty/src/_match.rs | 68 |
1 files changed, 41 insertions, 27 deletions
diff --git a/crates/ra_hir_ty/src/_match.rs b/crates/ra_hir_ty/src/_match.rs index 779e78574..3e6e1e333 100644 --- a/crates/ra_hir_ty/src/_match.rs +++ b/crates/ra_hir_ty/src/_match.rs | |||
@@ -573,14 +573,20 @@ pub(crate) fn is_useful( | |||
573 | matrix: &Matrix, | 573 | matrix: &Matrix, |
574 | v: &PatStack, | 574 | v: &PatStack, |
575 | ) -> MatchCheckResult<Usefulness> { | 575 | ) -> MatchCheckResult<Usefulness> { |
576 | // Handle the special case of enums with no variants. In that case, no match | 576 | // Handle two special cases: |
577 | // arm is useful. | 577 | // - enum with no variants |
578 | if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(AdtId::EnumId(enum_id)), .. }) = | 578 | // - `!` type |
579 | cx.infer[cx.match_expr].strip_references() | 579 | // In those cases, no match arm is useful. |
580 | { | 580 | match cx.infer[cx.match_expr].strip_references() { |
581 | if cx.db.enum_data(*enum_id).variants.is_empty() { | 581 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(AdtId::EnumId(enum_id)), .. }) => { |
582 | if cx.db.enum_data(*enum_id).variants.is_empty() { | ||
583 | return Ok(Usefulness::NotUseful); | ||
584 | } | ||
585 | } | ||
586 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. }) => { | ||
582 | return Ok(Usefulness::NotUseful); | 587 | return Ok(Usefulness::NotUseful); |
583 | } | 588 | } |
589 | _ => (), | ||
584 | } | 590 | } |
585 | 591 | ||
586 | if v.is_empty() { | 592 | if v.is_empty() { |
@@ -1918,6 +1924,17 @@ mod tests { | |||
1918 | } | 1924 | } |
1919 | 1925 | ||
1920 | #[test] | 1926 | #[test] |
1927 | fn type_never() { | ||
1928 | let content = r" | ||
1929 | fn test_fn(never: !) { | ||
1930 | match never {} | ||
1931 | } | ||
1932 | "; | ||
1933 | |||
1934 | check_no_diagnostic(content); | ||
1935 | } | ||
1936 | |||
1937 | #[test] | ||
1921 | fn enum_never_ref() { | 1938 | fn enum_never_ref() { |
1922 | let content = r" | 1939 | let content = r" |
1923 | enum Never {} | 1940 | enum Never {} |
@@ -1929,6 +1946,23 @@ mod tests { | |||
1929 | 1946 | ||
1930 | check_no_diagnostic(content); | 1947 | check_no_diagnostic(content); |
1931 | } | 1948 | } |
1949 | |||
1950 | #[test] | ||
1951 | fn expr_diverges_missing_arm() { | ||
1952 | let content = r" | ||
1953 | enum Either { | ||
1954 | A, | ||
1955 | B, | ||
1956 | } | ||
1957 | fn test_fn() { | ||
1958 | match loop {} { | ||
1959 | Either::A => (), | ||
1960 | } | ||
1961 | } | ||
1962 | "; | ||
1963 | |||
1964 | check_no_diagnostic(content); | ||
1965 | } | ||
1932 | } | 1966 | } |
1933 | 1967 | ||
1934 | #[cfg(test)] | 1968 | #[cfg(test)] |
@@ -1981,26 +2015,6 @@ mod false_negatives { | |||
1981 | } | 2015 | } |
1982 | 2016 | ||
1983 | #[test] | 2017 | #[test] |
1984 | fn expr_diverges_missing_arm() { | ||
1985 | let content = r" | ||
1986 | enum Either { | ||
1987 | A, | ||
1988 | B, | ||
1989 | } | ||
1990 | fn test_fn() { | ||
1991 | match loop {} { | ||
1992 | Either::A => (), | ||
1993 | } | ||
1994 | } | ||
1995 | "; | ||
1996 | |||
1997 | // This is a false negative. | ||
1998 | // Even though the match expression diverges, rustc fails | ||
1999 | // to compile here since `Either::B` is missing. | ||
2000 | check_no_diagnostic(content); | ||
2001 | } | ||
2002 | |||
2003 | #[test] | ||
2004 | fn expr_loop_missing_arm() { | 2018 | fn expr_loop_missing_arm() { |
2005 | let content = r" | 2019 | let content = r" |
2006 | enum Either { | 2020 | enum Either { |
@@ -2018,7 +2032,7 @@ mod false_negatives { | |||
2018 | // We currently infer the type of `loop { break Foo::A }` to `!`, which | 2032 | // We currently infer the type of `loop { break Foo::A }` to `!`, which |
2019 | // causes us to skip the diagnostic since `Either::A` doesn't type check | 2033 | // causes us to skip the diagnostic since `Either::A` doesn't type check |
2020 | // with `!`. | 2034 | // with `!`. |
2021 | check_no_diagnostic(content); | 2035 | check_diagnostic(content); |
2022 | } | 2036 | } |
2023 | 2037 | ||
2024 | #[test] | 2038 | #[test] |