From aabaf121550dd3743f12ff30bab625d6f2d6f89c Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Wed, 3 Jul 2019 08:25:27 -0400 Subject: [PATCH] Fix leak when early returning out of `box` syntax Fixes #62289 --- src/librustc_mir/build/expr/as_rvalue.rs | 2 +- src/test/mir-opt/issue-62289.rs | 91 ++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 src/test/mir-opt/issue-62289.rs diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 17e7b1acc68..56c518a6d57 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -128,7 +128,7 @@ fn expr_as_rvalue( expr_span, scope, result, - value.ty, + expr.ty, ); } diff --git a/src/test/mir-opt/issue-62289.rs b/src/test/mir-opt/issue-62289.rs new file mode 100644 index 00000000000..a3b517e9bca --- /dev/null +++ b/src/test/mir-opt/issue-62289.rs @@ -0,0 +1,91 @@ +// check that we don't forget to drop the Box if we early return before +// initializing it +// ignore-tidy-linelength +// ignore-wasm32-bare compiled with panic=abort by default + +#![feature(box_syntax)] + +fn test() -> Option> { + Some(box (None?)) +} + +fn main() { + test(); +} + +// END RUST SOURCE +// START rustc.test.ElaborateDrops.before.mir +// fn test() -> std::option::Option> { +// ... +// bb0: { +// StorageLive(_1); +// StorageLive(_2); +// _2 = Box(u32); +// StorageLive(_3); +// StorageLive(_4); +// _4 = std::option::Option::::None; +// _3 = const as std::ops::Try>::into_result(move _4) -> [return: bb2, unwind: bb3]; +// } +// bb1 (cleanup): { +// resume; +// } +// bb2: { +// StorageDead(_4); +// _5 = discriminant(_3); +// switchInt(move _5) -> [0isize: bb10, 1isize: bb5, otherwise: bb4]; +// } +// bb3 (cleanup): { +// drop(_2) -> bb1; +// } +// bb4: { +// unreachable; +// } +// bb5: { +// StorageLive(_6); +// _6 = ((_3 as Err).0: std::option::NoneError); +// StorageLive(_8); +// StorageLive(_9); +// _9 = _6; +// _8 = const >::from(move _9) -> [return: bb7, unwind: bb3]; +// } +// bb6: { +// return; +// } +// bb7: { +// StorageDead(_9); +// _0 = const > as std::ops::Try>::from_error(move _8) -> [return: bb8, unwind: bb3]; +// } +// bb8: { +// StorageDead(_8); +// StorageDead(_6); +// drop(_2) -> bb9; +// } +// bb9: { +// StorageDead(_2); +// StorageDead(_1); +// StorageDead(_3); +// goto -> bb6; +// } +// bb10: { +// StorageLive(_10); +// _10 = ((_3 as Ok).0: u32); +// (*_2) = _10; +// StorageDead(_10); +// _1 = move _2; +// drop(_2) -> [return: bb12, unwind: bb11]; +// } +// bb11 (cleanup): { +// drop(_1) -> bb1; +// } +// bb12: { +// StorageDead(_2); +// _0 = std::option::Option::>::Some(move _1,); +// drop(_1) -> bb13; +// } +// bb13: { +// StorageDead(_1); +// StorageDead(_3); +// goto -> bb6; +// } +// } +// END rustc.test.ElaborateDrops.before.mir