about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNadrieril <nadrieril+git@gmail.com>2019-12-04 16:13:19 +0000
committerNadrieril <nadrieril+git@gmail.com>2019-12-04 16:43:25 +0000
commita591ede2e21807f23013fde9d63ee0af04d6faf3 (patch)
treeafe4cde250c37241497c45f6ab895a6180386572
parentbfb556f97d47689ac110373de4986ce14fd52d30 (diff)
downloadrust-a591ede2e21807f23013fde9d63ee0af04d6faf3.tar.gz
rust-a591ede2e21807f23013fde9d63ee0af04d6faf3.zip
Only special-case empty matches when `exhaustive_patterns` is off
When the feature is on, the special casing is not needed. That way when
we stabilize the feature this `if` can just be removed.
-rw-r--r--src/librustc_mir/hair/pattern/check_match.rs31
1 files changed, 14 insertions, 17 deletions
diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs
index d29169cb341..fc14506f305 100644
--- a/src/librustc_mir/hair/pattern/check_match.rs
+++ b/src/librustc_mir/hair/pattern/check_match.rs
@@ -168,6 +168,8 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
 
             // Fifth, check if the match is exhaustive.
             let scrut_ty = self.tables.node_type(scrut.hir_id);
+            // 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 is_empty_match = inlined_arms.is_empty();
             check_exhaustive(cx, scrut_ty, scrut.span, &matrix, scrut.hir_id, is_empty_match);
         })
@@ -435,27 +437,22 @@ fn check_exhaustive<'p, 'tcx>(
     hir_id: HirId,
     is_empty_match: bool,
 ) {
-    // If the match has no arms, check whether the scrutinee is uninhabited.
-    // 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 scrutinee_is_visibly_uninhabited = if cx.tcx.features().exhaustive_patterns {
-        let module = cx.tcx.hir().get_module_parent(hir_id);
-        cx.tcx.is_ty_uninhabited_from(module, scrut_ty)
-    } else {
-        match scrut_ty.kind {
+    // In the absence of the `exhaustive_patterns` feature, empty matches are not detected by
+    // `is_useful` to exhaustively match uninhabited types, so we manually check here.
+    if is_empty_match && !cx.tcx.features().exhaustive_patterns {
+        let scrutinee_is_visibly_uninhabited = match scrut_ty.kind {
             ty::Never => true,
-            ty::Adt(def, _) if def.is_enum() => {
-                def.variants.is_empty() && !cx.is_foreign_non_exhaustive_enum(scrut_ty)
+            ty::Adt(def, _) => {
+                def.is_enum()
+                    && def.variants.is_empty()
+                    && !cx.is_foreign_non_exhaustive_enum(scrut_ty)
             }
             _ => false,
+        };
+        if scrutinee_is_visibly_uninhabited {
+            // If the type *is* uninhabited, an empty match is vacuously exhaustive.
+            return;
         }
-    };
-    if is_empty_match && scrutinee_is_visibly_uninhabited {
-        // If the type *is* uninhabited, it's vacuously exhaustive.
-        // This early return is only needed here because in the absence of the
-        // `exhaustive_patterns` feature, empty matches are not detected by `is_useful`
-        // to exhaustively match uninhabited types.
-        return;
     }
 
     let witnesses = match check_not_useful(cx, scrut_ty, matrix, hir_id) {