Skip to content

Commit c133e1c

Browse files
committed
Simplify type computation.
1 parent b5f048d commit c133e1c

24 files changed

Lines changed: 1256 additions & 1396 deletions

File tree

compiler/rustc_mir_transform/src/elaborate_drop.rs

Lines changed: 34 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ use rustc_index::Idx;
66
use rustc_middle::mir::*;
77
use rustc_middle::ty::adjustment::PointerCoercion;
88
use rustc_middle::ty::util::IntTypeExt;
9-
use rustc_middle::ty::{self, GenericArg, GenericArgsRef, Ty, TyCtxt};
9+
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt};
1010
use rustc_middle::{bug, span_bug};
11-
use rustc_span::{DUMMY_SP, Spanned, dummy_spanned};
11+
use rustc_span::{DUMMY_SP, dummy_spanned};
1212
use tracing::{debug, instrument};
1313

1414
use crate::patch::MirPatch;
@@ -216,6 +216,7 @@ where
216216
) -> BasicBlock {
217217
let tcx = self.tcx();
218218
let span = self.source_info.span;
219+
let obj_ref_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, drop_ty);
219220

220221
let async_drop_fn_def_id = if call_destructor_only {
221222
// Resolving obj.<AsyncDrop::drop>()
@@ -233,37 +234,9 @@ where
233234
.output();
234235
let fut = self.new_temp(fut_ty);
235236

236-
// #1:pin_obj_bb >>> obj_ref = &mut obj
237-
let obj_ref_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, drop_ty);
238-
let obj_ref_place = Place::from(self.new_temp(obj_ref_ty));
239-
let assign_obj_ref_place = self.assign(
240-
obj_ref_place,
241-
Rvalue::Ref(
242-
tcx.lifetimes.re_erased,
243-
BorrowKind::Mut { kind: MutBorrowKind::Default },
244-
place,
245-
),
246-
);
247-
248-
// pin_obj_place preparation
249-
let pin_obj_new_unchecked_fn = Ty::new_fn_def(
250-
tcx,
251-
tcx.require_lang_item(LangItem::PinNewUnchecked, span),
252-
[GenericArg::from(obj_ref_ty)],
253-
);
254-
let pin_obj_ty = pin_obj_new_unchecked_fn.fn_sig(tcx).output().no_bound_vars().unwrap();
255-
let pin_obj_place = Place::from(self.new_temp(pin_obj_ty));
256-
let pin_obj_new_unchecked_fn = Operand::Constant(Box::new(ConstOperand {
257-
span,
258-
user_ty: None,
259-
const_: Const::zero_sized(pin_obj_new_unchecked_fn),
260-
}));
261-
262237
// Create an intermediate block that does StorageDead(fut) then jumps to succ.
263-
// This is necessary because `succ` may differ from `self.succ` (e.g. when
264-
// build_async_drop is called from drop_loop, `succ` is the loop header).
265-
// Placing StorageDead directly at `self.succ` would miss the loop-back edge,
266-
// causing StorageLive(fut) to fire again without a preceding StorageDead.
238+
// This is necessary because we do not want to modify statements
239+
// in existing blocks, in case those are used somewhere else in MIR.
267240
let succ_with_dead = self.new_block_with_statements(
268241
unwind,
269242
vec![self.storage_dead(fut)],
@@ -297,35 +270,24 @@ where
297270
},
298271
);
299272

300-
// #2:call_drop_bb
301-
let mut call_statements = Vec::new();
273+
// #2:call_drop_bb >>> call AsyncDrop::drop(pin_obj) OR call async_drop_in_place(pin_obj.pointer)
274+
let pin_adt_def = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, span));
275+
let pin_obj_ty = Ty::new_adt(tcx, pin_adt_def, tcx.mk_args(&[obj_ref_ty.into()]));
276+
// Where we store the result of Pin<&drop_ty>::new_unchecked(&mut place).
277+
let pin_obj_local = self.new_temp(pin_obj_ty);
302278
let drop_arg = if call_destructor_only {
303-
pin_obj_place
279+
// `AsyncDrop::drop` takes `self: Pin<&mut Self>`.
280+
Operand::Move(pin_obj_local.into())
304281
} else {
305-
let ty::Adt(adt_def, adt_args) = pin_obj_ty.kind() else {
306-
bug!();
307-
};
308-
let unwrap_ty =
309-
adt_def.non_enum_variant().fields[FieldIdx::ZERO].ty(tcx, adt_args).skip_norm_wip();
310-
let obj_ref_place = Place::from(self.new_temp(unwrap_ty));
311-
call_statements.push(self.assign(
312-
obj_ref_place,
313-
Rvalue::Use(
314-
Operand::Copy(tcx.mk_place_field(pin_obj_place, FieldIdx::ZERO, unwrap_ty)),
315-
WithRetag::Yes,
316-
),
317-
));
318-
319-
obj_ref_place
282+
// `async_drop_in_place` takes `obj: &mut T`.
283+
Operand::Copy(tcx.mk_place_field(pin_obj_local.into(), FieldIdx::ZERO, obj_ref_ty))
320284
};
321-
call_statements.push(self.storage_live(fut));
322-
323285
let call_drop_bb = self.new_block_with_statements(
324286
unwind,
325-
call_statements,
287+
vec![self.storage_live(fut)],
326288
TerminatorKind::Call {
327289
func: Operand::function_handle(tcx, async_drop_fn_def_id, [drop_ty.into()], span),
328-
args: [Spanned { node: Operand::Move(drop_arg), span: DUMMY_SP }].into(),
290+
args: [dummy_spanned(drop_arg)].into(),
329291
destination: fut.into(),
330292
target: Some(drop_term_bb),
331293
unwind: unwind_with_dead.into_action(),
@@ -335,13 +297,28 @@ where
335297
);
336298

337299
// #1:pin_obj_bb >>> call Pin<ObjTy>::new_unchecked(&mut obj)
300+
let obj_ref_place = Place::from(self.new_temp(obj_ref_ty));
301+
let pin_obj_new_unchecked_fn = tcx.require_lang_item(LangItem::PinNewUnchecked, span);
302+
let assign_obj_ref_place = self.assign(
303+
obj_ref_place,
304+
Rvalue::Ref(
305+
tcx.lifetimes.re_erased,
306+
BorrowKind::Mut { kind: MutBorrowKind::Default },
307+
place,
308+
),
309+
);
338310
self.new_block_with_statements(
339311
unwind,
340312
vec![assign_obj_ref_place],
341313
TerminatorKind::Call {
342-
func: pin_obj_new_unchecked_fn,
314+
func: Operand::function_handle(
315+
tcx,
316+
pin_obj_new_unchecked_fn,
317+
[obj_ref_ty.into()],
318+
span,
319+
),
343320
args: [dummy_spanned(Operand::Move(obj_ref_place))].into(),
344-
destination: pin_obj_place,
321+
destination: pin_obj_local.into(),
345322
target: Some(call_drop_bb),
346323
unwind: unwind.into_action(),
347324
call_source: CallSource::Misc,
@@ -928,8 +905,7 @@ where
928905
)],
929906
TerminatorKind::Call {
930907
func: Operand::function_handle(tcx, drop_fn, [ty.into()], self.source_info.span),
931-
args: [Spanned { node: Operand::Move(Place::from(ref_place)), span: DUMMY_SP }]
932-
.into(),
908+
args: [dummy_spanned(Operand::Move(Place::from(ref_place)))].into(),
933909
destination: unit_temp,
934910
target: Some(succ),
935911
unwind: unwind.into_action(),

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

Lines changed: 33 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,17 @@ yields ()
66
let mut _0: ();
77
let mut _3: &mut AsyncEnum;
88
let mut _4: impl std::future::Future<Output = ()>;
9-
let mut _5: &mut AsyncInt;
10-
let mut _6: std::pin::Pin<&mut AsyncInt>;
11-
let mut _7: &mut AsyncInt;
12-
let mut _8: impl std::future::Future<Output = ()>;
9+
let mut _5: std::pin::Pin<&mut AsyncInt>;
10+
let mut _6: &mut AsyncInt;
11+
let mut _7: impl std::future::Future<Output = ()>;
12+
let mut _8: std::pin::Pin<&mut AsyncInt>;
1313
let mut _9: &mut AsyncInt;
14-
let mut _10: std::pin::Pin<&mut AsyncInt>;
15-
let mut _11: &mut AsyncInt;
14+
let mut _10: isize;
15+
let mut _11: isize;
1616
let mut _12: isize;
17-
let mut _13: isize;
18-
let mut _14: isize;
19-
let mut _15: impl std::future::Future<Output = ()>;
20-
let mut _16: &mut AsyncEnum;
21-
let mut _17: std::pin::Pin<&mut AsyncEnum>;
17+
let mut _13: impl std::future::Future<Output = ()>;
18+
let mut _14: std::pin::Pin<&mut AsyncEnum>;
19+
let mut _15: &mut AsyncEnum;
2220

2321
bb0: {
2422
_3 = move (_1.0: &mut AsyncEnum);
@@ -60,44 +58,42 @@ yields ()
6058
}
6159

6260
bb9: {
63-
_7 = copy (_6.0: &mut AsyncInt);
6461
StorageLive(_4);
65-
_4 = async_drop_in_place::<AsyncInt>(move _7) -> [return: bb8, unwind: bb7];
62+
_4 = async_drop_in_place::<AsyncInt>(copy (_5.0: &mut AsyncInt)) -> [return: bb8, unwind: bb7];
6663
}
6764

6865
bb10: {
69-
_5 = &mut (((*_3) as A).0: AsyncInt);
70-
_6 = Pin::<&mut AsyncInt>::new_unchecked(move _5) -> [return: bb9, unwind: bb2];
66+
_6 = &mut (((*_3) as A).0: AsyncInt);
67+
_5 = Pin::<&mut AsyncInt>::new_unchecked(move _6) -> [return: bb9, unwind: bb2];
7168
}
7269

7370
bb11: {
74-
StorageDead(_8);
71+
StorageDead(_7);
7572
goto -> bb3;
7673
}
7774

7875
bb12: {
79-
StorageDead(_8);
76+
StorageDead(_7);
8077
goto -> bb1;
8178
}
8279

8380
bb13 (cleanup): {
84-
StorageDead(_8);
81+
StorageDead(_7);
8582
goto -> bb2;
8683
}
8784

8885
bb14: {
89-
async drop((((*_3) as A).0: AsyncInt); poll=_8) -> [return: bb11, unwind: bb13, drop: bb12];
86+
async drop((((*_3) as A).0: AsyncInt); poll=_7) -> [return: bb11, unwind: bb13, drop: bb12];
9087
}
9188

9289
bb15: {
93-
_11 = copy (_10.0: &mut AsyncInt);
94-
StorageLive(_8);
95-
_8 = async_drop_in_place::<AsyncInt>(move _11) -> [return: bb14, unwind: bb13];
90+
StorageLive(_7);
91+
_7 = async_drop_in_place::<AsyncInt>(copy (_8.0: &mut AsyncInt)) -> [return: bb14, unwind: bb13];
9692
}
9793

9894
bb16: {
9995
_9 = &mut (((*_3) as A).0: AsyncInt);
100-
_10 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb15, unwind: bb2];
96+
_8 = Pin::<&mut AsyncInt>::new_unchecked(move _9) -> [return: bb15, unwind: bb2];
10197
}
10298

10399
bb17 (cleanup): {
@@ -117,46 +113,46 @@ yields ()
117113
}
118114

119115
bb21: {
120-
_12 = discriminant((*_3));
121-
switchInt(move _12) -> [0: bb16, otherwise: bb20];
116+
_10 = discriminant((*_3));
117+
switchInt(move _10) -> [0: bb16, otherwise: bb20];
122118
}
123119

124120
bb22 (cleanup): {
125-
_13 = discriminant((*_3));
126-
switchInt(move _13) -> [0: bb4, otherwise: bb17];
121+
_11 = discriminant((*_3));
122+
switchInt(move _11) -> [0: bb4, otherwise: bb17];
127123
}
128124

129125
bb23: {
130-
_14 = discriminant((*_3));
131-
switchInt(move _14) -> [0: bb10, otherwise: bb19];
126+
_12 = discriminant((*_3));
127+
switchInt(move _12) -> [0: bb10, otherwise: bb19];
132128
}
133129

134130
bb24: {
135-
StorageDead(_15);
131+
StorageDead(_13);
136132
goto -> bb21;
137133
}
138134

139135
bb25: {
140-
StorageDead(_15);
136+
StorageDead(_13);
141137
goto -> bb23;
142138
}
143139

144140
bb26 (cleanup): {
145-
StorageDead(_15);
141+
StorageDead(_13);
146142
goto -> bb22;
147143
}
148144

149145
bb27: {
150-
async drop((*_3); poll=_15) -> [return: bb24, unwind: bb26, drop: bb25];
146+
async drop((*_3); poll=_13) -> [return: bb24, unwind: bb26, drop: bb25];
151147
}
152148

153149
bb28: {
154-
StorageLive(_15);
155-
_15 = <AsyncEnum as AsyncDrop>::drop(move _17) -> [return: bb27, unwind: bb26];
150+
StorageLive(_13);
151+
_13 = <AsyncEnum as AsyncDrop>::drop(move _14) -> [return: bb27, unwind: bb26];
156152
}
157153

158154
bb29: {
159-
_16 = &mut (*_3);
160-
_17 = Pin::<&mut AsyncEnum>::new_unchecked(move _16) -> [return: bb28, unwind: bb22];
155+
_15 = &mut (*_3);
156+
_14 = Pin::<&mut AsyncEnum>::new_unchecked(move _15) -> [return: bb28, unwind: bb22];
161157
}
162158
}

0 commit comments

Comments
 (0)