about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNadrieril <nadrieril+git@gmail.com>2020-05-09 15:17:16 +0100
committerNadrieril <nadrieril+git@gmail.com>2020-05-17 17:38:24 +0100
commit079400c74b2a4f0e173a1f22a54cb29e8c8fd5ba (patch)
tree35bef70f1131cad1c4293ec11d92154c73551376 /src
parente5a2cd526a6ad92b90dda81104abc7adf4c83495 (diff)
downloadrust-079400c74b2a4f0e173a1f22a54cb29e8c8fd5ba.tar.gz
rust-079400c74b2a4f0e173a1f22a54cb29e8c8fd5ba.zip
Fix bug just discovered
Suggested by matthewjasper here:
https://github.com/rust-lang/rust/pull/71930#issuecomment-626022502
I have no idea what this does but it seems to work.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir_build/hair/pattern/check_match.rs22
-rw-r--r--src/librustc_typeck/check/_match.rs2
2 files changed, 3 insertions, 21 deletions
diff --git a/src/librustc_mir_build/hair/pattern/check_match.rs b/src/librustc_mir_build/hair/pattern/check_match.rs
index b805e858aac..707502640e0 100644
--- a/src/librustc_mir_build/hair/pattern/check_match.rs
+++ b/src/librustc_mir_build/hair/pattern/check_match.rs
@@ -186,30 +186,10 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
         // Fourth, check for unreachable arms.
         let matrix = check_arms(&mut cx, &inlined_arms, source);
 
-        // FIXME: getting the type using `node_type` means that if `f` has output type `!`, we
-        // get `scrut_ty = !` instead of `bool` in the following:
-        // ```
-        // fn from(never: !) -> usize {
-        //     match never {
-        //         true => 1,
-        //         false => 0,
-        //     }
-        // }
-        // ```
-        // If we use `expr_ty_adjusted` instead, then the following breaks, because we get
-        // `scrut_ty = ()` instead of `!`.
-        // ```
-        // fn from(never: !) -> usize {
-        //     match never {}
-        // }
-        // ```
-        // As a workaround, we retrieve the type from the match arms when possible.
-        let scrut_ty = self.tables.node_type(scrut.hir_id);
-        let scrut_ty = inlined_arms.iter().map(|(p, _, _)| p.ty).next().unwrap_or(scrut_ty);
-
         // Fifth, check if the match is exhaustive.
         // Note: An empty match isn't the same as an empty matrix for diagnostics purposes,
         // since an empty matrix can occur when there are arms, if those arms all have guards.
+        let scrut_ty = self.tables.expr_ty_adjusted(scrut);
         let is_empty_match = inlined_arms.is_empty();
         check_exhaustive(&mut cx, scrut_ty, scrut.span, &matrix, scrut.hir_id, is_empty_match);
     }
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 16af168ce1a..fb139b5033b 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -436,6 +436,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         if let Some(m) = contains_ref_bindings {
             self.check_expr_with_needs(scrut, Needs::maybe_mut_place(m))
+        } else if arms.is_empty() {
+            self.check_expr(scrut)
         } else {
             // ...but otherwise we want to use any supertype of the
             // scrutinee. This is sort of a workaround, see note (*) in