Fix comparisons of the nil type to do something sensible.

Closes #576.
This commit is contained in:
Michael Sullivan 2011-07-11 16:37:21 -05:00 committed by Brian Anderson
parent 7fc7ebd520
commit 4618e802db
2 changed files with 22 additions and 26 deletions

View File

@ -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. <
@ -2441,7 +2440,7 @@ 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,
@ -2449,10 +2448,10 @@ fn compare_scalar_types(@block_ctxt cx, ValueRef lhs, ValueRef rhs, &ty::t t,
// 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); }
@ -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;
@ -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;
@ -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 ;

View File

@ -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() {
@ -159,4 +157,4 @@ fn main() {
test_fn();
test_native_fn();
test_obj();
}
}