about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2013-11-30 00:26:21 -0800
committerAlex Crichton <alex@alexcrichton.com>2013-11-30 00:30:28 -0800
commit7bb166ef4f5d9629aba514dccaf4f3fb094a3cbb (patch)
tree57ebd745f07e96a69a23793daafc0467b59e6982 /src
parent80991bb578329ca921fdc910d9b6b064e8f521d2 (diff)
downloadrust-7bb166ef4f5d9629aba514dccaf4f3fb094a3cbb.tar.gz
rust-7bb166ef4f5d9629aba514dccaf4f3fb094a3cbb.zip
Don't run cleanups twice in "if true" blocks
Turns out `with_scope` already translates destructors, so by manually
translating destructors we end up running them all twice (bad).

Closes #10734
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/trans/controlflow.rs18
-rw-r--r--src/test/run-pass/issue-10734.rs20
2 files changed, 31 insertions, 7 deletions
diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs
index 952854e7d04..c62757e1353 100644
--- a/src/librustc/middle/trans/controlflow.rs
+++ b/src/librustc/middle/trans/controlflow.rs
@@ -77,7 +77,7 @@ pub fn trans_if(bcx: @mut Block,
             return with_scope(bcx, thn.info(), "if_true_then", |bcx| {
                 let bcx_out = trans_block(bcx, thn, dest);
                 debuginfo::clear_source_location(bcx.fcx);
-                trans_block_cleanups(bcx_out, block_cleanups(bcx))
+                bcx_out
             })
         } else {
             let mut trans = TransItemVisitor { ccx: bcx.fcx.ccx } ;
@@ -90,9 +90,9 @@ pub fn trans_if(bcx: @mut Block,
                                       elexpr.info(),
                                       "if_false_then",
                                       |bcx| {
-                        let bcx_out = trans_if_else(bcx, elexpr, dest);
+                        let bcx_out = trans_if_else(bcx, elexpr, dest, false);
                         debuginfo::clear_source_location(bcx.fcx);
-                        trans_block_cleanups(bcx_out, block_cleanups(bcx))
+                        bcx_out
                     })
                 }
                 // if false { .. }
@@ -116,7 +116,7 @@ pub fn trans_if(bcx: @mut Block,
     let (else_bcx_in, next_bcx) = match els {
       Some(elexpr) => {
           let else_bcx_in = scope_block(bcx, elexpr.info(), "else");
-          let else_bcx_out = trans_if_else(else_bcx_in, elexpr, dest);
+          let else_bcx_out = trans_if_else(else_bcx_in, elexpr, dest, true);
           (else_bcx_in, join_blocks(bcx, [then_bcx_out, else_bcx_out]))
       }
       _ => {
@@ -138,7 +138,7 @@ pub fn trans_if(bcx: @mut Block,
 
     // trans `else [ if { .. } ... | { .. } ]`
     fn trans_if_else(else_bcx_in: @mut Block, elexpr: @ast::Expr,
-                     dest: expr::Dest) -> @mut Block {
+                     dest: expr::Dest, cleanup: bool) -> @mut Block {
         let else_bcx_out = match elexpr.node {
             ast::ExprIf(_, _, _) => {
                 let elseif_blk = ast_util::block_from_expr(elexpr);
@@ -150,8 +150,12 @@ pub fn trans_if(bcx: @mut Block,
             // would be nice to have a constraint on ifs
             _ => else_bcx_in.tcx().sess.bug("strange alternative in if")
         };
-        debuginfo::clear_source_location(else_bcx_in.fcx);
-        trans_block_cleanups(else_bcx_out, block_cleanups(else_bcx_in))
+        if cleanup {
+            debuginfo::clear_source_location(else_bcx_in.fcx);
+            trans_block_cleanups(else_bcx_out, block_cleanups(else_bcx_in))
+        } else {
+            else_bcx_out
+        }
     }
 }
 
diff --git a/src/test/run-pass/issue-10734.rs b/src/test/run-pass/issue-10734.rs
new file mode 100644
index 00000000000..5123b214b8d
--- /dev/null
+++ b/src/test/run-pass/issue-10734.rs
@@ -0,0 +1,20 @@
+// Copyright 2013 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.
+
+pub fn main() {
+    if true {
+        let _a = ~3;
+    }
+    if false {
+        fail!()
+    } else {
+        let _a = ~3;
+    }
+}