about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-09-07 18:53:14 -0700
committerPatrick Walton <pcwalton@mimiga.net>2012-09-10 12:48:42 -0700
commit22b875770543ec1fe93cfb35fd07c692db5675e2 (patch)
tree62004747db05cf0fb7d82b85133210c67e2c7bb3 /src
parent9a15c50f6c3cec5320ef91f000142af0367890a4 (diff)
downloadrust-22b875770543ec1fe93cfb35fd07c692db5675e2.tar.gz
rust-22b875770543ec1fe93cfb35fd07c692db5675e2.zip
rustc: Make shape-based compare glue never called for comparison operators.
Only called for string patterns.
Diffstat (limited to 'src')
-rw-r--r--src/libcore/iter.rs2
-rw-r--r--src/libcore/str.rs17
-rw-r--r--src/libcore/task.rs40
-rw-r--r--src/libstd/json.rs79
-rw-r--r--src/libsyntax/ast.rs51
-rw-r--r--src/libsyntax/attr.rs7
-rw-r--r--src/libsyntax/ext/pipes/proto.rs2
-rw-r--r--src/libsyntax/ext/simplext.rs4
-rw-r--r--src/libsyntax/parse/comments.rs9
-rw-r--r--src/libsyntax/print/pprust.rs43
-rw-r--r--src/rustc/middle/borrowck/check_loans.rs7
-rw-r--r--src/rustc/middle/resolve.rs22
-rw-r--r--src/rustc/middle/trans/expr.rs19
-rw-r--r--src/rustc/middle/trans/shape.rs10
-rw-r--r--src/rustc/middle/ty.rs4
-rw-r--r--src/rustc/middle/typeck/check.rs27
-rw-r--r--src/rustc/middle/typeck/infer/unify.rs4
-rw-r--r--src/test/bench/shootout-k-nucleotide.rs10
-rw-r--r--src/test/run-pass/pipe-select.rs2
-rw-r--r--src/test/run-pass/structured-compare-recursive.rs5
-rw-r--r--src/test/run-pass/tag.rs20
-rw-r--r--src/test/run-pass/while-prelude-drop.rs20
22 files changed, 322 insertions, 82 deletions
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index e9d6784136f..1e05965925c 100644
--- a/src/libcore/iter.rs
+++ b/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 => {
diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index ca96090ebd4..66ef6e001b7 100644
--- a/src/libcore/str.rs
+++ b/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 {
diff --git a/src/libcore/task.rs b/src/libcore/task.rs
index bee810fceba..ced39ef067b 100644
--- a/src/libcore/task.rs
+++ b/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
  *
diff --git a/src/libstd/json.rs b/src/libstd/json.rs
index 1adb41e8d10..de6f2ea3e90 100644
--- a/src/libstd/json.rs
+++ b/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 {
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index e2cfdd119b6..364576aae33 100644
--- a/src/libsyntax/ast.rs
+++ b/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
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index 9dc610e2fb6..a12233765ca 100644
--- a/src/libsyntax/attr.rs
+++ b/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)]
diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs
index 4065c8cf2ba..cb470aee7f3 100644
--- a/src/libsyntax/ext/pipes/proto.rs
+++ b/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 {
diff --git a/src/libsyntax/ext/simplext.rs b/src/libsyntax/ext/simplext.rs
index bb5af8402df..c6ddc449b20 100644
--- a/src/libsyntax/ext/simplext.rs
+++ b/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);
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs
index b85262cb79d..7fcf7a032dc 100644
--- a/src/libsyntax/parse/comments.rs
+++ b/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 {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 942963797cb..46faa67114e 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/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);
 }
 
diff --git a/src/rustc/middle/borrowck/check_loans.rs b/src/rustc/middle/borrowck/check_loans.rs
index c45e6d03546..2d4f988c007 100644
--- a/src/rustc/middle/borrowck/check_loans.rs
+++ b/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
diff --git a/src/rustc/middle/resolve.rs b/src/rustc/middle/resolve.rs
index 94786aa8a89..b85b10e50e8 100644
--- a/src/rustc/middle/resolve.rs
+++ b/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;
diff --git a/src/rustc/middle/trans/expr.rs b/src/rustc/middle/trans/expr.rs
index b1ee870dbb5..0fe4f3cd917 100644
--- a/src/rustc/middle/trans/expr.rs
+++ b/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");
       }
     };
 
diff --git a/src/rustc/middle/trans/shape.rs b/src/rustc/middle/trans/shape.rs
index d65b0e1978c..cdbaf6e5ee2 100644
--- a/src/rustc/middle/trans/shape.rs
+++ b/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;
                             }
diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs
index e6476b57e70..b8d610e7a15 100644
--- a/src/rustc/middle/ty.rs
+++ b/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,
diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs
index f63f6f2e125..677a7a444f0 100644
--- a/src/rustc/middle/typeck/check.rs
+++ b/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|
diff --git a/src/rustc/middle/typeck/infer/unify.rs b/src/rustc/middle/typeck/infer/unify.rs
index 2793d0e4f5a..500a4d5b419 100644
--- a/src/rustc/middle/typeck/infer/unify.rs
+++ b/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 {
     }
 
 
-}
\ No newline at end of file
+}
diff --git a/src/test/bench/shootout-k-nucleotide.rs b/src/test/bench/shootout-k-nucleotide.rs
index 5f907e55a1f..c1d9a10a106 100644
--- a/src/test/bench/shootout-k-nucleotide.rs
+++ b/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));
    }
 
diff --git a/src/test/run-pass/pipe-select.rs b/src/test/run-pass/pipe-select.rs
index 783febf942c..29504d477a1 100644
--- a/src/test/run-pass/pipe-select.rs
+++ b/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;
         }
     });
diff --git a/src/test/run-pass/structured-compare-recursive.rs b/src/test/run-pass/structured-compare-recursive.rs
deleted file mode 100644
index 269cbf0363b..00000000000
--- a/src/test/run-pass/structured-compare-recursive.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-enum taggy { foo(@taggy), bar, }
-
-fn main() { assert (bar <= bar); }
diff --git a/src/test/run-pass/tag.rs b/src/test/run-pass/tag.rs
index 1793f5f22a2..6d6e2ad09d0 100644
--- a/src/test/run-pass/tag.rs
+++ b/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(); }
diff --git a/src/test/run-pass/while-prelude-drop.rs b/src/test/run-pass/while-prelude-drop.rs
index 6315a92ca2d..9400840dd8e 100644
--- a/src/test/run-pass/while-prelude-drop.rs
+++ b/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";