]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_const_eval/check_match.rs
use a more conservative inhabitableness rule
[rust.git] / src / librustc_const_eval / check_match.rs
index e5362a70e53b6fbc44ed648fbf1f5f0670548af5..9b30946c0bebbc1d834cd9cdd045352dbd76be28 100644 (file)
@@ -182,7 +182,12 @@ fn check_match(
             let pat_ty = self.tables.node_id_to_type(scrut.id);
             let module = self.tcx.hir.local_def_id(self.tcx.hir.get_module_parent(scrut.id));
             if inlined_arms.is_empty() {
-                if !pat_ty.is_uninhabited_from(module, self.tcx) {
+                let scrutinee_is_uninhabited = if self.tcx.sess.features.borrow().never_type {
+                    pat_ty.is_uninhabited_from(module, self.tcx)
+                } else {
+                    self.conservative_is_uninhabited(pat_ty)
+                };
+                if !scrutinee_is_uninhabited {
                     // We know the type is inhabited, so this must be wrong
                     let mut err = create_e0004(self.tcx.sess, scrut.span,
                                                format!("non-exhaustive patterns: type {} \
@@ -208,6 +213,15 @@ fn check_match(
         })
     }
 
+    fn conservative_is_uninhabited(&self, scrutinee_ty: Ty<'tcx>) -> bool {
+        // "rustc-1.0-style" uncontentious uninhabitableness check
+        match scrutinee_ty.sty {
+            ty::TyNever => true,
+            ty::TyAdt(def, _) => def.variants.is_empty(),
+            _ => false
+        }
+    }
+
     fn check_irrefutable(&self, pat: &Pat, is_fn_arg: bool) {
         let origin = if is_fn_arg {
             "function argument"