Skip to content

Commit 26b62b2

Browse files
Extract borrowck coroutine drop-liveness hack
1 parent 61f4528 commit 26b62b2

File tree

2 files changed

+20
-20
lines changed

2 files changed

+20
-20
lines changed

compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
318318
})
319319
}
320320

321-
ty::Coroutine(_, args) => {
321+
ty::Coroutine(def_id, args) => {
322322
// rust-lang/rust#49918: Locals can be stored across await points in the coroutine,
323323
// called interior/witness types. Since we do not compute these witnesses until after
324324
// building MIR, we consider all coroutines to unconditionally require a drop during
@@ -344,8 +344,9 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
344344
// redundant. There is no storage for the resume type, so if it is actually stored
345345
// in the interior, we'll already detect the need for a drop by checking the witness.
346346
let typing_env = tcx.erase_regions(typing_env);
347-
let needs_drop = args.witness().needs_drop(tcx, typing_env)
348-
|| args.upvar_tys().iter().any(|ty| ty.needs_drop(tcx, typing_env));
347+
let needs_drop = tcx.mir_coroutine_witnesses(def_id).is_some_and(|witness| {
348+
witness.field_tys.iter().any(|field| field.ty.needs_drop(tcx, typing_env))
349+
}) || args.upvar_tys().iter().any(|ty| ty.needs_drop(tcx, typing_env));
349350
if needs_drop {
350351
constraints.outlives.extend(args.upvar_tys().iter().map(ty::GenericArg::from));
351352
constraints.outlives.push(args.resume_ty().into());

compiler/rustc_ty_utils/src/needs_drop.rs

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,6 @@ fn has_significant_drop_raw<'tcx>(
101101
struct NeedsDropTypes<'tcx, F> {
102102
tcx: TyCtxt<'tcx>,
103103
typing_env: ty::TypingEnv<'tcx>,
104-
/// Whether to reveal coroutine witnesses, this is set
105-
/// to `false` unless we compute `needs_drop` for a coroutine witness.
106-
reveal_coroutine_witnesses: bool,
107104
query_ty: Ty<'tcx>,
108105
seen_tys: FxHashSet<Ty<'tcx>>,
109106
/// A stack of types left to process, and the recursion depth when we
@@ -131,7 +128,6 @@ impl<'tcx, F> NeedsDropTypes<'tcx, F> {
131128
Self {
132129
tcx,
133130
typing_env,
134-
reveal_coroutine_witnesses: exhaustive,
135131
seen_tys,
136132
query_ty: ty,
137133
unchecked_tys: vec![(ty, 0)],
@@ -195,23 +191,26 @@ where
195191
// for the coroutine witness and check whether any of the contained types
196192
// need to be dropped, and only require the captured types to be live
197193
// if they do.
198-
ty::Coroutine(_, args) => {
199-
if self.reveal_coroutine_witnesses {
200-
queue_type(self, args.as_coroutine().witness());
194+
ty::Coroutine(def_id, args) => {
195+
if self.exhaustive {
196+
for upvar in args.as_coroutine().upvar_tys() {
197+
queue_type(self, upvar);
198+
}
199+
queue_type(self, args.as_coroutine().resume_ty());
200+
if let Some(witness) = tcx.mir_coroutine_witnesses(def_id) {
201+
for field_ty in &witness.field_tys {
202+
queue_type(
203+
self,
204+
EarlyBinder::bind(field_ty.ty).instantiate(tcx, args),
205+
);
206+
}
207+
}
201208
} else {
202209
return Some(self.always_drop_component(ty));
203210
}
204211
}
205-
ty::CoroutineWitness(def_id, args) => {
206-
if let Some(witness) = tcx.mir_coroutine_witnesses(def_id) {
207-
self.reveal_coroutine_witnesses = true;
208-
for field_ty in &witness.field_tys {
209-
queue_type(
210-
self,
211-
EarlyBinder::bind(field_ty.ty).instantiate(tcx, args),
212-
);
213-
}
214-
}
212+
ty::CoroutineWitness(..) => {
213+
unreachable!("witness should be handled in parent");
215214
}
216215

217216
ty::UnsafeBinder(bound_ty) => {

0 commit comments

Comments
 (0)