Created
May 21, 2013 03:54
-
-
Save yjh0502/5617381 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs | |
index d859e03..23300a9 100644 | |
--- a/src/librustc/middle/check_match.rs | |
+++ b/src/librustc/middle/check_match.rs | |
@@ -498,10 +498,29 @@ pub fn specialize(cx: @MatchCheckCtxt, | |
lookup_const_by_id(cx.tcx, did).get(); | |
let e_v = eval_const_expr(cx.tcx, const_expr); | |
let match_ = match *ctor_id { | |
- val(ref v) => compare_const_vals(&e_v, v) == 0, | |
+ val(ref v) => { | |
+ match compare_const_vals(&e_v, v) { | |
+ Some(val1) if val1 == 0 => true, | |
+ Some(_) => false, | |
+ None => { | |
+ cx.tcx.sess.span_err(pat_span, | |
+ "mismatched types between arms"); | |
+ false | |
+ } | |
+ } | |
+ }, | |
range(ref c_lo, ref c_hi) => { | |
- compare_const_vals(c_lo, &e_v) >= 0 && | |
- compare_const_vals(c_hi, &e_v) <= 0 | |
+ let m1 = compare_const_vals(c_lo, &e_v), | |
+ m2 = compare_const_vals(c_hi, &e_v); | |
+ match (m1, m2) { | |
+ (Some(val1), Some(val2)) if val1 >= 0 && val2 <= 0 => true, | |
+ (Some(_), Some(_)) => false, | |
+ _ => { | |
+ cx.tcx.sess.span_err(pat_span, | |
+ "mismatched types between ranges"); | |
+ false | |
+ } | |
+ } | |
} | |
single => true, | |
_ => fail!("type error") | |
@@ -529,10 +548,28 @@ pub fn specialize(cx: @MatchCheckCtxt, | |
lookup_const_by_id(cx.tcx, did).get(); | |
let e_v = eval_const_expr(cx.tcx, const_expr); | |
let match_ = match *ctor_id { | |
- val(ref v) => compare_const_vals(&e_v, v) == 0, | |
+ val(ref v) => | |
+ match compare_const_vals(&e_v, v) { | |
+ Some(val1) if val1 == 0 => true, | |
+ Some(_) => false, | |
+ None => { | |
+ cx.tcx.sess.span_err(pat_span, | |
+ "mismatched types between arms"); | |
+ false | |
+ } | |
+ }, | |
range(ref c_lo, ref c_hi) => { | |
- compare_const_vals(c_lo, &e_v) >= 0 && | |
- compare_const_vals(c_hi, &e_v) <= 0 | |
+ let m1 = compare_const_vals(c_lo, &e_v), | |
+ m2 = compare_const_vals(c_hi, &e_v); | |
+ match (m1, m2) { | |
+ (Some(val1), Some(val2)) if val1 >= 0 && val2 <= 0 => true, | |
+ (Some(_), Some(_)) => false, | |
+ _ => { | |
+ cx.tcx.sess.span_err(pat_span, | |
+ "mismatched types between ranges"); | |
+ false | |
+ } | |
+ } | |
} | |
single => true, | |
_ => fail!("type error") | |
@@ -619,10 +656,29 @@ pub fn specialize(cx: @MatchCheckCtxt, | |
pat_lit(expr) => { | |
let e_v = eval_const_expr(cx.tcx, expr); | |
let match_ = match *ctor_id { | |
- val(ref v) => compare_const_vals(&e_v, v) == 0, | |
+ val(ref v) => { | |
+ match compare_const_vals(&e_v, v) { | |
+ Some(val1) if val1 == 0 => true, | |
+ Some(_) => false, | |
+ None => { | |
+ cx.tcx.sess.span_err(pat_span, | |
+ "mismatched types between arms"); | |
+ false | |
+ } | |
+ } | |
+ }, | |
range(ref c_lo, ref c_hi) => { | |
- compare_const_vals(c_lo, &e_v) >= 0 && | |
- compare_const_vals(c_hi, &e_v) <= 0 | |
+ let m1 = compare_const_vals(c_lo, &e_v), | |
+ m2 = compare_const_vals(c_hi, &e_v); | |
+ match (m1, m2) { | |
+ (Some(val1), Some(val2)) if val1 >= 0 && val2 <= 0 => true, | |
+ (Some(_), Some(_)) => false, | |
+ _ => { | |
+ cx.tcx.sess.span_err(pat_span, | |
+ "mismatched types between ranges"); | |
+ false | |
+ } | |
+ } | |
} | |
single => true, | |
_ => fail!("type error") | |
@@ -638,11 +694,22 @@ pub fn specialize(cx: @MatchCheckCtxt, | |
_ => fail!("type error") | |
}; | |
let v_lo = eval_const_expr(cx.tcx, lo), | |
- v_hi = eval_const_expr(cx.tcx, hi); | |
- let match_ = compare_const_vals(&c_lo, &v_lo) >= 0 && | |
- compare_const_vals(&c_hi, &v_hi) <= 0; | |
- if match_ { Some(vec::to_owned(r.tail())) } else { None } | |
- } | |
+ v_hi = eval_const_expr(cx.tcx, hi); | |
+ | |
+ let m1 = compare_const_vals(&c_lo, &v_lo), | |
+ m2 = compare_const_vals(&c_hi, &v_hi); | |
+ match (m1, m2) { | |
+ (Some(val1), Some(val2)) if val1 >= 0 && val2 <= 0 => { | |
+ Some(vec::to_owned(r.tail())) | |
+ }, | |
+ (Some(_), Some(_)) => None, | |
+ _ => { | |
+ cx.tcx.sess.span_err(pat_span, | |
+ "mismatched types between ranges"); | |
+ None | |
+ } | |
+ } | |
+ } | |
pat_vec(before, slice, after) => { | |
match *ctor_id { | |
vec(_) => { | |
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs | |
index 6cc4409..252af2f 100644 | |
--- a/src/librustc/middle/const_eval.rs | |
+++ b/src/librustc/middle/const_eval.rs | |
@@ -420,65 +420,75 @@ pub fn lit_to_const(lit: @lit) -> const_val { | |
} | |
} | |
-pub fn compare_const_vals(a: &const_val, b: &const_val) -> int { | |
+pub fn compare_const_vals(a: &const_val, b: &const_val) -> Option<int> { | |
match (a, b) { | |
(&const_int(a), &const_int(b)) => { | |
if a == b { | |
- 0 | |
+ Some(0) | |
} else if a < b { | |
- -1 | |
+ Some(-1) | |
} else { | |
- 1 | |
+ Some(1) | |
} | |
} | |
(&const_uint(a), &const_uint(b)) => { | |
if a == b { | |
- 0 | |
+ Some(0) | |
} else if a < b { | |
- -1 | |
+ Some(-1) | |
} else { | |
- 1 | |
+ Some(1) | |
} | |
} | |
(&const_float(a), &const_float(b)) => { | |
if a == b { | |
- 0 | |
+ Some(0) | |
} else if a < b { | |
- -1 | |
+ Some(-1) | |
} else { | |
- 1 | |
+ Some(1) | |
} | |
} | |
(&const_str(ref a), &const_str(ref b)) => { | |
if (*a) == (*b) { | |
- 0 | |
+ Some(0) | |
} else if (*a) < (*b) { | |
- -1 | |
+ Some(-1) | |
} else { | |
- 1 | |
+ Some(1) | |
} | |
} | |
(&const_bool(a), &const_bool(b)) => { | |
if a == b { | |
- 0 | |
+ Some(0) | |
} else if a < b { | |
- -1 | |
+ Some(-1) | |
} else { | |
- 1 | |
+ Some(1) | |
} | |
} | |
- _ => fail!("compare_const_vals: ill-typed comparison") | |
+ _ => { | |
+ None | |
+ } | |
} | |
} | |
-pub fn compare_lit_exprs(tcx: middle::ty::ctxt, a: @expr, b: @expr) -> int { | |
- compare_const_vals(&eval_const_expr(tcx, a), &eval_const_expr(tcx, b)) | |
+pub fn compare_lit_exprs(tcx: middle::ty::ctxt, a: @expr, b: @expr) -> Option<int> { | |
+ compare_const_vals(&eval_const_expr(tcx, a), &eval_const_expr(tcx, b)) | |
} | |
-pub fn lit_expr_eq(tcx: middle::ty::ctxt, a: @expr, b: @expr) -> bool { | |
- compare_lit_exprs(tcx, a, b) == 0 | |
+pub fn lit_expr_eq(tcx: middle::ty::ctxt, a: @expr, b: @expr) -> Option<bool> { | |
+ match compare_lit_exprs(tcx, a, b) { | |
+ Some(val) if val == 0 => Some(true), | |
+ Some(_) => Some(false), | |
+ None => None, | |
+ } | |
} | |
-pub fn lit_eq(a: @lit, b: @lit) -> bool { | |
- compare_const_vals(&lit_to_const(a), &lit_to_const(b)) == 0 | |
+pub fn lit_eq(a: @lit, b: @lit) -> Option<bool> { | |
+ match compare_const_vals(&lit_to_const(a), &lit_to_const(b)) { | |
+ Some(val) if val == 0 => Some(true), | |
+ Some(_) => Some(false), | |
+ None => None, | |
+ } | |
} | |
diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs | |
index d2834a0..587a3d7 100644 | |
--- a/src/librustc/middle/trans/_match.rs | |
+++ b/src/librustc/middle/trans/_match.rs | |
@@ -193,48 +193,57 @@ pub enum Opt { | |
pub fn opt_eq(tcx: ty::ctxt, a: &Opt, b: &Opt) -> bool { | |
match (a, b) { | |
- (&lit(a), &lit(b)) => { | |
- match (a, b) { | |
- (UnitLikeStructLit(a), UnitLikeStructLit(b)) => a == b, | |
- _ => { | |
- let a_expr; | |
- match a { | |
- ExprLit(existing_a_expr) => a_expr = existing_a_expr, | |
- ConstLit(a_const) => { | |
- let e = const_eval::lookup_const_by_id(tcx, a_const); | |
- a_expr = e.get(); | |
- } | |
- UnitLikeStructLit(_) => { | |
- fail!("UnitLikeStructLit should have been handled \ | |
- above") | |
+ (&lit(a), &lit(b)) => { | |
+ match (a, b) { | |
+ (UnitLikeStructLit(a), UnitLikeStructLit(b)) => a == b, | |
+ _ => { | |
+ let a_expr; | |
+ match a { | |
+ ExprLit(existing_a_expr) => a_expr = existing_a_expr, | |
+ ConstLit(a_const) => { | |
+ let e = const_eval::lookup_const_by_id(tcx, a_const); | |
+ a_expr = e.get(); | |
+ } | |
+ UnitLikeStructLit(_) => { | |
+ fail!("UnitLikeStructLit should have been handled \ | |
+ above") | |
+ } | |
} | |
- } | |
- let b_expr; | |
- match b { | |
- ExprLit(existing_b_expr) => b_expr = existing_b_expr, | |
- ConstLit(b_const) => { | |
- let e = const_eval::lookup_const_by_id(tcx, b_const); | |
- b_expr = e.get(); | |
+ let b_expr; | |
+ match b { | |
+ ExprLit(existing_b_expr) => b_expr = existing_b_expr, | |
+ ConstLit(b_const) => { | |
+ let e = const_eval::lookup_const_by_id(tcx, b_const); | |
+ b_expr = e.get(); | |
+ } | |
+ UnitLikeStructLit(_) => { | |
+ fail!("UnitLikeStructLit should have been handled \ | |
+ above") | |
+ } | |
} | |
- UnitLikeStructLit(_) => { | |
- fail!("UnitLikeStructLit should have been handled \ | |
- above") | |
+ | |
+ match const_eval::compare_lit_exprs(tcx, a_expr, b_expr) { | |
+ Some(val) if val == 0 => true, | |
+ Some(_) => false, | |
+ None => fail!("compare_list_exprs: type mismatch"), | |
} | |
} | |
- | |
- const_eval::compare_lit_exprs(tcx, a_expr, b_expr) == 0 | |
} | |
} | |
- } | |
- (&range(a1, a2), &range(b1, b2)) => { | |
- const_eval::compare_lit_exprs(tcx, a1, b1) == 0 && | |
- const_eval::compare_lit_exprs(tcx, a2, b2) == 0 | |
- } | |
- (&var(a, _), &var(b, _)) => a == b, | |
- (&vec_len_eq(a), &vec_len_eq(b)) => a == b, | |
- (&vec_len_ge(a, _), &vec_len_ge(b, _)) => a == b, | |
- _ => false | |
+ (&range(a1, a2), &range(b1, b2)) => { | |
+ let m1 = const_eval::compare_lit_exprs(tcx, a1, b1); | |
+ let m2 = const_eval::compare_lit_exprs(tcx, a2, b2); | |
+ match (m1, m2) { | |
+ (Some(val1), Some(val2)) if val1 == 0 && val2 == 0 => true, | |
+ (Some(_), Some(_)) => false, | |
+ _ => fail!("compare_list_exprs: type mismatch"), | |
+ } | |
+ } | |
+ (&var(a, _), &var(b, _)) => a == b, | |
+ (&vec_len_eq(a), &vec_len_eq(b)) => a == b, | |
+ (&vec_len_ge(a, _), &vec_len_ge(b, _)) => a == b, | |
+ _ => false | |
} | |
} | |
diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs | |
index 0708345..4d856c0 100644 | |
--- a/src/librustc/middle/typeck/check/_match.rs | |
+++ b/src/librustc/middle/typeck/check/_match.rs | |
@@ -408,8 +408,18 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) { | |
// no-op | |
} else if !ty::type_is_numeric(b_ty) { | |
tcx.sess.span_err(pat.span, "non-numeric type used in range"); | |
- } else if !valid_range_bounds(fcx.ccx, begin, end) { | |
- tcx.sess.span_err(begin.span, "lower range bound must be less than upper"); | |
+ } else { | |
+ match valid_range_bounds(fcx.ccx, begin, end) { | |
+ Some(false) => { | |
+ tcx.sess.span_err(begin.span, | |
+ "lower range bound must be less than upper"); | |
+ }, | |
+ None => { | |
+ tcx.sess.span_err(begin.span, | |
+ "mismatched types in range"); | |
+ }, | |
+ _ => { }, | |
+ } | |
} | |
fcx.write_ty(pat.id, b_ty); | |
} | |
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs | |
index 942f73b..6c939a8 100644 | |
--- a/src/librustc/middle/typeck/check/mod.rs | |
+++ b/src/librustc/middle/typeck/check/mod.rs | |
@@ -1053,8 +1053,12 @@ pub fn check_lit(fcx: @mut FnCtxt, lit: @ast::lit) -> ty::t { | |
pub fn valid_range_bounds(ccx: @mut CrateCtxt, | |
from: @ast::expr, | |
to: @ast::expr) | |
- -> bool { | |
- const_eval::compare_lit_exprs(ccx.tcx, from, to) <= 0 | |
+ -> Option<bool> { | |
+ match const_eval::compare_lit_exprs(ccx.tcx, from, to) { | |
+ Some(val) if val <= 0 => Some(true), | |
+ Some(_) => Some(false), | |
+ None => None | |
+ } | |
} | |
pub fn check_expr_has_type( |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment