Skip to content

Commit

Permalink
Fix comparisons of the nil type to do something sensible.
Browse files Browse the repository at this point in the history
  • Loading branch information
msullivan authored and brson committed Jul 11, 2011
1 parent 7fc7ebd commit 4618e80
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 26 deletions.
40 changes: 19 additions & 21 deletions src/comp/middle/trans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2362,9 +2362,8 @@ fn make_cmp_glue(&@block_ctxt cx, ValueRef lhs0, ValueRef rhs0, &ty::t t,
rhs_fill = vec_fill(scx, rhs);
bcx = scx;
}
r =
compare_numerical_values(bcx, lhs_fill, rhs_fill,
unsigned_int, llop);
r = compare_scalar_values(bcx, lhs_fill, rhs_fill,
unsigned_int, llop);
r.bcx.build.Store(r.val, flag);
} else {
// == and <= default to true if they find == all the way. <
Expand Down Expand Up @@ -2441,18 +2440,18 @@ fn make_cmp_glue(&@block_ctxt cx, ValueRef lhs0, ValueRef rhs0, &ty::t t,


// Used only for creating scalar comparsion glue.
tag numerical_type { signed_int; unsigned_int; floating_point; }
tag scalar_type { nil_type; signed_int; unsigned_int; floating_point; }


fn compare_scalar_types(@block_ctxt cx, ValueRef lhs, ValueRef rhs, &ty::t t,
ValueRef llop) -> result {
// FIXME: this could be a lot shorter if we could combine multiple cases
// of alt expressions (issue #449).

auto f = bind compare_numerical_values(cx, lhs, rhs, _, llop);
auto f = bind compare_scalar_values(cx, lhs, rhs, _, llop);

alt (ty::struct(cx.fcx.lcx.ccx.tcx, t)) {
case (ty::ty_nil) { ret rslt(cx, C_bool(true)); }
case (ty::ty_nil) { ret f(nil_type); }
case (ty::ty_bool) { ret f(unsigned_int); }
case (ty::ty_int) { ret f(signed_int); }
case (ty::ty_float) { ret f(floating_point); }
Expand Down Expand Up @@ -2514,13 +2513,20 @@ fn make_scalar_cmp_glue(&@block_ctxt cx, ValueRef lhs, ValueRef rhs, &ty::t t,
}


// A helper function to compare numerical values.
fn compare_numerical_values(&@block_ctxt cx, ValueRef lhs, ValueRef rhs,
numerical_type nt, ValueRef llop) -> result {
// A helper function to do the actual comparison of scalar values.
fn compare_scalar_values(&@block_ctxt cx, ValueRef lhs, ValueRef rhs,
scalar_type nt, ValueRef llop) -> result {
auto eq_cmp;
auto lt_cmp;
auto le_cmp;
alt (nt) {
case (nil_type) {
// We don't need to do actual comparisons for nil.
// () == () holds but () < () does not.
eq_cmp = 1u;
lt_cmp = 0u;
le_cmp = 1u;
}
case (floating_point) {
eq_cmp = lib::llvm::LLVMRealUEQ;
lt_cmp = lib::llvm::LLVMRealULT;
Expand All @@ -2543,10 +2549,12 @@ fn compare_numerical_values(&@block_ctxt cx, ValueRef lhs, ValueRef rhs,
// the above, and "auto eq_result = cmp_fn(eq_cmp, lhs, rhs);" in the
// below.

fn generic_cmp(&@block_ctxt cx, numerical_type nt, uint op, ValueRef lhs,
fn generic_cmp(&@block_ctxt cx, scalar_type nt, uint op, ValueRef lhs,
ValueRef rhs) -> ValueRef {
let ValueRef r;
if (nt == floating_point) {
if (nt == nil_type) {
r = C_bool(op != 0u);
} else if (nt == floating_point) {
r = cx.build.FCmp(op, lhs, rhs);
} else { r = cx.build.ICmp(op, lhs, rhs); }
ret r;
Expand All @@ -2573,16 +2581,6 @@ fn compare_numerical_values(&@block_ctxt cx, ValueRef lhs, ValueRef rhs,
ret rslt(last_cx, last_result);
}


// A helper function to create numerical comparison glue.
fn make_numerical_cmp_glue(&@block_ctxt cx, ValueRef lhs, ValueRef rhs,
numerical_type nt, ValueRef llop) {
auto r = compare_numerical_values(cx, lhs, rhs, nt, llop);
r.bcx.build.Store(r.val, r.bcx.fcx.llretptr);
r.bcx.build.RetVoid();
}


type val_pair_fn = fn(&@block_ctxt, ValueRef, ValueRef) -> result ;

type val_and_ty_fn = fn(&@block_ctxt, ValueRef, ty::t) -> result ;
Expand Down
8 changes: 3 additions & 5 deletions src/test/run-pass/binops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
fn test_nil() {
assert () == ();
assert !(() != ());
// FIXME (#576): The current implementation of relational ops on nil
// is nonsensical
assert () < ();
assert !(() < ());
assert () <= ();
assert !(() > ());
assert !(() >= ());
assert () >= ();
}

fn test_bool() {
Expand Down Expand Up @@ -159,4 +157,4 @@ fn main() {
test_fn();
test_native_fn();
test_obj();
}
}

0 comments on commit 4618e80

Please sign in to comment.