diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 3a25b84e8d20..98ca83a6ff6d 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -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) { diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 3538f35cda9c..1c14a0be2c09 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -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 is_binopable(cx: &ctxt, ty: t, op: ast::binop) -> bool { ty_ivec(_) { tycat_vec } ty_rec(_) { tycat_struct } ty_tag(_, _) { tycat_struct } + ty_bot. { tycat_bot } _ { tycat_other } } } @@ -2954,11 +2956,13 @@ fn is_binopable(cx: &ctxt, ty: t, op: ast::binop) -> bool { /*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 index 000000000000..dc847b30fc2d --- /dev/null +++ b/src/test/run-pass/early-ret-binop-add.rs @@ -0,0 +1,4 @@ +fn wsucc(n: int) -> int { + { ret n + 1 } + 0; +} +fn main() {}