about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2016-05-11 10:46:36 +0300
committerEduard Burtescu <edy.burt@gmail.com>2016-05-11 10:46:36 +0300
commite940de64ca7c31dcf1111406850eaa7a7e01cd36 (patch)
tree44684d56e840fb1b149a5c8d4e6bfa89893dee8e /src
parent80ec1b9f1040fba67846924234167feeb24d1f68 (diff)
downloadrust-e940de64ca7c31dcf1111406850eaa7a7e01cd36.tar.gz
rust-e940de64ca7c31dcf1111406850eaa7a7e01cd36.zip
mir: drop temps outside-in by scheduling the drops inside-out.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/build/expr/as_temp.rs16
-rw-r--r--src/test/run-pass/issue-23338-ensure-param-drop-order.rs16
2 files changed, 16 insertions, 16 deletions
diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs
index a4f4e44b1b1..13686d24ffd 100644
--- a/src/librustc_mir/build/expr/as_temp.rs
+++ b/src/librustc_mir/build/expr/as_temp.rs
@@ -35,12 +35,8 @@ impl<'a,'tcx> Builder<'a,'tcx> {
 
         let expr_ty = expr.ty.clone();
         let temp = this.temp(expr_ty.clone());
-        // In constants, temp_lifetime is None. We should not need to drop
-        // anything because no values with a destructor can be created in
-        // a constant at this time, even if the type may need dropping.
-        if let Some(temp_lifetime) = expr.temp_lifetime {
-            this.schedule_drop(expr.span, temp_lifetime, &temp, expr_ty);
-        }
+        let temp_lifetime = expr.temp_lifetime;
+        let expr_span = expr.span;
 
         // Careful here not to cause an infinite cycle. If we always
         // called `into`, then for lvalues like `x.f`, it would
@@ -51,7 +47,6 @@ impl<'a,'tcx> Builder<'a,'tcx> {
         // course) `as_temp`.
         match Category::of(&expr.kind).unwrap() {
             Category::Lvalue => {
-                let expr_span = expr.span;
                 let lvalue = unpack!(block = this.as_lvalue(block, expr));
                 let rvalue = Rvalue::Use(Operand::Consume(lvalue));
                 let scope_id = this.innermost_scope_id();
@@ -62,6 +57,13 @@ impl<'a,'tcx> Builder<'a,'tcx> {
             }
         }
 
+        // In constants, temp_lifetime is None. We should not need to drop
+        // anything because no values with a destructor can be created in
+        // a constant at this time, even if the type may need dropping.
+        if let Some(temp_lifetime) = temp_lifetime {
+            this.schedule_drop(expr_span, temp_lifetime, &temp, expr_ty);
+        }
+
         block.and(temp)
     }
 }
diff --git a/src/test/run-pass/issue-23338-ensure-param-drop-order.rs b/src/test/run-pass/issue-23338-ensure-param-drop-order.rs
index 73c52a0843c..fb84e7bae51 100644
--- a/src/test/run-pass/issue-23338-ensure-param-drop-order.rs
+++ b/src/test/run-pass/issue-23338-ensure-param-drop-order.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(rustc_attrs)]
-
 // ignore-pretty : (#23623) problems when  ending with // comments
 
 // This test is ensuring that parameters are indeed dropped after
@@ -42,11 +40,11 @@ pub fn main() {
                    //    | | |     |                     eval tail of foo
                    //    | | | +-- Make D(de_5, 6)
                    //    | | | | +-- Make D(de_6, 7)
-                   6, // | | | +-- Drop D(de_5, 6)
-                   //    | | |   | |
-                   5, // | | |   | +-- Drop D(de_4, 5)
-                   //    | | |   |
+                   5, // | | | | | +-- Drop D(de_4, 5)
+                   //    | | | | |
                    2, // | | +-- Drop D(de_2, 2)
+                   //    | |   | |
+                   6, // | |   +-- Drop D(de_5, 6)
                    //    | |     |
                    1, // | +-- Drop D(de_1, 1)
                    //    |       |
@@ -66,8 +64,8 @@ fn test<'a>(log: d::Log<'a>) {
     d::println(&format!("result {}", result));
 }
 
-#[rustc_no_mir] // FIXME #29855 MIR doesn't handle all drops correctly.
-fn foo<'a>(da0: D<'a>, de1: D<'a>) -> D<'a> {
+// FIXME(#33490) Remove the double braces when old trans is gone.
+fn foo<'a>(da0: D<'a>, de1: D<'a>) -> D<'a> {{
     d::println("entered foo");
     let de2 = de1.incr();      // creates D(de_2, 2)
     let de4 = {
@@ -76,7 +74,7 @@ fn foo<'a>(da0: D<'a>, de1: D<'a>) -> D<'a> {
     };
     d::println("eval tail of foo");
     de4.incr().incr()          // creates D(de_5, 6) and D(de_6, 7)
-}
+}}
 
 // This module provides simultaneous printouts of the dynamic extents
 // of all of the D values, in addition to logging the order that each