Add support for unit literals to const_eval.
This commit is contained in:
Jakub Wieczorek 2014-06-24 00:12:17 +02:00 committed by Alex Crichton
parent 85effb9f3e
commit c484c2d1f8
7 changed files with 89 additions and 11 deletions

View File

@ -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)
}

View File

@ -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
}
}

View File

@ -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,

View File

@ -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)) => ()
}
}

View File

@ -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() {}

View File

@ -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
}

View File

@ -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());
}