Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

rustc: Make shape-based compare glue never called for comparison oper…

…ators.

Only called for string patterns.
  • Loading branch information...
commit 22b875770543ec1fe93cfb35fd07c692db5675e2 1 parent 9a15c50
@pcwalton pcwalton authored
View
2  src/libcore/iter.rs
@@ -179,7 +179,7 @@ pure fn min<A:Copy Ord,IA:BaseIter<A>>(self: IA) -> A {
}
}
-pure fn max<A:Copy,IA:BaseIter<A>>(self: IA) -> A {
+pure fn max<A:Copy Ord,IA:BaseIter<A>>(self: IA) -> A {
match do foldl::<A,Option<A>,IA>(self, None) |a, b| {
match a {
Some(a_) if a_ > b => {
View
17 src/libcore/str.rs
@@ -769,28 +769,17 @@ pure fn lt(a: &str, b: &str) -> bool {
/// Bytewise less than or equal
pure fn le(a: &str, b: &str) -> bool {
- let (a_len, b_len) = (a.len(), b.len());
- let mut end = uint::min(a_len, b_len);
-
- let mut i = 0;
- while i < end {
- let (c_a, c_b) = (a[i], b[i]);
- if c_a < c_b { return true; }
- if c_a > c_b { return false; }
- i += 1;
- }
-
- return a_len <= b_len;
+ !lt(b, a)
}
/// Bytewise greater than or equal
pure fn ge(a: &str, b: &str) -> bool {
- !lt(b, a)
+ !lt(a, b)
}
/// Bytewise greater than
pure fn gt(a: &str, b: &str) -> bool {
- !le(b, a)
+ !le(a, b)
}
impl &str: Eq {
View
40 src/libcore/task.rs
@@ -158,6 +158,46 @@ enum SchedMode {
PlatformThread
}
+impl SchedMode : cmp::Eq {
+ pure fn eq(&&other: SchedMode) -> bool {
+ match self {
+ SingleThreaded => {
+ match other {
+ SingleThreaded => true,
+ _ => false
+ }
+ }
+ ThreadPerCore => {
+ match other {
+ ThreadPerCore => true,
+ _ => false
+ }
+ }
+ ThreadPerTask => {
+ match other {
+ ThreadPerTask => true,
+ _ => false
+ }
+ }
+ ManualThreads(e0a) => {
+ match other {
+ ManualThreads(e0b) => e0a == e0b,
+ _ => false
+ }
+ }
+ PlatformThread => {
+ match other {
+ PlatformThread => true,
+ _ => false
+ }
+ }
+ }
+ }
+ pure fn ne(&&other: SchedMode) -> bool {
+ !self.eq(other)
+ }
+}
+
/**
* Scheduler configuration options
*
View
79 src/libstd/json.rs
@@ -3,11 +3,12 @@
//! json serialization
-use core::cmp::Eq;
+use core::cmp::{Eq, Ord};
use result::{Result, Ok, Err};
use io::WriterUtil;
use map::hashmap;
use map::map;
+use sort::Sort;
export Json;
export Error;
@@ -603,6 +604,75 @@ pure fn eq(value0: Json, value1: Json) -> bool {
}
}
+/// Test if two json values are less than one another
+pure fn lt(value0: Json, value1: Json) -> bool {
+ match value0 {
+ Num(f0) => {
+ match value1 {
+ Num(f1) => f0 < f1,
+ String(_) | Boolean(_) | List(_) | Dict(_) | Null => true
+ }
+ }
+
+ String(s0) => {
+ match value1 {
+ Num(_) => false,
+ String(s1) => s0 < s1,
+ Boolean(_) | List(_) | Dict(_) | Null => true
+ }
+ }
+
+ Boolean(b0) => {
+ match value1 {
+ Num(_) | String(_) => false,
+ Boolean(b1) => b0 < b1,
+ List(_) | Dict(_) | Null => true
+ }
+ }
+
+ List(l0) => {
+ match value1 {
+ Num(_) | String(_) | Boolean(_) => false,
+ List(l1) => l0 < l1,
+ Dict(_) | Null => true
+ }
+ }
+
+ Dict(d0) => {
+ match value1 {
+ Num(_) | String(_) | Boolean(_) | List(_) => false,
+ Dict(d1) => {
+ unchecked {
+ let (d0_flat, d1_flat) = {
+ let d0_flat = dvec::DVec();
+ for d0.each |k, v| { d0_flat.push((k, v)); }
+ let d0_flat = dvec::unwrap(d0_flat);
+ d0_flat.qsort();
+
+ let mut d1_flat = dvec::DVec();
+ for d1.each |k, v| { d1_flat.push((k, v)); }
+ let d1_flat = dvec::unwrap(d1_flat);
+ d1_flat.qsort();
+
+ (d0_flat, d1_flat)
+ };
+
+ d0_flat < d1_flat
+ }
+ }
+ Null => true
+ }
+ }
+
+ Null => {
+ match value1 {
+ Num(_) | String(_) | Boolean(_) | List(_) | Dict(_) => false,
+ Null => true
+ }
+ }
+ }
+}
+
impl Error : Eq {
pure fn eq(&&other: Error) -> bool {
self.line == other.line &&
@@ -617,6 +687,13 @@ impl Json : Eq {
pure fn ne(&&other: Json) -> bool { !self.eq(other) }
}
+impl Json : Ord {
+ pure fn lt(&&other: Json) -> bool { lt(self, other) }
+ pure fn le(&&other: Json) -> bool { !other.lt(self) }
+ pure fn ge(&&other: Json) -> bool { !self.lt(other) }
+ pure fn gt(&&other: Json) -> bool { other.lt(self) }
+}
+
trait ToJson { fn to_json() -> Json; }
impl Json: ToJson {
View
51 src/libsyntax/ast.rs
@@ -405,6 +405,13 @@ enum proto {
proto_block, // fn&
}
+impl proto : cmp::Eq {
+ pure fn eq(&&other: proto) -> bool {
+ (self as uint) == (other as uint)
+ }
+ pure fn ne(&&other: proto) -> bool { !self.eq(other) }
+}
+
#[auto_serialize]
enum vstore {
// FIXME (#2112): Change uint to @expr (actually only constant exprs)
@@ -454,7 +461,49 @@ impl binop : cmp::Eq {
enum unop {
box(mutability),
uniq(mutability),
- deref, not, neg
+ deref,
+ not,
+ neg
+}
+
+impl unop : cmp::Eq {
+ pure fn eq(&&other: unop) -> bool {
+ match self {
+ box(e0a) => {
+ match other {
+ box(e0b) => e0a == e0b,
+ _ => false
+ }
+ }
+ uniq(e0a) => {
+ match other {
+ uniq(e0b) => e0a == e0b,
+ _ => false
+ }
+ }
+ deref => {
+ match other {
+ deref => true,
+ _ => false
+ }
+ }
+ not => {
+ match other {
+ not => true,
+ _ => false
+ }
+ }
+ neg => {
+ match other {
+ neg => true,
+ _ => false
+ }
+ }
+ }
+ }
+ pure fn ne(&&other: unop) -> bool {
+ !self.eq(other)
+ }
}
// Generally, after typeck you can get the inferred value
View
7 src/libsyntax/attr.rs
@@ -337,6 +337,13 @@ enum inline_attr {
ia_never,
}
+impl inline_attr : cmp::Eq {
+ pure fn eq(&&other: inline_attr) -> bool {
+ (self as uint) == (other as uint)
+ }
+ pure fn ne(&&other: inline_attr) -> bool { !self.eq(other) }
+}
+
/// True if something like #[inline] is found in the list of attrs.
fn find_inline_attr(attrs: ~[ast::attribute]) -> inline_attr {
// FIXME (#2809)---validate the usage of #[inline] and #[inline(always)]
View
2  src/libsyntax/ext/pipes/proto.rs
@@ -143,7 +143,7 @@ struct protocol_ {
fn get_state_by_id(id: uint) -> state { self.states[id] }
fn has_state(name: ~str) -> bool {
- self.states.find(|i| i.name == name) != None
+ self.states.find(|i| i.name == name).is_some()
}
fn filename() -> ~str {
View
4 src/libsyntax/ext/simplext.rs
@@ -68,7 +68,7 @@ fn elts_to_ell(cx: ext_ctxt, elts: ~[@expr]) ->
match elt.node {
expr_mac(m) => match m.node {
ast::mac_ellipsis => {
- if res != None {
+ if res.is_some() {
cx.span_fatal(m.span, ~"only one ellipsis allowed");
}
res =
@@ -449,7 +449,7 @@ fn p_t_s_rec(cx: ext_ctxt, m: matchable, s: selector, b: binders) {
}
}
{pre: pre, rep: None, post: post} => {
- if post != ~[] {
+ if post.len() > 0 {
cx.bug(~"elts_to_ell provided an invalid result");
}
p_t_s_r_length(cx, vec::len(pre), false, s, b);
View
9 src/libsyntax/parse/comments.rs
@@ -17,6 +17,15 @@ enum cmnt_style {
blank_line, // Just a manual blank line "\n\n", for layout
}
+impl cmnt_style : cmp::Eq {
+ pure fn eq(&&other: cmnt_style) -> bool {
+ (self as uint) == (other as uint)
+ }
+ pure fn ne(&&other: cmnt_style) -> bool {
+ (self as uint) != (other as uint)
+ }
+}
+
type cmnt = {style: cmnt_style, lines: ~[~str], pos: uint};
fn is_doc_comment(s: ~str) -> bool {
View
43 src/libsyntax/print/pprust.rs
@@ -1616,10 +1616,13 @@ fn print_fn_args_and_ret(s: ps, decl: ast::fn_decl,
pclose(s);
maybe_print_comment(s, decl.output.span.lo);
- if decl.output.node != ast::ty_nil {
- space_if_not_bol(s);
- word_space(s, ~"->");
- print_type(s, decl.output);
+ match decl.output.node {
+ ast::ty_nil => {}
+ _ => {
+ space_if_not_bol(s);
+ word_space(s, ~"->");
+ print_type(s, decl.output);
+ }
}
}
@@ -1628,11 +1631,16 @@ fn print_fn_block_args(s: ps, decl: ast::fn_decl,
word(s.s, ~"|");
print_fn_args(s, decl, cap_items, None);
word(s.s, ~"|");
- if decl.output.node != ast::ty_infer {
- space_if_not_bol(s);
- word_space(s, ~"->");
- print_type(s, decl.output);
+
+ match decl.output.node {
+ ast::ty_infer => {}
+ _ => {
+ space_if_not_bol(s);
+ word_space(s, ~"->");
+ print_type(s, decl.output);
+ }
}
+
maybe_print_comment(s, decl.output.span.lo);
}
@@ -1829,14 +1837,19 @@ fn print_ty_fn(s: ps, opt_proto: Option<ast::proto>, purity: ast::purity,
pclose(s);
maybe_print_comment(s, decl.output.span.lo);
- if decl.output.node != ast::ty_nil {
- space_if_not_bol(s);
- ibox(s, indent_unit);
- word_space(s, ~"->");
- if decl.cf == ast::noreturn { word_nbsp(s, ~"!"); }
- else { print_type(s, decl.output); }
- end(s);
+
+ match decl.output.node {
+ ast::ty_nil => {}
+ _ => {
+ space_if_not_bol(s);
+ ibox(s, indent_unit);
+ word_space(s, ~"->");
+ if decl.cf == ast::noreturn { word_nbsp(s, ~"!"); }
+ else { print_type(s, decl.output); }
+ end(s);
+ }
}
+
end(s);
}
View
7 src/rustc/middle/borrowck/check_loans.rs
@@ -79,6 +79,13 @@ enum assignment_type {
at_mutbl_ref,
}
+impl assignment_type : cmp::Eq {
+ pure fn eq(&&other: assignment_type) -> bool {
+ (self as uint) == (other as uint)
+ }
+ pure fn ne(&&other: assignment_type) -> bool { !self.eq(other) }
+}
+
impl assignment_type {
fn checked_by_liveness() -> bool {
// the liveness pass guarantees that immutable local variables
View
22 src/rustc/middle/resolve.rs
@@ -210,6 +210,15 @@ enum ResolveResult<T> {
Success(T) // Successfully resolved the import.
}
+impl<T> ResolveResult<T> {
+ fn failed() -> bool {
+ match self { Failed => true, _ => false }
+ }
+ fn indeterminate() -> bool {
+ match self { Indeterminate => true, _ => false }
+ }
+}
+
enum TypeParameters/& {
NoTypeParameters, //< No type parameters.
HasTypeParameters(&~[ty_param], //< Type parameters.
@@ -558,9 +567,14 @@ struct NameBindings {
fn defined_in_namespace(namespace: Namespace) -> bool {
match namespace {
- ModuleNS => return self.module_def != NoModuleDef,
- TypeNS => return self.type_def != None,
- ValueNS => return self.value_def != None
+ ModuleNS => {
+ match self.module_def {
+ NoModuleDef => false,
+ _ => true
+ }
+ }
+ TypeNS => return self.type_def.is_some(),
+ ValueNS => return self.value_def.is_some()
}
}
@@ -1788,7 +1802,7 @@ struct Resolver {
// processing imports here. (See the loop in
// resolve_imports_for_module.)
- if resolution_result != Indeterminate {
+ if !resolution_result.indeterminate() {
match *import_directive.subclass {
GlobImport => {
assert module_.glob_count >= 1u;
View
19 src/rustc/middle/trans/expr.rs
@@ -1117,12 +1117,21 @@ fn trans_eager_binop(bcx: block,
AShr(bcx, lhs, rhs)
} else { LShr(bcx, lhs, rhs) }
}
+ ast::eq | ast::ne | ast::lt | ast::ge | ast::le | ast::gt => {
+ if ty::type_is_bot(rhs_t) {
+ C_bool(false)
+ } else {
+ if !ty::type_is_scalar(rhs_t) {
+ bcx.tcx().sess.span_bug(binop_expr.span,
+ ~"non-scalar comparison");
+ }
+ let cmpr = base::compare_scalar_types(bcx, lhs, rhs, rhs_t, op);
+ bcx = cmpr.bcx;
+ cmpr.val
+ }
+ }
_ => {
- let cmpr = base::trans_compare(bcx, op,
- lhs, lhs_t,
- rhs, rhs_t);
- bcx = cmpr.bcx;
- cmpr.val
+ bcx.tcx().sess.span_bug(binop_expr.span, ~"unexpected binop");
}
};
View
10 src/rustc/middle/trans/shape.rs
@@ -516,12 +516,14 @@ fn gen_enum_shapes(ccx: @crate_ctxt) -> ValueRef {
ranges[i].align.bounded &&
ranges[j].size.bounded &&
ranges[j].align.bounded {
- if ranges[i].size >= ranges[j].size &&
- ranges[i].align >= ranges[j].align {
+ if ranges[i].size.min >= ranges[j].size.min &&
+ ranges[i].align.min >= ranges[j].align.min {
// Throw out j.
candidates[j] = false;
- } else if ranges[j].size >= ranges[i].size &&
- ranges[j].align >= ranges[j].align {
+ } else if ranges[j].size.min >=
+ ranges[i].size.min &&
+ ranges[j].align.min >=
+ ranges[j].align.min {
// Throw out i.
candidates[i] = false;
}
View
4 src/rustc/middle/ty.rs
@@ -3081,8 +3081,8 @@ fn occurs_check(tcx: ctxt, sp: span, vid: TyVid, rt: t) {
// Maintains a little union-set tree for inferred modes. `canon()` returns
// the current head value for `m0`.
-fn canon<T:Copy>(tbl: hashmap<ast::node_id, ast::inferable<T>>,
- +m0: ast::inferable<T>) -> ast::inferable<T> {
+fn canon<T:Copy cmp::Eq>(tbl: hashmap<ast::node_id, ast::inferable<T>>,
+ +m0: ast::inferable<T>) -> ast::inferable<T> {
match m0 {
ast::infer(id) => match tbl.find(id) {
None => m0,
View
27 src/rustc/middle/typeck/check.rs
@@ -1132,7 +1132,13 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
let rhs_bot = check_expr_with(fcx, rhs, tvar);
let result_t = match op {
ast::eq | ast::lt | ast::le | ast::ne | ast::ge |
- ast::gt => ty::mk_bool(fcx.ccx.tcx),
+ ast::gt => {
+ if !ty::type_is_scalar(lhs_t) {
+ fcx.ccx.tcx.sess.span_bug(expr.span,
+ ~"non-scalar compare");
+ }
+ ty::mk_bool(fcx.ccx.tcx)
+ }
_ => lhs_t
};
fcx.write_ty(expr.id, result_t);
@@ -1410,23 +1416,6 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
let typ = check_lit(fcx, lit);
fcx.write_ty(id, typ);
}
-
- // Something of a hack: special rules for comparison operators that
- // simply unify LHS and RHS. This helps with inference as LHS and RHS
- // do not need to be "resolvable". Some tests, particularly those with
- // complicated trait requirements, fail without this---I think this code
- // can be removed if we improve trait resolution to be more eager when
- // possible.
- ast::expr_binary(ast::ne, lhs, rhs) |
- ast::expr_binary(ast::le, lhs, rhs) |
- ast::expr_binary(ast::gt, lhs, rhs) |
- ast::expr_binary(ast::ge, lhs, rhs) => {
- let tcx = fcx.ccx.tcx;
- let tvar = fcx.infcx().next_ty_var();
- bot |= check_expr_with(fcx, lhs, tvar);
- bot |= check_expr_with(fcx, rhs, tvar);
- fcx.write_ty(id, ty::mk_bool(tcx));
- }
ast::expr_binary(op, lhs, rhs) => {
bot |= check_binop(fcx, expr, op, lhs, rhs);
}
@@ -1806,7 +1795,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
}
ast::expr_rec(fields, base) => {
option::iter(base, |b| { check_expr(fcx, b, expected); });
- let expected = if expected == None && base != None {
+ let expected = if expected.is_none() && base.is_some() {
Some(fcx.expr_ty(base.get()))
} else { expected };
let flds = unpack_expected(fcx, expected, |sty|
View
4 src/rustc/middle/typeck/infer/unify.rs
@@ -20,7 +20,7 @@ struct node<V:Copy, T:Copy> {
}
impl infer_ctxt {
- fn get<V:Copy vid, T:Copy>(
+ fn get<V:Copy vid Eq, T:Copy>(
vb: &vals_and_bindings<V, T>, vid: V) -> node<V, T> {
let vid_u = vid.to_uint();
@@ -377,4 +377,4 @@ impl infer_ctxt {
}
-}
+}
View
10 src/test/bench/shootout-k-nucleotide.rs
@@ -14,22 +14,22 @@ fn sort_and_fmt(mm: hashmap<~[u8], uint>, total: uint) -> ~str {
return (xx as float) * 100f / (yy as float);
}
- pure fn le_by_val<TT: Copy, UU: Copy>(kv0: &(TT,UU),
- kv1: &(TT,UU)) -> bool {
+ pure fn le_by_val<TT: Copy Ord, UU: Copy Ord>(kv0: &(TT,UU),
+ kv1: &(TT,UU)) -> bool {
let (_, v0) = *kv0;
let (_, v1) = *kv1;
return v0 >= v1;
}
- pure fn le_by_key<TT: Copy, UU: Copy>(kv0: &(TT,UU),
- kv1: &(TT,UU)) -> bool {
+ pure fn le_by_key<TT: Copy Ord, UU: Copy Ord>(kv0: &(TT,UU),
+ kv1: &(TT,UU)) -> bool {
let (k0, _) = *kv0;
let (k1, _) = *kv1;
return k0 <= k1;
}
// sort by key, then by value
- fn sortKV<TT: Copy, UU: Copy>(orig: ~[(TT,UU)]) -> ~[(TT,UU)] {
+ fn sortKV<TT: Copy Ord, UU: Copy Ord>(orig: ~[(TT,UU)]) -> ~[(TT,UU)] {
return sort::merge_sort(le_by_val, sort::merge_sort(le_by_key, orig));
}
View
2  src/test/run-pass/pipe-select.rs
@@ -46,7 +46,7 @@ fn main() {
error!("selecting");
let (i, m, _) = select(~[left, right]);
error!("selected %?", i);
- if m != None {
+ if m.is_some() {
assert i == 1;
}
});
View
5 src/test/run-pass/structured-compare-recursive.rs
@@ -1,5 +0,0 @@
-
-
-enum taggy { foo(@taggy), bar, }
-
-fn main() { assert (bar <= bar); }
View
20 src/test/run-pass/tag.rs
@@ -4,6 +4,26 @@
// -*- rust -*-
enum colour { red(int, int), green, }
+impl colour : cmp::Eq {
+ pure fn eq(&&other: colour) -> bool {
+ match self {
+ red(a0, b0) => {
+ match other {
+ red(a1, b1) => a0 == a1 && b0 == b1,
+ green => false,
+ }
+ }
+ green => {
+ match other {
+ red(*) => false,
+ green => true
+ }
+ }
+ }
+ }
+ pure fn ne(&&other: colour) -> bool { !self.eq(other) }
+}
+
fn f() { let x = red(1, 2); let y = green; assert (x != y); }
fn main() { f(); }
View
20 src/test/run-pass/while-prelude-drop.rs
@@ -1,6 +1,26 @@
enum t { a, b(~str), }
+impl t : cmp::Eq {
+ pure fn eq(&&other: t) -> bool {
+ match self {
+ a => {
+ match other {
+ a => true,
+ b(_) => false
+ }
+ }
+ b(s0) => {
+ match other {
+ a => false,
+ b(s1) => s0 == s1
+ }
+ }
+ }
+ }
+ pure fn ne(&&other: t) -> bool { !self.eq(other) }
+}
+
fn make(i: int) -> t {
if i > 10 { return a; }
let mut s = ~"hello";
Please sign in to comment.
Something went wrong with that request. Please try again.