]> git.lizzy.rs Git - rust.git/commitdiff
Make _|_ type binopable
authorTim Chevalier <chevalier@alum.wellesley.edu>
Wed, 3 Aug 2011 01:04:24 +0000 (18:04 -0700)
committerTim Chevalier <chevalier@alum.wellesley.edu>
Wed, 3 Aug 2011 01:06:46 +0000 (18:06 -0700)
But don't actually generate code that does the operation. That means
hoisting the check I added in my last commit from trans_compare
up into trans_eager_binop (don't generate any code if one operand
has type _|_ ).

Closes #777

src/comp/middle/trans.rs
src/comp/middle/ty.rs
src/test/run-pass/early-ret-binop-add.rs [new file with mode: 0644]

index 3a25b84e8d209613892911b5b2186f7edafd9435..98ca83a6ff6d18fef643bd447a0e04b26e0bec0c 100644 (file)
@@ -2702,8 +2702,6 @@ fn trans_unary(cx: &@block_ctxt, op: ast::unop, e: &@ast::expr,
     }
 }
 
-// Important to get types for both lhs and rhs, because one might be _|_
-// and the other not.
 fn trans_compare(cx0: &@block_ctxt, op: ast::binop,
                  lhs0: ValueRef, lhs_t: ty::t, rhs0: ValueRef,
                 rhs_t: ty::t) -> result {
@@ -2725,22 +2723,14 @@ fn trans_compare(cx0: &@block_ctxt, op: ast::binop,
       ast::le. | ast::gt. { llop = C_u8(abi::cmp_glue_op_le); }
     }
 
-    if (! ty::type_is_bot(bcx_tcx(cx0), rhs_r.ty) &&
-        ! ty::type_is_bot(bcx_tcx(cx0), lhs_r.ty)) {
-        let rs = compare(cx, lhs, rhs, rhs_r.ty, llop);
+    let rs = compare(cx, lhs, rhs, rhs_r.ty, llop);
 
-        // Invert the result if necessary.
-        alt op {
-          ast::eq. | ast::lt. | ast::le. { ret rslt(rs.bcx, rs.val); }
-          ast::ne. | ast::ge. | ast::gt. {
-            ret rslt(rs.bcx, rs.bcx.build.Not(rs.val));
-          }
-        }
-    }
-    else {
-        // If either is bottom, it diverges. So no need to do the
-        // actual comparison.
-        ret rslt(cx, cx.build.Unreachable());
+    // Invert the result if necessary.
+    alt op {
+      ast::eq. | ast::lt. | ast::le. { ret rslt(rs.bcx, rs.val); }
+      ast::ne. | ast::ge. | ast::gt. {
+        ret rslt(rs.bcx, rs.bcx.build.Not(rs.val));
+      }
     }
 }
 
@@ -3387,6 +3377,14 @@ fn trans_vec_add(cx: &@block_ctxt, t: &ty::t, lhs: ValueRef, rhs: ValueRef) ->
 // and the other not.
 fn trans_eager_binop(cx: &@block_ctxt, op: ast::binop, lhs: ValueRef,
                      lhs_t: ty::t, rhs: ValueRef, rhs_t: ty::t) -> result {
+
+    // If either is bottom, it diverges. So no need to do the
+    // operation.
+    if (ty::type_is_bot(bcx_tcx(cx), lhs_t) ||
+        ty::type_is_bot(bcx_tcx(cx), rhs_t)) {
+        ret rslt(cx, cx.build.Unreachable());
+    }
+
     let is_float = false;
     let intype = lhs_t;
     if ty::type_is_bot(bcx_tcx(cx), intype) {
index 3538f35cda9cd06c338cf864527ea65e9ca393a5..1c14a0be2c09f40c35cec03b543d938ef2f26814 100644 (file)
@@ -2880,6 +2880,7 @@ fn is_binopable(cx: &ctxt, ty: t, op: ast::binop) -> bool {
     const tycat_str: int = 4;
     const tycat_vec: int = 5;
     const tycat_struct: int = 6;
+    const tycat_bot: int = 7;
 
     const opcat_add: int = 0;
     const opcat_sub: int = 1;
@@ -2938,6 +2939,7 @@ fn tycat(cx: &ctxt, ty: t) -> int {
           ty_ivec(_) { tycat_vec }
           ty_rec(_) { tycat_struct }
           ty_tag(_, _) { tycat_struct }
+          ty_bot.    { tycat_bot }
           _ { tycat_other }
         }
     }
@@ -2954,11 +2956,13 @@ fn tycat(cx: &ctxt, ty: t) -> int {
          /*float*/
          /*str*/
          /*vec*/
+         /*bot*/
         tbl =
         [[f, f, f, f, t, t, f, f], [f, f, f, f, t, t, t, t],
          [t, t, t, t, t, t, t, f], [t, t, t, f, t, t, f, f],
          [t, f, f, f, t, t, f, f], [t, f, f, f, t, t, f, f],
-         [f, f, f, f, t, t, f, f]]; /*struct*/
+         [f, f, f, f, t, t, f, f],
+         [t, t, t, t, t, t, t, t]]; /*struct*/
 
     ret tbl.(tycat(cx, ty)).(opcat(op));
 }
diff --git a/src/test/run-pass/early-ret-binop-add.rs b/src/test/run-pass/early-ret-binop-add.rs
new file mode 100644 (file)
index 0000000..dc847b3
--- /dev/null
@@ -0,0 +1,4 @@
+fn wsucc(n: int) -> int {
+    { ret n + 1 } + 0;
+}
+fn main() {}