Skip to content

Commit e982162

Browse files
committed
Avoid modifying succ block in build_async_drop.
1 parent 34d1ae2 commit e982162

20 files changed

Lines changed: 792 additions & 678 deletions

compiler/rustc_mir_transform/src/elaborate_drop.rs

Lines changed: 25 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,6 @@ pub(crate) trait DropElaborator<'a, 'tcx>: fmt::Debug {
9696
fn typing_env(&self) -> ty::TypingEnv<'tcx>;
9797
fn allow_async_drops(&self) -> bool;
9898

99-
fn terminator_loc(&self, bb: BasicBlock) -> Location;
100-
10199
// Drop logic
102100

103101
/// Returns how `path` should be dropped, given `mode`.
@@ -200,19 +198,18 @@ where
200198
self.elaborator.tcx()
201199
}
202200

203-
// Generates three blocks:
204-
// * #1:pin_obj_bb: call Pin<ObjTy>::new_unchecked(&mut obj)
205-
// * #2:call_drop_bb: fut = call obj.<AsyncDrop::drop>() OR call async_drop_in_place<T>(obj)
206-
// * #3:drop_term_bb: drop (obj, fut, ...)
207-
// We keep async drop unexpanded to poll-loop here, to expand it later, at StateTransform -
208-
// into states expand.
209-
// call_destructor_only - to call only AsyncDrop::drop, not full async_drop_in_place glue
201+
/// Generates three blocks:
202+
/// * #1:pin_obj_bb: call Pin<ObjTy>::new_unchecked(&mut obj)
203+
/// * #2:call_drop_bb: fut = call obj.<AsyncDrop::drop>() OR call async_drop_in_place<T>(obj)
204+
/// * #3:drop_term_bb: drop (obj, fut, ...)
205+
/// We keep async drop unexpanded to poll-loop here, to expand it later, at StateTransform -
206+
/// into states expand.
207+
/// call_destructor_only - to call only AsyncDrop::drop, not full async_drop_in_place glue
210208
#[instrument(level = "debug", skip(self), ret)]
211209
fn build_async_drop(
212210
&mut self,
213211
place: Place<'tcx>,
214212
drop_ty: Ty<'tcx>,
215-
bb: Option<BasicBlock>,
216213
succ: BasicBlock,
217214
unwind: Unwind,
218215
dropline: Option<BasicBlock>,
@@ -221,11 +218,6 @@ where
221218
let tcx = self.tcx();
222219
let span = self.source_info.span;
223220

224-
let pin_obj_bb = bb.unwrap_or_else(|| {
225-
// Temporary terminator, will be replaced by patch
226-
self.new_block(unwind, TerminatorKind::Return)
227-
});
228-
229221
let (fut_ty, drop_fn_def_id, trait_args) = if call_destructor_only {
230222
// Resolving obj.<AsyncDrop::drop>()
231223
let trait_ref =
@@ -260,8 +252,8 @@ where
260252
self.elaborator.body().span,
261253
"AsyncDrop type without correct `async fn drop(...)`.",
262254
);
263-
self.elaborator.patch().patch_terminator(
264-
pin_obj_bb,
255+
return self.new_block(
256+
unwind,
265257
TerminatorKind::Drop {
266258
place,
267259
target: succ,
@@ -271,7 +263,6 @@ where
271263
async_fut: None,
272264
},
273265
);
274-
return pin_obj_bb;
275266
};
276267
let drop_fn = Ty::new_fn_def(tcx, drop_fn_def_id, trait_args);
277268
let sig = drop_fn.fn_sig(tcx);
@@ -291,10 +282,7 @@ where
291282
// #1:pin_obj_bb >>> obj_ref = &mut obj
292283
let obj_ref_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, drop_ty);
293284
let obj_ref_place = Place::from(self.new_temp(obj_ref_ty));
294-
295-
let term_loc = self.elaborator.terminator_loc(pin_obj_bb);
296-
self.elaborator.patch().add_assign(
297-
term_loc,
285+
let assign_obj_ref_place = self.assign(
298286
obj_ref_place,
299287
Rvalue::Ref(
300288
tcx.lifetimes.re_erased,
@@ -394,8 +382,9 @@ where
394382
}
395383

396384
// #1:pin_obj_bb >>> call Pin<ObjTy>::new_unchecked(&mut obj)
397-
self.elaborator.patch().patch_terminator(
398-
pin_obj_bb,
385+
self.new_block_with_statements(
386+
unwind,
387+
vec![assign_obj_ref_place],
399388
TerminatorKind::Call {
400389
func: pin_obj_new_unchecked_fn,
401390
args: [dummy_spanned(Operand::Move(obj_ref_place))].into(),
@@ -405,24 +394,25 @@ where
405394
call_source: CallSource::Misc,
406395
fn_span: span,
407396
},
408-
);
409-
pin_obj_bb
397+
)
410398
}
411399

412400
fn build_drop(&mut self, bb: BasicBlock) {
413401
let drop_ty = self.place_ty(self.place);
414402
if !self.elaborator.patch_ref().block(self.elaborator.body(), bb).is_cleanup
415403
&& self.check_if_can_async_drop(drop_ty, false)
416404
{
417-
self.build_async_drop(
405+
let async_drop_bb = self.build_async_drop(
418406
self.place,
419407
drop_ty,
420-
Some(bb),
421408
self.succ,
422409
self.unwind,
423410
self.dropline,
424411
false,
425412
);
413+
self.elaborator
414+
.patch()
415+
.patch_terminator(bb, TerminatorKind::Goto { target: async_drop_bb });
426416
} else {
427417
self.elaborator.patch().patch_terminator(
428418
bb,
@@ -1005,7 +995,7 @@ where
1005995
) -> BasicBlock {
1006996
let ty = self.place_ty(self.place);
1007997
if !unwind.is_cleanup() && self.check_if_can_async_drop(ty, true) {
1008-
self.build_async_drop(self.place, ty, None, succ, unwind, dropline, true)
998+
self.build_async_drop(self.place, ty, succ, unwind, dropline, true)
1009999
} else {
10101000
self.destructor_call_block_sync(succ, unwind)
10111001
}
@@ -1067,15 +1057,11 @@ where
10671057

10681058
let place = tcx.mk_place_deref(ptr);
10691059
if !unwind.is_cleanup() && self.check_if_can_async_drop(ety, false) {
1070-
self.build_async_drop(
1071-
place,
1072-
ety,
1073-
Some(drop_block),
1074-
loop_block,
1075-
unwind,
1076-
dropline,
1077-
false,
1078-
);
1060+
let async_drop_bb =
1061+
self.build_async_drop(place, ety, loop_block, unwind, dropline, false);
1062+
self.elaborator
1063+
.patch()
1064+
.patch_terminator(drop_block, TerminatorKind::Goto { target: async_drop_bb });
10791065
} else {
10801066
self.elaborator.patch().patch_terminator(
10811067
drop_block,
@@ -1331,15 +1317,7 @@ where
13311317
fn drop_block(&mut self, target: BasicBlock, unwind: Unwind) -> BasicBlock {
13321318
let drop_ty = self.place_ty(self.place);
13331319
if !unwind.is_cleanup() && self.check_if_can_async_drop(drop_ty, false) {
1334-
self.build_async_drop(
1335-
self.place,
1336-
drop_ty,
1337-
None,
1338-
self.succ,
1339-
unwind,
1340-
self.dropline,
1341-
false,
1342-
)
1320+
self.build_async_drop(self.place, drop_ty, self.succ, unwind, self.dropline, false)
13431321
} else {
13441322
self.new_block(
13451323
unwind,

compiler/rustc_mir_transform/src/elaborate_drops.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,6 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for ElaborateDropsCtxt<'a, 'tcx> {
162162
true
163163
}
164164

165-
fn terminator_loc(&self, bb: BasicBlock) -> Location {
166-
self.patch.terminator_loc(self.body, bb)
167-
}
168-
169165
#[instrument(level = "debug", skip(self), ret)]
170166
fn drop_style(&self, path: Self::Path, mode: DropFlagMode) -> DropStyle {
171167
let ((maybe_init, maybe_uninit), multipart) = match mode {

compiler/rustc_mir_transform/src/patch.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -166,11 +166,6 @@ impl<'tcx> MirPatch<'tcx> {
166166
}
167167
}
168168

169-
pub(crate) fn terminator_loc(&self, body: &Body<'tcx>, bb: BasicBlock) -> Location {
170-
let offset = self.block(body, bb).statements.len();
171-
Location { block: bb, statement_index: offset }
172-
}
173-
174169
/// Queues the addition of a new temporary with additional local info.
175170
pub(crate) fn new_local_with_info(
176171
&mut self,

compiler/rustc_mir_transform/src/shim.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -429,9 +429,6 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> {
429429
self.typing_env
430430
}
431431

432-
fn terminator_loc(&self, bb: BasicBlock) -> Location {
433-
self.patch.terminator_loc(self.body, bb)
434-
}
435432
fn allow_async_drops(&self) -> bool {
436433
self.produce_async_drops
437434
}

tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.MentionedItems.after.mir

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ yields ()
2222

2323
bb0: {
2424
_3 = move (_1.0: &mut AsyncEnum);
25-
goto -> bb21;
25+
goto -> bb24;
2626
}
2727

2828
bb1: {
@@ -49,43 +49,43 @@ yields ()
4949
}
5050

5151
bb6: {
52-
_5 = &mut (((*_3) as A).0: AsyncInt);
53-
_6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb9, unwind: bb2];
52+
StorageDead(_4);
53+
goto -> bb1;
5454
}
5555

5656
bb7: {
57-
StorageDead(_4);
58-
goto -> bb1;
57+
async drop((((*_3) as A).0: AsyncInt); poll=_4) -> [return: bb6, unwind: bb2];
5958
}
6059

6160
bb8: {
62-
async drop((((*_3) as A).0: AsyncInt); poll=_4) -> [return: bb7, unwind: bb2];
61+
_7 = copy (_6.0: &mut AsyncInt);
62+
StorageLive(_4);
63+
_4 = async_drop_in_place::<AsyncInt>(move _7) -> [return: bb7, unwind: bb2];
6364
}
6465

6566
bb9: {
66-
_7 = copy (_6.0: &mut AsyncInt);
67-
StorageLive(_4);
68-
_4 = async_drop_in_place::<AsyncInt>(move _7) -> [return: bb8, unwind: bb2];
67+
_5 = &mut (((*_3) as A).0: AsyncInt);
68+
_6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb8, unwind: bb2];
6969
}
7070

7171
bb10: {
72-
_9 = &mut (((*_3) as A).0: AsyncInt);
73-
_10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb13, unwind: bb2];
72+
StorageDead(_8);
73+
goto -> bb3;
7474
}
7575

7676
bb11: {
77-
StorageDead(_8);
78-
goto -> bb3;
77+
async drop((((*_3) as A).0: AsyncInt); poll=_8) -> [return: bb10, unwind: bb2, drop: bb1];
7978
}
8079

8180
bb12: {
82-
async drop((((*_3) as A).0: AsyncInt); poll=_8) -> [return: bb11, unwind: bb2, drop: bb1];
81+
_11 = copy (_10.0: &mut AsyncInt);
82+
StorageLive(_8);
83+
_8 = async_drop_in_place::<AsyncInt>(move _11) -> [return: bb11, unwind: bb2];
8384
}
8485

8586
bb13: {
86-
_11 = copy (_10.0: &mut AsyncInt);
87-
StorageLive(_8);
88-
_8 = async_drop_in_place::<AsyncInt>(move _11) -> [return: bb12, unwind: bb2];
87+
_9 = &mut (((*_3) as A).0: AsyncInt);
88+
_10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb12, unwind: bb2];
8989
}
9090

9191
bb14 (cleanup): {
@@ -106,7 +106,7 @@ yields ()
106106

107107
bb18: {
108108
_12 = discriminant((*_3));
109-
switchInt(move _12) -> [0: bb10, otherwise: bb17];
109+
switchInt(move _12) -> [0: bb13, otherwise: bb17];
110110
}
111111

112112
bb19 (cleanup): {
@@ -118,25 +118,25 @@ yields ()
118118
bb20: {
119119
StorageDead(_15);
120120
_14 = discriminant((*_3));
121-
switchInt(move _14) -> [0: bb6, otherwise: bb16];
121+
switchInt(move _14) -> [0: bb9, otherwise: bb16];
122122
}
123123

124124
bb21: {
125-
_16 = &mut (*_3);
126-
_17 = Pin::<&mut AsyncEnum>::new_unchecked(move _16) -> [return: bb24, unwind: bb19];
125+
StorageDead(_15);
126+
goto -> bb18;
127127
}
128128

129129
bb22: {
130-
StorageDead(_15);
131-
goto -> bb18;
130+
async drop((*_3); poll=_15) -> [return: bb21, unwind: bb19, drop: bb20];
132131
}
133132

134133
bb23: {
135-
async drop((*_3); poll=_15) -> [return: bb22, unwind: bb19, drop: bb20];
134+
StorageLive(_15);
135+
_15 = <AsyncEnum as AsyncDrop>::drop(move _17) -> [return: bb22, unwind: bb19];
136136
}
137137

138138
bb24: {
139-
StorageLive(_15);
140-
_15 = <AsyncEnum as AsyncDrop>::drop(move _17) -> [return: bb23, unwind: bb19];
139+
_16 = &mut (*_3);
140+
_17 = Pin::<&mut AsyncEnum>::new_unchecked(move _16) -> [return: bb23, unwind: bb19];
141141
}
142142
}

tests/mir-opt/coroutine/async_drop.core.future-async_drop-async_drop_in_place-{closure#0}.AsyncEnum.StateTransform.after.mir

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -100,25 +100,25 @@ fn async_drop_in_place::{closure#0}(_1: Pin<&mut {async fn body of async_drop_in
100100
}
101101

102102
bb5: {
103-
_46 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum);
104-
_9 = &mut (((*_46) as A).0: AsyncInt);
105-
_10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb8, unwind: bb3];
106-
}
107-
108-
bb6: {
109103
nop;
110104
goto -> bb2;
111105
}
112106

113-
bb7: {
107+
bb6: {
114108
_24 = move _2;
115109
goto -> bb17;
116110
}
117111

118-
bb8: {
112+
bb7: {
119113
_11 = copy (_10.0: &mut AsyncInt);
120114
nop;
121-
(((*_43) as variant#5).0: impl std::future::Future<Output = ()>) = async_drop_in_place::<AsyncInt>(move _11) -> [return: bb7, unwind: bb3];
115+
(((*_43) as variant#5).0: impl std::future::Future<Output = ()>) = async_drop_in_place::<AsyncInt>(move _11) -> [return: bb6, unwind: bb3];
116+
}
117+
118+
bb8: {
119+
_46 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum);
120+
_9 = &mut (((*_46) as A).0: AsyncInt);
121+
_10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb7, unwind: bb3];
122122
}
123123

124124
bb9 (cleanup): {
@@ -142,7 +142,7 @@ fn async_drop_in_place::{closure#0}(_1: Pin<&mut {async fn body of async_drop_in
142142
nop;
143143
_50 = no_retag copy (((*_43) as variant#7).0: &mut AsyncEnum);
144144
_12 = discriminant((*_50));
145-
switchInt(move _12) -> [0: bb5, otherwise: bb10];
145+
switchInt(move _12) -> [0: bb8, otherwise: bb10];
146146
}
147147

148148
bb13: {
@@ -178,7 +178,7 @@ fn async_drop_in_place::{closure#0}(_1: Pin<&mut {async fn body of async_drop_in
178178
bb19: {
179179
StorageDead(_26);
180180
_27 = discriminant(_23);
181-
switchInt(move _27) -> [0: bb6, 1: bb16, otherwise: bb18];
181+
switchInt(move _27) -> [0: bb5, 1: bb16, otherwise: bb18];
182182
}
183183

184184
bb20: {

0 commit comments

Comments
 (0)