aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirill Bulatov <[email protected]>2019-08-14 20:20:18 +0100
committerKirill Bulatov <[email protected]>2019-08-26 20:44:50 +0100
commit44cf7b34fe1a486168590f7fead442f12602c419 (patch)
treecc57761879baba138231882b4147bade8bc4bfbd
parentc1f47c37886b5cba116ba99fa37977d51871eba4 (diff)
Fix never in if expressions
-rw-r--r--crates/ra_hir/src/marks.rs2
-rw-r--r--crates/ra_hir/src/ty/infer.rs13
-rw-r--r--crates/ra_hir/src/ty/tests.rs42
3 files changed, 53 insertions, 4 deletions
diff --git a/crates/ra_hir/src/marks.rs b/crates/ra_hir/src/marks.rs
index 3795debc1..1adf5cd53 100644
--- a/crates/ra_hir/src/marks.rs
+++ b/crates/ra_hir/src/marks.rs
@@ -16,4 +16,6 @@ test_utils::marks!(
16 match_second_arm_never 16 match_second_arm_never
17 match_all_arms_never 17 match_all_arms_never
18 match_no_never_arms 18 match_no_never_arms
19 if_never
20 if_else_never
19); 21);
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index b310bf6bd..d01063766 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -987,14 +987,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
987 let then_ty = self.infer_expr(*then_branch, expected); 987 let then_ty = self.infer_expr(*then_branch, expected);
988 match else_branch { 988 match else_branch {
989 Some(else_branch) => { 989 Some(else_branch) => {
990 self.infer_expr(*else_branch, expected); 990 let else_ty = self.infer_expr(*else_branch, expected);
991 if Self::is_never(&then_ty) {
992 tested_by!(if_never);
993 else_ty
994 } else {
995 tested_by!(if_else_never);
996 then_ty
997 }
991 } 998 }
992 None => { 999 None => {
993 // no else branch -> unit 1000 // no else branch -> unit
994 self.unify(&then_ty, &Ty::unit()); // actually coerce 1001 self.unify(&then_ty, &Ty::unit()); // actually coerce
1002 then_ty
995 } 1003 }
996 }; 1004 }
997 then_ty
998 } 1005 }
999 Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected), 1006 Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected),
1000 Expr::TryBlock { body } => { 1007 Expr::TryBlock { body } => {
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index 7ec834836..94b0fe3b3 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -3595,7 +3595,7 @@ fn no_such_field_diagnostics() {
3595 ); 3595 );
3596} 3596}
3597 3597
3598mod match_with_never_tests { 3598mod branching_with_never_tests {
3599 use super::type_at; 3599 use super::type_at;
3600 use test_utils::covers; 3600 use test_utils::covers;
3601 3601
@@ -3645,6 +3645,46 @@ fn test(a: i32) {
3645 } 3645 }
3646 3646
3647 #[test] 3647 #[test]
3648 fn if_never() {
3649 covers!(if_never);
3650 let t = type_at(
3651 r#"
3652//- /main.rs
3653fn test() {
3654 let i = if true {
3655 loop {}
3656 } else {
3657 3.0
3658 };
3659 i<|>
3660 ()
3661}
3662"#,
3663 );
3664 assert_eq!(t, "f64");
3665 }
3666
3667 #[test]
3668 fn if_else_never() {
3669 covers!(if_else_never);
3670 let t = type_at(
3671 r#"
3672//- /main.rs
3673fn test(input: bool) {
3674 let i = if input {
3675 2.0
3676 } else {
3677 return
3678 };
3679 i<|>
3680 ()
3681}
3682"#,
3683 );
3684 assert_eq!(t, "f64");
3685 }
3686
3687 #[test]
3648 fn match_second_arm_never() { 3688 fn match_second_arm_never() {
3649 covers!(match_second_arm_never); 3689 covers!(match_second_arm_never);
3650 let t = type_at( 3690 let t = type_at(