rustc: Make shape-based compare glue never called for comparison operators.
Only called for string patterns.
This commit is contained in:
parent
9a15c50f6c
commit
22b8757705
|
@ -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 => {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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|
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
|
||||
|
||||
enum taggy { foo(@taggy), bar, }
|
||||
|
||||
fn main() { assert (bar <= bar); }
|
|
@ -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(); }
|
||||
|
|
|
@ -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";
|
||||
|
|
Loading…
Reference in New Issue