Skip to content

Instantly share code, notes, and snippets.

@yjh0502
Created May 21, 2013 03:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yjh0502/5617381 to your computer and use it in GitHub Desktop.
Save yjh0502/5617381 to your computer and use it in GitHub Desktop.
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