diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 09a9273dba73a..629c7f4dab709 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -10,7 +10,7 @@ #![allow(non_camel_case_types)] -use middle::const_eval::{compare_const_vals, const_bool, const_float, const_val}; +use middle::const_eval::{compare_const_vals, const_bool, const_float, const_nil, const_val}; use middle::const_eval::{eval_const_expr, lookup_const_by_id}; use middle::def::*; use middle::pat_util::*; @@ -203,6 +203,7 @@ enum ctor { fn const_val_to_expr(value: &const_val) -> Gc { let node = match value { &const_bool(b) => LitBool(b), + &const_nil => LitNil, _ => unreachable!() }; box(GC) Expr { @@ -309,6 +310,9 @@ fn all_constructors(cx: &MatchCheckCtxt, m: &Matrix, left_ty: ty::t) -> Vec [true, false].iter().map(|b| val(const_bool(*b))).collect(), + ty::ty_nil => + vec!(val(const_nil)), + ty::ty_rptr(_, ty::mt { ty: ty, .. }) => match ty::get(ty).sty { ty::ty_vec(_, None) => vec_constructors(m), _ => vec!(single) @@ -326,9 +330,6 @@ fn all_constructors(cx: &MatchCheckCtxt, m: &Matrix, left_ty: ty::t) -> Vec vec!(vec(n)), - ty::ty_nil if !m.iter().all(|r| is_wild(cx, *r.get(0))) => - vec!(), - _ => vec!(single) } diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 72def2c10da32..942b8ba7962ed 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -299,7 +299,8 @@ pub enum const_val { const_uint(u64), const_str(InternedString), const_binary(Rc >), - const_bool(bool) + const_bool(bool), + const_nil } pub fn eval_const_expr(tcx: &ty::ctxt, e: &Expr) -> const_val { @@ -514,7 +515,7 @@ pub fn lit_to_const(lit: &Lit) -> const_val { LitFloat(ref n, _) | LitFloatUnsuffixed(ref n) => { const_float(from_str::(n.get()).unwrap() as f64) } - LitNil => const_int(0i64), + LitNil => const_nil, LitBool(b) => const_bool(b) } } @@ -530,6 +531,7 @@ pub fn compare_const_vals(a: &const_val, b: &const_val) -> Option { (&const_str(ref a), &const_str(ref b)) => compare_vals(a, b), (&const_bool(a), &const_bool(b)) => compare_vals(a, b), (&const_binary(ref a), &const_binary(ref b)) => compare_vals(a, b), + (&const_nil, &const_nil) => compare_vals((), ()), _ => None } } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 00a0e8fc39bd6..9bb498de24ed1 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -4184,6 +4184,12 @@ pub fn eval_repeat_count(tcx: &T, count_expr: &ast::Expr) -> repeat count but found binary array"); return 0; } + const_eval::const_nil => { + tcx.ty_ctxt().sess.span_err(count_expr.span, + "expected positive integer for \ + repeat count but found ()"); + return 0; + } }, Err(..) => { tcx.ty_ctxt().sess.span_err(count_expr.span, diff --git a/src/test/compile-fail/issue-15129.rs b/src/test/compile-fail/issue-15129.rs new file mode 100644 index 0000000000000..83d7096087ef8 --- /dev/null +++ b/src/test/compile-fail/issue-15129.rs @@ -0,0 +1,27 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub enum T { + T1(()), + T2(()) +} + +pub enum V { + V1(int), + V2(bool) +} + +fn main() { + match (T1(()), V2(true)) { + //~^ ERROR non-exhaustive patterns: `(T1(()), V2(_))` not covered + (T1(()), V1(i)) => (), + (T2(()), V2(b)) => () + } +} diff --git a/src/test/compile-fail/non-exhaustive-pattern-witness.rs b/src/test/compile-fail/non-exhaustive-pattern-witness.rs index d0f51bf2da43b..7fba306d86860 100644 --- a/src/test/compile-fail/non-exhaustive-pattern-witness.rs +++ b/src/test/compile-fail/non-exhaustive-pattern-witness.rs @@ -67,8 +67,11 @@ fn vectors_with_nested_enums() { } } -fn main() { - struct_with_a_nested_enum_and_vector(); - enum_with_multiple_missing_variants(); - enum_struct_variant(); +fn missing_nil() { + match ((), false) { + //~^ ERROR non-exhaustive patterns: `((), false)` not covered + ((), true) => () + } } + +fn main() {} diff --git a/src/test/compile-fail/repeat_count.rs b/src/test/compile-fail/repeat_count.rs index 692c51b5b5ff7..6d8655fd7d452 100644 --- a/src/test/compile-fail/repeat_count.rs +++ b/src/test/compile-fail/repeat_count.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -13,4 +13,10 @@ fn main() { let n = 1; let a = [0, ..n]; //~ ERROR expected constant integer for repeat count but found variable + let b = [0, ..()]; //~ ERROR expected positive integer for repeat count but found () + let c = [0, ..true]; //~ ERROR expected positive integer for repeat count but found boolean + let d = [0, ..0.5]; //~ ERROR expected positive integer for repeat count but found float + let e = [0, .."foo"]; //~ ERROR expected positive integer for repeat count but found string + let f = [0, ..-4]; + //~^ ERROR expected positive integer for repeat count but found negative integer } diff --git a/src/test/run-pass/issue-15129.rs b/src/test/run-pass/issue-15129.rs new file mode 100644 index 0000000000000..fcc392e3779dc --- /dev/null +++ b/src/test/run-pass/issue-15129.rs @@ -0,0 +1,33 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub enum T { + T1(()), + T2(()) +} + +pub enum V { + V1(int), + V2(bool) +} + +fn foo(x: (T, V)) -> String { + match x { + (T1(()), V1(i)) => format!("T1(()), V1({})", i), + (T2(()), V2(b)) => format!("T2(()), V2({})", b), + _ => String::new() + } +} + + +fn main() { + assert_eq!(foo((T1(()), V1(99))), "T1(()), V1(99)".to_string()); + assert_eq!(foo((T2(()), V2(true))), "T2(()), V2(true)".to_string()); +}