From c484c2d1f840a3fd195b951a67745564b51715ad Mon Sep 17 00:00:00 2001 From: Jakub Wieczorek <jakub@jakub.cc> Date: Tue, 24 Jun 2014 00:12:17 +0200 Subject: [PATCH] Fix #15129 Add support for unit literals to const_eval. --- src/librustc/middle/check_match.rs | 9 ++--- src/librustc/middle/const_eval.rs | 6 ++-- src/librustc/middle/ty.rs | 6 ++++ src/test/compile-fail/issue-15129.rs | 27 +++++++++++++++ .../non-exhaustive-pattern-witness.rs | 11 ++++--- src/test/compile-fail/repeat_count.rs | 8 ++++- src/test/run-pass/issue-15129.rs | 33 +++++++++++++++++++ 7 files changed, 89 insertions(+), 11 deletions(-) create mode 100644 src/test/compile-fail/issue-15129.rs create mode 100644 src/test/run-pass/issue-15129.rs diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 09a9273dba7..629c7f4dab7 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<Expr> { 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<ctor ty::ty_bool => [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<ctor ty::ty_vec(_, Some(n)) => 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 4444cac0043..7567e73b01d 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<Vec<u8> >), - 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::<f64>(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<int> { (&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 b0e838a442b..689a47f1136 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -4184,6 +4184,12 @@ pub fn eval_repeat_count<T: ExprTyProvider>(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 00000000000..83d7096087e --- /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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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 d0f51bf2da4..7fba306d868 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 692c51b5b5f..6d8655fd7d4 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 00000000000..fcc392e3779 --- /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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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()); +}