Skip to content

Commit 34d1ae2

Browse files
committed
Simplify build_adrop_for_coroutine_shim.
1 parent c2e44e3 commit 34d1ae2

2 files changed

Lines changed: 66 additions & 101 deletions

File tree

compiler/rustc_mir_transform/src/shim.rs

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -30,40 +30,6 @@ pub(super) fn provide(providers: &mut Providers) {
3030
providers.mir_shims = make_shim;
3131
}
3232

33-
// Replace Pin<&mut ImplCoroutine> accesses (_1.0) into Pin<&mut ProxyCoroutine> accesses
34-
struct FixProxyFutureDropVisitor<'tcx> {
35-
tcx: TyCtxt<'tcx>,
36-
replace_to: Local,
37-
}
38-
39-
impl<'tcx> MutVisitor<'tcx> for FixProxyFutureDropVisitor<'tcx> {
40-
fn tcx(&self) -> TyCtxt<'tcx> {
41-
self.tcx
42-
}
43-
44-
fn visit_place(
45-
&mut self,
46-
place: &mut Place<'tcx>,
47-
_context: PlaceContext,
48-
_location: Location,
49-
) {
50-
if place.local == Local::from_u32(1) {
51-
if place.projection.len() == 1 {
52-
assert!(matches!(
53-
place.projection.first(),
54-
Some(ProjectionElem::Field(FieldIdx::ZERO, _))
55-
));
56-
*place = Place::from(self.replace_to);
57-
} else if place.projection.len() == 2 {
58-
assert!(matches!(place.projection[0], ProjectionElem::Field(FieldIdx::ZERO, _)));
59-
assert!(matches!(place.projection[1], ProjectionElem::Deref));
60-
*place =
61-
Place::from(self.replace_to).project_deeper(&[ProjectionElem::Deref], self.tcx);
62-
}
63-
}
64-
}
65-
}
66-
6733
fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body<'tcx> {
6834
debug!("make_shim({:?})", instance);
6935

compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs

Lines changed: 66 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ use super::*;
1212
use crate::deref_separator::deref_finder;
1313
use crate::patch::MirPatch;
1414

15+
const SELF_ARG: Local = Local::arg(0);
16+
1517
pub(super) fn build_async_destructor_ctor_shim<'tcx>(
1618
tcx: TyCtxt<'tcx>,
1719
def_id: DefId,
@@ -76,7 +78,7 @@ pub(super) fn build_async_drop_shim<'tcx>(
7678
let source_info = SourceInfo::outermost(span);
7779

7880
// The first argument (index 0) which will be local 1 (after the return value).
79-
let coroutine_layout = Place::from(Local::arg(0));
81+
let coroutine_layout = Place::from(SELF_ARG);
8082
let coroutine_layout_dropee =
8183
tcx.mk_place_field(coroutine_layout, FieldIdx::new(0), drop_ptr_ty);
8284

@@ -199,87 +201,85 @@ fn build_adrop_for_coroutine_shim<'tcx>(
199201
let ty::Coroutine(coroutine_def_id, impl_args) = impl_ty.kind() else {
200202
bug!("build_adrop_for_coroutine_shim not for coroutine impl type: ({:?})", instance);
201203
};
202-
let proxy_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, proxy_ty);
203-
// taking _1.0 (impl from Pin)
204-
let pin_proxy_layout_local = Local::new(1);
205204
let source_info = SourceInfo::outermost(span);
206-
// converting `(_1: Pin<&mut CorLayout>, _2: &mut Context<'_>) -> Poll<()>`
207-
// into `(_1: Pin<&mut ProxyLayout>, _2: &mut Context<'_>) -> Poll<()>`
208-
// let mut _x: &mut CorLayout = &mut *_1.0.0;
209-
// Replace old _1.0 accesses into _x accesses;
210205
let body = tcx.optimized_mir(*coroutine_def_id).future_drop_poll().unwrap();
211206
let mut body: Body<'tcx> =
212207
EarlyBinder::bind(body.clone()).instantiate(tcx, impl_args).skip_norm_wip();
213208
body.source.instance = instance;
214209
body.phase = MirPhase::Runtime(RuntimePhase::Initial);
215210
body.var_debug_info.clear();
211+
212+
// converting `(_1: Pin<&mut CorLayout>, _2: &mut Context<'_>) -> Poll<()>`
213+
// into `(_1: Pin<&mut ProxyLayout>, _2: &mut Context<'_>) -> Poll<()>`
214+
// let mut _x: &mut CorLayout = &mut *_1.0.0;
215+
// Replace old _1.0 accesses into _x accesses;
216+
let proxy_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, proxy_ty);
217+
216218
let pin_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, span));
217219
let args = tcx.mk_args(&[proxy_ref.into()]);
218220
let pin_proxy_ref = Ty::new_adt(tcx, pin_adt_ref, args);
219221

220222
let cor_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, impl_ty);
221-
222-
let proxy_ref_local = body.local_decls.push(LocalDecl::new(proxy_ref, span));
223223
let cor_ref_local = body.local_decls.push(LocalDecl::new(cor_ref, span));
224224

225225
FixProxyFutureDropVisitor { tcx, replace_to: cor_ref_local }.visit_body(&mut body);
226+
226227
// Now changing first arg from Pin<&mut ImplCoroutine> to Pin<&mut ProxyCoroutine>
227-
body.local_decls[pin_proxy_layout_local] = LocalDecl::new(pin_proxy_ref, span);
228-
229-
{
230-
let mut idx: usize = 0;
231-
// _proxy = _1.0 : Pin<&mut ProxyLayout> ==> &mut ProxyLayout
232-
let proxy_ref_place = Place::from(pin_proxy_layout_local)
233-
.project_deeper(&[PlaceElem::Field(FieldIdx::ZERO, proxy_ref)], tcx);
234-
body.basic_blocks_mut()[START_BLOCK].statements.insert(
235-
idx,
236-
Statement::new(
237-
source_info,
238-
StatementKind::Assign(Box::new((
239-
Place::from(proxy_ref_local),
240-
Rvalue::Use(Operand::Copy(proxy_ref_place), WithRetag::Yes),
241-
))),
242-
),
243-
);
244-
idx += 1;
245-
246-
// _cor_ref_tmp = (*(*_proxy).0).0...
247-
let mut cor_ref_tmp_local = proxy_ref_local;
248-
proxy_ty.find_async_drop_impl_coroutine(tcx, |ty| {
249-
if ty != proxy_ty {
250-
let ty_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, ty);
251-
let impl_ptr_place = Place::from(cor_ref_tmp_local).project_deeper(
252-
&[PlaceElem::Deref, PlaceElem::Field(FieldIdx::ZERO, ty_ref)],
253-
tcx,
254-
);
255-
cor_ref_tmp_local = body.local_decls.push(LocalDecl::new(ty_ref, span));
256-
body.basic_blocks_mut()[START_BLOCK].statements.insert(
257-
idx,
258-
Statement::new(
259-
source_info,
260-
StatementKind::Assign(Box::new((
261-
Place::from(cor_ref_tmp_local),
262-
Rvalue::Use(Operand::Copy(impl_ptr_place), WithRetag::Yes),
263-
))),
264-
),
265-
);
266-
idx += 1;
267-
}
268-
});
228+
body.local_decls[SELF_ARG] = LocalDecl::new(pin_proxy_ref, span);
269229

270-
// _cor_ref = cor_ref_tmp
271-
body.basic_blocks_mut()[START_BLOCK].statements.insert(
272-
idx,
273-
Statement::new(
274-
source_info,
275-
StatementKind::Assign(Box::new((
276-
Place::from(cor_ref_local),
277-
Rvalue::Use(Operand::Move(Place::from(cor_ref_tmp_local)), WithRetag::Yes),
278-
))),
279-
),
280-
);
230+
// Build the projection to assign `cor_ref_local = _1.<projection>`.
231+
let mut pin_proxy_to_cor_projection = vec![
232+
// _1.0 : Pin<&mut ProxyLayout> ==> &mut ProxyLayout
233+
PlaceElem::Field(FieldIdx::ZERO, proxy_ref),
234+
];
235+
236+
// _cor_ref_tmp = (*(*_proxy).0).0...
237+
proxy_ty.find_async_drop_impl_coroutine(tcx, |ty| {
238+
if ty != proxy_ty {
239+
let ty_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, ty);
240+
pin_proxy_to_cor_projection.push(PlaceElem::Deref);
241+
pin_proxy_to_cor_projection.push(PlaceElem::Field(FieldIdx::ZERO, ty_ref));
242+
}
243+
});
244+
245+
// _cor_ref = cor_ref_tmp
246+
let projected_pin = Place::from(SELF_ARG).project_deeper(&pin_proxy_to_cor_projection, tcx);
247+
body.basic_blocks_mut()[START_BLOCK].statements.insert(
248+
0,
249+
Statement::new(
250+
source_info,
251+
StatementKind::Assign(Box::new((
252+
Place::from(cor_ref_local),
253+
Rvalue::Use(Operand::Move(projected_pin), WithRetag::Yes),
254+
))),
255+
),
256+
);
257+
258+
// We did not bother respectig deref separation, do it here.
259+
deref_finder(tcx, &mut body, false);
260+
261+
return body;
262+
263+
/// Replace Pin<&mut ImplCoroutine> accesses (_1.0) into Pin<&mut ProxyCoroutine> accesses
264+
struct FixProxyFutureDropVisitor<'tcx> {
265+
tcx: TyCtxt<'tcx>,
266+
replace_to: Local,
267+
}
268+
269+
impl<'tcx> MutVisitor<'tcx> for FixProxyFutureDropVisitor<'tcx> {
270+
fn tcx(&self) -> TyCtxt<'tcx> {
271+
self.tcx
272+
}
273+
274+
fn visit_place(&mut self, place: &mut Place<'tcx>, _: PlaceContext, _: Location) {
275+
if place.local == SELF_ARG
276+
&& let Some((first, rest)) = place.projection.split_first()
277+
{
278+
assert!(matches!(first, ProjectionElem::Field(FieldIdx::ZERO, _)));
279+
*place = Place::from(self.replace_to).project_deeper(rest, self.tcx);
280+
}
281+
}
281282
}
282-
body
283283
}
284284

285285
// When dropping async drop coroutine, we continue its execution.
@@ -294,9 +294,8 @@ fn build_adrop_for_adrop_shim<'tcx>(
294294
let source_info = SourceInfo::outermost(span);
295295
let proxy_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, proxy_ty);
296296
// taking _1.0 (impl from Pin)
297-
let pin_proxy_layout_local = Local::new(1);
298-
let proxy_ref_place = Place::from(pin_proxy_layout_local)
299-
.project_deeper(&[PlaceElem::Field(FieldIdx::ZERO, proxy_ref)], tcx);
297+
let proxy_ref_place =
298+
Place::from(SELF_ARG).project_deeper(&[PlaceElem::Field(FieldIdx::ZERO, proxy_ref)], tcx);
300299
let cor_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, impl_ty);
301300

302301
// ret_ty = `Poll<()>`

0 commit comments

Comments
 (0)