Skip to content

Commit 4618e80

Browse files
msullivanbrson
authored andcommitted
Fix comparisons of the nil type to do something sensible.
Closes #576.
1 parent 7fc7ebd commit 4618e80

File tree

2 files changed

+22
-26
lines changed

2 files changed

+22
-26
lines changed

src/comp/middle/trans.rs

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2362,9 +2362,8 @@ fn make_cmp_glue(&@block_ctxt cx, ValueRef lhs0, ValueRef rhs0, &ty::t t,
23622362
rhs_fill = vec_fill(scx, rhs);
23632363
bcx = scx;
23642364
}
2365-
r =
2366-
compare_numerical_values(bcx, lhs_fill, rhs_fill,
2367-
unsigned_int, llop);
2365+
r = compare_scalar_values(bcx, lhs_fill, rhs_fill,
2366+
unsigned_int, llop);
23682367
r.bcx.build.Store(r.val, flag);
23692368
} else {
23702369
// == and <= default to true if they find == all the way. <
@@ -2441,18 +2440,18 @@ fn make_cmp_glue(&@block_ctxt cx, ValueRef lhs0, ValueRef rhs0, &ty::t t,
24412440

24422441

24432442
// Used only for creating scalar comparsion glue.
2444-
tag numerical_type { signed_int; unsigned_int; floating_point; }
2443+
tag scalar_type { nil_type; signed_int; unsigned_int; floating_point; }
24452444

24462445

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

2452-
auto f = bind compare_numerical_values(cx, lhs, rhs, _, llop);
2451+
auto f = bind compare_scalar_values(cx, lhs, rhs, _, llop);
24532452

24542453
alt (ty::struct(cx.fcx.lcx.ccx.tcx, t)) {
2455-
case (ty::ty_nil) { ret rslt(cx, C_bool(true)); }
2454+
case (ty::ty_nil) { ret f(nil_type); }
24562455
case (ty::ty_bool) { ret f(unsigned_int); }
24572456
case (ty::ty_int) { ret f(signed_int); }
24582457
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,
25142513
}
25152514

25162515

2517-
// A helper function to compare numerical values.
2518-
fn compare_numerical_values(&@block_ctxt cx, ValueRef lhs, ValueRef rhs,
2519-
numerical_type nt, ValueRef llop) -> result {
2516+
// A helper function to do the actual comparison of scalar values.
2517+
fn compare_scalar_values(&@block_ctxt cx, ValueRef lhs, ValueRef rhs,
2518+
scalar_type nt, ValueRef llop) -> result {
25202519
auto eq_cmp;
25212520
auto lt_cmp;
25222521
auto le_cmp;
25232522
alt (nt) {
2523+
case (nil_type) {
2524+
// We don't need to do actual comparisons for nil.
2525+
// () == () holds but () < () does not.
2526+
eq_cmp = 1u;
2527+
lt_cmp = 0u;
2528+
le_cmp = 1u;
2529+
}
25242530
case (floating_point) {
25252531
eq_cmp = lib::llvm::LLVMRealUEQ;
25262532
lt_cmp = lib::llvm::LLVMRealULT;
@@ -2543,10 +2549,12 @@ fn compare_numerical_values(&@block_ctxt cx, ValueRef lhs, ValueRef rhs,
25432549
// the above, and "auto eq_result = cmp_fn(eq_cmp, lhs, rhs);" in the
25442550
// below.
25452551

2546-
fn generic_cmp(&@block_ctxt cx, numerical_type nt, uint op, ValueRef lhs,
2552+
fn generic_cmp(&@block_ctxt cx, scalar_type nt, uint op, ValueRef lhs,
25472553
ValueRef rhs) -> ValueRef {
25482554
let ValueRef r;
2549-
if (nt == floating_point) {
2555+
if (nt == nil_type) {
2556+
r = C_bool(op != 0u);
2557+
} else if (nt == floating_point) {
25502558
r = cx.build.FCmp(op, lhs, rhs);
25512559
} else { r = cx.build.ICmp(op, lhs, rhs); }
25522560
ret r;
@@ -2573,16 +2581,6 @@ fn compare_numerical_values(&@block_ctxt cx, ValueRef lhs, ValueRef rhs,
25732581
ret rslt(last_cx, last_result);
25742582
}
25752583

2576-
2577-
// A helper function to create numerical comparison glue.
2578-
fn make_numerical_cmp_glue(&@block_ctxt cx, ValueRef lhs, ValueRef rhs,
2579-
numerical_type nt, ValueRef llop) {
2580-
auto r = compare_numerical_values(cx, lhs, rhs, nt, llop);
2581-
r.bcx.build.Store(r.val, r.bcx.fcx.llretptr);
2582-
r.bcx.build.RetVoid();
2583-
}
2584-
2585-
25862584
type val_pair_fn = fn(&@block_ctxt, ValueRef, ValueRef) -> result ;
25872585

25882586
type val_and_ty_fn = fn(&@block_ctxt, ValueRef, ty::t) -> result ;

src/test/run-pass/binops.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@
33
fn test_nil() {
44
assert () == ();
55
assert !(() != ());
6-
// FIXME (#576): The current implementation of relational ops on nil
7-
// is nonsensical
8-
assert () < ();
6+
assert !(() < ());
97
assert () <= ();
108
assert !(() > ());
11-
assert !(() >= ());
9+
assert () >= ();
1210
}
1311

1412
fn test_bool() {
@@ -159,4 +157,4 @@ fn main() {
159157
test_fn();
160158
test_native_fn();
161159
test_obj();
162-
}
160+
}

0 commit comments

Comments
 (0)