Skip to content

Commit 4a6ba51

Browse files
committed
Schedule storage-dead of temporaries sooner
This ensures that we will correctly generate a storage-dead if the initializing expression diverges.
1 parent decfc9b commit 4a6ba51

File tree

4 files changed

+32
-17
lines changed

4 files changed

+32
-17
lines changed

src/librustc_mir/build/expr/as_temp.rs

+28-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! See docs in build/expr/mod.rs
22
33
use crate::build::{BlockAnd, BlockAndExtension, Builder};
4+
use crate::build::scope::{CachedBlock, DropKind};
45
use crate::hair::*;
56
use rustc::middle::region;
67
use rustc::mir::*;
@@ -63,6 +64,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
6364
}
6465
this.local_decls.push(local_decl)
6566
};
67+
let temp_place = &Place::Base(PlaceBase::Local(temp));
68+
6669
if !expr_ty.is_never() {
6770
this.cfg.push(
6871
block,
@@ -71,25 +74,38 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
7174
kind: StatementKind::StorageLive(temp),
7275
},
7376
);
77+
78+
// In constants, temp_lifetime is None for temporaries that live for the
79+
// 'static lifetime. Thus we do not drop these temporaries and simply leak them.
80+
// This is equivalent to what `let x = &foo();` does in functions. The temporary
81+
// is lifted to their surrounding scope. In a function that means the temporary lives
82+
// until just before the function returns. In constants that means it outlives the
83+
// constant's initialization value computation. Anything outliving a constant
84+
// must have the `'static` lifetime and live forever.
85+
// Anything with a shorter lifetime (e.g the `&foo()` in `bar(&foo())` or anything
86+
// within a block will keep the regular drops just like runtime code.
87+
if let Some(temp_lifetime) = temp_lifetime {
88+
this.schedule_drop(
89+
expr_span,
90+
temp_lifetime,
91+
temp_place,
92+
expr_ty,
93+
DropKind::Storage,
94+
);
95+
}
7496
}
7597

76-
unpack!(block = this.into(&Place::Base(PlaceBase::Local(temp)), block, expr));
98+
unpack!(block = this.into(temp_place, block, expr));
7799

78-
// In constants, temp_lifetime is None for temporaries that live for the
79-
// 'static lifetime. Thus we do not drop these temporaries and simply leak them.
80-
// This is equivalent to what `let x = &foo();` does in functions. The temporary
81-
// is lifted to their surrounding scope. In a function that means the temporary lives
82-
// until just before the function returns. In constants that means it outlives the
83-
// constant's initialization value computation. Anything outliving a constant
84-
// must have the `'static` lifetime and live forever.
85-
// Anything with a shorter lifetime (e.g the `&foo()` in `bar(&foo())` or anything
86-
// within a block will keep the regular drops just like runtime code.
87100
if let Some(temp_lifetime) = temp_lifetime {
88-
this.schedule_drop_storage_and_value(
101+
this.schedule_drop(
89102
expr_span,
90103
temp_lifetime,
91-
&Place::Base(PlaceBase::Local(temp)),
104+
temp_place,
92105
expr_ty,
106+
DropKind::Value {
107+
cached_block: CachedBlock::default(),
108+
},
93109
);
94110
}
95111

src/test/mir-opt/issue-49232.rs

-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ fn main() {
8686
// unreachable;
8787
// }
8888
// bb17: {
89-
// StorageDead(_4);
9089
// goto -> bb18;
9190
// }
9291
// bb18: {

src/test/mir-opt/match_false_edges.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ fn main() {
109109
// goto -> bb13;
110110
// }
111111
// bb13: {
112-
// StorageDead(_1);
113112
// StorageDead(_2);
113+
// StorageDead(_1);
114114
// _0 = ();
115115
// return;
116116
// }
@@ -186,8 +186,8 @@ fn main() {
186186
// goto -> bb13;
187187
// }
188188
// bb13: {
189-
// StorageDead(_1);
190189
// StorageDead(_2);
190+
// StorageDead(_1);
191191
// _0 = ();
192192
// return;
193193
// }
@@ -289,8 +289,8 @@ fn main() {
289289
// goto -> bb17;
290290
// }
291291
// bb17: {
292-
// StorageDead(_1);
293292
// StorageDead(_2);
293+
// StorageDead(_1);
294294
// _0 = ();
295295
// return;
296296
// }

src/test/mir-opt/storage_live_dead_in_statics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,8 @@ fn main() {
182182
// _2 = Foo { tup: const "hi", data: move _3 };
183183
// _1 = &_2;
184184
// _0 = &(*_1);
185-
// StorageDead(_1);
186185
// StorageDead(_5);
186+
// StorageDead(_1);
187187
// return;
188188
// }
189189
//}

0 commit comments

Comments
 (0)