]> git.lizzy.rs Git - rust.git/commitdiff
emit StorageLive for box temporaries
authorAriel Ben-Yehuda <ariel.byd@gmail.com>
Mon, 14 Aug 2017 11:10:05 +0000 (14:10 +0300)
committerAriel Ben-Yehuda <ariel.byd@gmail.com>
Mon, 14 Aug 2017 11:10:05 +0000 (14:10 +0300)
We started emitting StorageDead, so we better emit the corrseponding
StorageLive to avoid problems.

src/librustc_mir/build/expr/as_rvalue.rs
src/test/mir-opt/box_expr.rs [new file with mode: 0644]

index 8974c4ec1fbfd126907f5aaaccb5232845e7a606..a625f4b04580be5fbc1acbdcaf202795f4e30c31 100644 (file)
@@ -97,13 +97,19 @@ fn expr_as_rvalue(&mut self,
             ExprKind::Box { value } => {
                 let value = this.hir.mirror(value);
                 let result = this.temp(expr.ty, expr_span);
-                // to start, malloc some memory of suitable type (thus far, uninitialized):
-                let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty);
-                this.cfg.push_assign(block, source_info, &result, box_);
                 if let Some(scope) = scope {
                     // schedule a shallow free of that memory, lest we unwind:
+                    this.cfg.push(block, Statement {
+                        source_info: source_info,
+                        kind: StatementKind::StorageLive(result.clone())
+                    });
                     this.schedule_drop(expr_span, scope, &result, value.ty);
                 }
+
+                // malloc some memory of suitable type (thus far, uninitialized):
+                let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty);
+                this.cfg.push_assign(block, source_info, &result, box_);
+
                 // initialize the box contents:
                 unpack!(block = this.into(&result.clone().deref(), block, value));
                 block.and(Rvalue::Use(Operand::Consume(result)))
diff --git a/src/test/mir-opt/box_expr.rs b/src/test/mir-opt/box_expr.rs
new file mode 100644 (file)
index 0000000..4015930
--- /dev/null
@@ -0,0 +1,88 @@
+// Copyright 2017 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.
+
+#![feature(box_syntax)]
+
+fn main() {
+    let x = box S::new();
+    drop(x);
+}
+
+struct S;
+
+impl S {
+    fn new() -> Self { S }
+}
+
+impl Drop for S {
+    fn drop(&mut self) {
+        println!("splat!");
+    }
+}
+
+// END RUST SOURCE
+// START rustc.node4.ElaborateDrops.before.mir
+//     let mut _0: ();
+//     let _1: std::boxed::Box<S>;
+//     let mut _2: std::boxed::Box<S>;
+//     let mut _3: ();
+//     let mut _4: std::boxed::Box<S>;
+//
+//     bb0: {
+//         StorageLive(_1);
+//         StorageLive(_2);
+//         _2 = Box(S);
+//         (*_2) = const S::new() -> [return: bb1, unwind: bb3];
+//     }
+//
+//     bb1: {
+//         _1 = _2;
+//         drop(_2) -> bb4;
+//     }
+//
+//     bb2: {
+//         resume;
+//     }
+//
+//     bb3: {
+//         drop(_2) -> bb2;
+//     }
+//
+//     bb4: {
+//         StorageDead(_2);
+//         StorageLive(_4);
+//         _4 = _1;
+//         _3 = const std::mem::drop(_4) -> [return: bb5, unwind: bb7];
+//     }
+//
+//     bb5: {
+//         drop(_4) -> [return: bb8, unwind: bb6];
+//     }
+//
+//     bb6: {
+//         drop(_1) -> bb2;
+//     }
+//
+//     bb7: {
+//         drop(_4) -> bb6;
+//     }
+//
+//     bb8: {
+//         StorageDead(_4);
+//         _0 = ();
+//         drop(_1) -> bb9;
+//     }
+//
+//     bb9: {
+//         StorageDead(_1);
+//         return;
+//     }
+// }
+// END rustc.node4.ElaborateDrops.before.mir