Skip to content

Commit a86564d

Browse files
Extract borrowck coroutine drop-liveness hack
1 parent 8c43399 commit a86564d

File tree

2 files changed

+21
-19
lines changed

2 files changed

+21
-19
lines changed

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

Lines changed: 5 additions & 2 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: types can be constructed, stored
323323
// in the interior, and sit idle when coroutine yields
324324
// (and is subsequently dropped).
@@ -346,7 +346,10 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
346346
// While we conservatively assume that all coroutines require drop
347347
// to avoid query cycles during MIR building, we can check the actual
348348
// witness during borrowck to avoid unnecessary liveness constraints.
349-
if args.witness().needs_drop(tcx, tcx.erase_regions(typing_env)) {
349+
let typing_env = tcx.erase_regions(typing_env);
350+
if tcx.mir_coroutine_witnesses(def_id).is_some_and(|witness| {
351+
witness.field_tys.iter().any(|field| field.ty.needs_drop(tcx, typing_env))
352+
}) {
350353
constraints.outlives.extend(args.upvar_tys().iter().map(ty::GenericArg::from));
351354
constraints.outlives.push(args.resume_ty().into());
352355
}

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)