about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2012-08-15 14:28:52 -0700
committerTim Chevalier <chevalier@alum.wellesley.edu>2012-08-15 14:57:45 -0700
commitc0140f5c344a206b4147d03d306bd6c83468d30b (patch)
tree4d2dcd5fb38d06b640c8bc7ee742959119ee1257
parenta83414b6e8879b2485374469f7f5fe60f22ae936 (diff)
downloadrust-c0140f5c344a206b4147d03d306bd6c83468d30b.tar.gz
rust-c0140f5c344a206b4147d03d306bd6c83468d30b.zip
Reject empty matches on inhabited types
Closes #3096
-rw-r--r--src/rustc/middle/check_alt.rs12
-rw-r--r--src/test/compile-fail/issue-3096-1.rs3
-rw-r--r--src/test/compile-fail/issue-3096-2.rs6
3 files changed, 18 insertions, 3 deletions
diff --git a/src/rustc/middle/check_alt.rs b/src/rustc/middle/check_alt.rs
index 796c30a31c0..66216b523cb 100644
--- a/src/rustc/middle/check_alt.rs
+++ b/src/rustc/middle/check_alt.rs
@@ -4,6 +4,7 @@ import const_eval::{eval_const_expr, const_val, const_int,
                     compare_const_vals};
 import syntax::codemap::span;
 import syntax::print::pprust::pat_to_str;
+import util::ppaux::ty_to_str;
 import pat_util::*;
 import syntax::visit;
 import driver::session::session;
@@ -29,10 +30,15 @@ fn check_expr(tcx: ty::ctxt, ex: @expr, &&s: (), v: visit::vt<()>) {
          // Check for empty enum, because is_useful only works on inhabited
          // types.
        let pat_ty = node_id_to_type(tcx, scrut.id);
-       if type_is_empty(tcx, pat_ty) && arms.is_empty() {
-               // Vacuously exhaustive
-               return;
+       if arms.is_empty() {
+           if !type_is_empty(tcx, pat_ty) {
+               // We know the type is inhabited, so this must be wrong
+               tcx.sess.span_err(ex.span, #fmt("non-exhaustive patterns: \
+                             type %s is non-empty", ty_to_str(tcx, pat_ty)));
            }
+           // If the type *is* empty, it's vacuously exhaustive
+           return;
+       }
        match ty::get(pat_ty).struct {
           ty_enum(did, _) => {
               if (*enum_variants(tcx, did)).is_empty() && arms.is_empty() {
diff --git a/src/test/compile-fail/issue-3096-1.rs b/src/test/compile-fail/issue-3096-1.rs
new file mode 100644
index 00000000000..edc3b322305
--- /dev/null
+++ b/src/test/compile-fail/issue-3096-1.rs
@@ -0,0 +1,3 @@
+fn main() {
+    match () { } //~ ERROR non-exhaustive
+}
diff --git a/src/test/compile-fail/issue-3096-2.rs b/src/test/compile-fail/issue-3096-2.rs
new file mode 100644
index 00000000000..cd3d63b5888
--- /dev/null
+++ b/src/test/compile-fail/issue-3096-2.rs
@@ -0,0 +1,6 @@
+enum bottom { } 
+
+fn main() {
+    let x = ptr::addr_of(()) as *bottom;
+    match x { } //~ ERROR non-exhaustive patterns
+}