diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index 34d002d334277..5114cab3f41bb 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -828,93 +828,112 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
             }
             _ => ty_hint
         };
-        match (try!(eval_const_expr_partial(tcx, &**a, ty_hint, fn_args)),
-               try!(eval_const_expr_partial(tcx, &**b, b_ty, fn_args))) {
-          (Float(a), Float(b)) => {
-            match op.node {
-              hir::BiAdd => Float(a + b),
-              hir::BiSub => Float(a - b),
-              hir::BiMul => Float(a * b),
-              hir::BiDiv => Float(a / b),
-              hir::BiRem => Float(a % b),
-              hir::BiEq => fromb(a == b),
-              hir::BiLt => fromb(a < b),
-              hir::BiLe => fromb(a <= b),
-              hir::BiNe => fromb(a != b),
-              hir::BiGe => fromb(a >= b),
-              hir::BiGt => fromb(a > b),
-              _ => signal!(e, InvalidOpForFloats(op.node))
-            }
-          }
-          (Int(a), Int(b)) => {
-            match op.node {
-              hir::BiAdd => try!(const_int_checked_add(a,b,e,expr_int_type)),
-              hir::BiSub => try!(const_int_checked_sub(a,b,e,expr_int_type)),
-              hir::BiMul => try!(const_int_checked_mul(a,b,e,expr_int_type)),
-              hir::BiDiv => try!(const_int_checked_div(a,b,e,expr_int_type)),
-              hir::BiRem => try!(const_int_checked_rem(a,b,e,expr_int_type)),
-              hir::BiAnd | hir::BiBitAnd => Int(a & b),
-              hir::BiOr | hir::BiBitOr => Int(a | b),
-              hir::BiBitXor => Int(a ^ b),
-              hir::BiShl => try!(const_int_checked_shl(a,b,e,expr_int_type)),
-              hir::BiShr => try!(const_int_checked_shr(a,b,e,expr_int_type)),
-              hir::BiEq => fromb(a == b),
-              hir::BiLt => fromb(a < b),
-              hir::BiLe => fromb(a <= b),
-              hir::BiNe => fromb(a != b),
-              hir::BiGe => fromb(a >= b),
-              hir::BiGt => fromb(a > b)
-            }
-          }
-          (Uint(a), Uint(b)) => {
-            match op.node {
-              hir::BiAdd => try!(const_uint_checked_add(a,b,e,expr_uint_type)),
-              hir::BiSub => try!(const_uint_checked_sub(a,b,e,expr_uint_type)),
-              hir::BiMul => try!(const_uint_checked_mul(a,b,e,expr_uint_type)),
-              hir::BiDiv => try!(const_uint_checked_div(a,b,e,expr_uint_type)),
-              hir::BiRem => try!(const_uint_checked_rem(a,b,e,expr_uint_type)),
-              hir::BiAnd | hir::BiBitAnd => Uint(a & b),
-              hir::BiOr | hir::BiBitOr => Uint(a | b),
-              hir::BiBitXor => Uint(a ^ b),
-              hir::BiShl => try!(const_uint_checked_shl(a,b,e,expr_uint_type)),
-              hir::BiShr => try!(const_uint_checked_shr(a,b,e,expr_uint_type)),
-              hir::BiEq => fromb(a == b),
-              hir::BiLt => fromb(a < b),
-              hir::BiLe => fromb(a <= b),
-              hir::BiNe => fromb(a != b),
-              hir::BiGe => fromb(a >= b),
-              hir::BiGt => fromb(a > b),
+        match try!(eval_const_expr_partial(tcx, &**a, ty_hint, fn_args)) {
+          Bool(a) if op.node == hir::BiAnd => {
+            if !a {
+              Bool(a)
+            } else if let Bool(b) = try!(eval_const_expr_partial(tcx, &**b, b_ty, fn_args)) {
+              Bool(b)
+            } else {
+              signal!(e, MiscBinaryOp)
             }
           }
-          // shifts can have any integral type as their rhs
-          (Int(a), Uint(b)) => {
-            match op.node {
-              hir::BiShl => try!(const_int_checked_shl_via_uint(a,b,e,expr_int_type)),
-              hir::BiShr => try!(const_int_checked_shr_via_uint(a,b,e,expr_int_type)),
-              _ => signal!(e, InvalidOpForIntUint(op.node)),
+          Bool(a) if op.node == hir::BiOr => {
+            if a {
+              Bool(a)
+            } else if let Bool(b) = try!(eval_const_expr_partial(tcx, &**b, b_ty, fn_args)) {
+              Bool(b)
+            } else {
+              signal!(e, MiscBinaryOp)
             }
           }
-          (Uint(a), Int(b)) => {
-            match op.node {
-              hir::BiShl => try!(const_uint_checked_shl_via_int(a,b,e,expr_uint_type)),
-              hir::BiShr => try!(const_uint_checked_shr_via_int(a,b,e,expr_uint_type)),
-              _ => signal!(e, InvalidOpForUintInt(op.node)),
+          x => {
+            match (x, try!(eval_const_expr_partial(tcx, &**b, b_ty, fn_args))) {
+              (Float(a), Float(b)) => {
+                match op.node {
+                  hir::BiAdd => Float(a + b),
+                  hir::BiSub => Float(a - b),
+                  hir::BiMul => Float(a * b),
+                  hir::BiDiv => Float(a / b),
+                  hir::BiRem => Float(a % b),
+                  hir::BiEq => fromb(a == b),
+                  hir::BiLt => fromb(a < b),
+                  hir::BiLe => fromb(a <= b),
+                  hir::BiNe => fromb(a != b),
+                  hir::BiGe => fromb(a >= b),
+                  hir::BiGt => fromb(a > b),
+                  _ => signal!(e, InvalidOpForFloats(op.node))
+                }
+              }
+              (Int(a), Int(b)) => {
+                match op.node {
+                  hir::BiAdd => try!(const_int_checked_add(a,b,e,expr_int_type)),
+                  hir::BiSub => try!(const_int_checked_sub(a,b,e,expr_int_type)),
+                  hir::BiMul => try!(const_int_checked_mul(a,b,e,expr_int_type)),
+                  hir::BiDiv => try!(const_int_checked_div(a,b,e,expr_int_type)),
+                  hir::BiRem => try!(const_int_checked_rem(a,b,e,expr_int_type)),
+                  hir::BiAnd | hir::BiBitAnd => Int(a & b),
+                  hir::BiOr | hir::BiBitOr => Int(a | b),
+                  hir::BiBitXor => Int(a ^ b),
+                  hir::BiShl => try!(const_int_checked_shl(a,b,e,expr_int_type)),
+                  hir::BiShr => try!(const_int_checked_shr(a,b,e,expr_int_type)),
+                  hir::BiEq => fromb(a == b),
+                  hir::BiLt => fromb(a < b),
+                  hir::BiLe => fromb(a <= b),
+                  hir::BiNe => fromb(a != b),
+                  hir::BiGe => fromb(a >= b),
+                  hir::BiGt => fromb(a > b)
+                }
+              }
+              (Uint(a), Uint(b)) => {
+                match op.node {
+                  hir::BiAdd => try!(const_uint_checked_add(a,b,e,expr_uint_type)),
+                  hir::BiSub => try!(const_uint_checked_sub(a,b,e,expr_uint_type)),
+                  hir::BiMul => try!(const_uint_checked_mul(a,b,e,expr_uint_type)),
+                  hir::BiDiv => try!(const_uint_checked_div(a,b,e,expr_uint_type)),
+                  hir::BiRem => try!(const_uint_checked_rem(a,b,e,expr_uint_type)),
+                  hir::BiAnd | hir::BiBitAnd => Uint(a & b),
+                  hir::BiOr | hir::BiBitOr => Uint(a | b),
+                  hir::BiBitXor => Uint(a ^ b),
+                  hir::BiShl => try!(const_uint_checked_shl(a,b,e,expr_uint_type)),
+                  hir::BiShr => try!(const_uint_checked_shr(a,b,e,expr_uint_type)),
+                  hir::BiEq => fromb(a == b),
+                  hir::BiLt => fromb(a < b),
+                  hir::BiLe => fromb(a <= b),
+                  hir::BiNe => fromb(a != b),
+                  hir::BiGe => fromb(a >= b),
+                  hir::BiGt => fromb(a > b),
+                }
+              }
+              // shifts can have any integral type as their rhs
+              (Int(a), Uint(b)) => {
+                match op.node {
+                  hir::BiShl => try!(const_int_checked_shl_via_uint(a,b,e,expr_int_type)),
+                  hir::BiShr => try!(const_int_checked_shr_via_uint(a,b,e,expr_int_type)),
+                  _ => signal!(e, InvalidOpForIntUint(op.node)),
+                }
+              }
+              (Uint(a), Int(b)) => {
+                match op.node {
+                  hir::BiShl => try!(const_uint_checked_shl_via_int(a,b,e,expr_uint_type)),
+                  hir::BiShr => try!(const_uint_checked_shr_via_int(a,b,e,expr_uint_type)),
+                  _ => signal!(e, InvalidOpForUintInt(op.node)),
+                }
+              }
+              (Bool(a), Bool(b)) => {
+                Bool(match op.node {
+                  hir::BiBitXor => a ^ b,
+                  hir::BiBitAnd => a & b,
+                  hir::BiBitOr => a | b,
+                  hir::BiEq => a == b,
+                  hir::BiNe => a != b,
+                  _ => signal!(e, InvalidOpForBools(op.node)),
+                 })
+              }
+
+              _ => signal!(e, MiscBinaryOp),
             }
           }
-          (Bool(a), Bool(b)) => {
-            Bool(match op.node {
-              hir::BiAnd => a && b,
-              hir::BiOr => a || b,
-              hir::BiBitXor => a ^ b,
-              hir::BiBitAnd => a & b,
-              hir::BiBitOr => a | b,
-              hir::BiEq => a == b,
-              hir::BiNe => a != b,
-              _ => signal!(e, InvalidOpForBools(op.node)),
-             })
-          }
-
-          _ => signal!(e, MiscBinaryOp),
         }
       }
       hir::ExprCast(ref base, ref target_ty) => {
diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs
index 91f17a50e2c41..07057a35fbbfe 100644
--- a/src/librustc_trans/trans/consts.rs
+++ b/src/librustc_trans/trans/consts.rs
@@ -591,6 +591,21 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             let is_float = ty.is_fp();
             let signed = ty.is_signed();
 
+            if ty.is_bool() && (b.node == hir::BiOr || b.node == hir::BiAnd) {
+              match eval_const_expr_partial(cx.tcx(),
+                                            &e1,
+                                            ExprTypeChecked,
+                                            None) {
+                Ok(ConstVal::Bool(false)) if b.node == hir::BiAnd => {
+                  return Ok(te1)
+                }
+                Ok(ConstVal::Bool(true)) if b.node == hir::BiOr => {
+                  return Ok(te1)
+                }
+                _ => ()
+              }
+            }
+
             let (te2, _) = try!(const_expr(cx, &**e2, param_substs, fn_args, trueconst));
 
             try!(check_binary_expr_validity(cx, e, ty, te1, te2, trueconst));
diff --git a/src/test/run-pass/issue-29608.rs b/src/test/run-pass/issue-29608.rs
new file mode 100644
index 0000000000000..9f895ce2b2ee7
--- /dev/null
+++ b/src/test/run-pass/issue-29608.rs
@@ -0,0 +1,17 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Testcase provided by oli-obk
+
+const X: bool = false && ((1u8 - 5u8) == 42);
+
+fn main() {
+println!("{}", X);
+}