Skip to content

Commit f22316c

Browse files
Experimental impl of a better way of handling coroutines in dtorck constraint
1 parent 6320b9e commit f22316c

File tree

5 files changed

+29
-21
lines changed

5 files changed

+29
-21
lines changed

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,10 +1267,12 @@ impl<'tcx> InferCtxt<'tcx> {
12671267
// to handle them without proper canonicalization. This means we may cause cycle
12681268
// errors and fail to reveal opaques while inside of bodies. We should rename this
12691269
// function and require explicit comments on all use-sites in the future.
1270-
ty::TypingMode::Analysis { defining_opaque_types_and_generators: _ }
1271-
| ty::TypingMode::Borrowck { defining_opaque_types: _ } => {
1270+
ty::TypingMode::Analysis { defining_opaque_types_and_generators: _ } => {
12721271
TypingMode::non_body_analysis()
12731272
}
1273+
ty::TypingMode::Borrowck { defining_opaque_types: _ } => {
1274+
TypingMode::Borrowck { defining_opaque_types: ty::List::empty() }
1275+
}
12741276
mode @ (ty::TypingMode::Coherence
12751277
| ty::TypingMode::PostBorrowckAnalysis { .. }
12761278
| ty::TypingMode::PostAnalysis) => mode,

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

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -345,12 +345,10 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
345345

346346
// While we conservatively assume that all coroutines require drop
347347
// to avoid query cycles during MIR building, we can be more precise
348-
// here and check the specific components of the coroutines. This
349-
// includes the witness types, upvars, *and* the resume ty.
350-
let typing_env = tcx.erase_regions(typing_env);
351-
let needs_drop = args.witness().needs_drop(tcx, typing_env)
352-
|| args.upvar_tys().iter().any(|ty| ty.needs_drop(tcx, typing_env))
353-
|| args.resume_ty().needs_drop(tcx, typing_env);
348+
// here by re-checking in a `TypingMode::Borrowck` environment. This
349+
// will recurse into the coroutine witness (which we can now access
350+
// without cycles).
351+
let needs_drop = ty.needs_drop(tcx, tcx.erase_regions(typing_env));
354352
if needs_drop {
355353
constraints.outlives.extend(args.upvar_tys().iter().map(ty::GenericArg::from));
356354
constraints.outlives.push(args.resume_ty().into());

compiler/rustc_traits/src/dropck_outlives.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ fn dropck_outlives<'tcx>(
2323
canonical_goal: CanonicalDropckOutlivesGoal<'tcx>,
2424
) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, DropckOutlivesResult<'tcx>>>, NoSolution> {
2525
debug!("dropck_outlives(goal={:#?})", canonical_goal);
26-
2726
tcx.infer_ctxt().enter_canonical_trait_query(&canonical_goal, |ocx, goal| {
2827
compute_dropck_outlives_inner(ocx, goal, DUMMY_SP)
2928
})

compiler/rustc_ty_utils/src/needs_drop.rs

Lines changed: 18 additions & 9 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)],
@@ -196,15 +192,28 @@ where
196192
// need to be dropped, and only require the captured types to be live
197193
// if they do.
198194
ty::Coroutine(_, args) => {
199-
if self.reveal_coroutine_witnesses {
200-
queue_type(self, args.as_coroutine().witness());
201-
} else {
202-
return Some(self.always_drop_component(ty));
195+
for arg in args.as_coroutine().upvar_tys() {
196+
queue_type(self, arg);
197+
}
198+
queue_type(self, args.as_coroutine().resume_ty());
199+
match self.typing_env.typing_mode {
200+
ty::TypingMode::Coherence => {
201+
unreachable!("coherence should not be considering drops")
202+
}
203+
ty::TypingMode::Analysis { .. } => {
204+
return Some(
205+
self.always_drop_component(args.as_coroutine().witness()),
206+
);
207+
}
208+
ty::TypingMode::Borrowck { .. }
209+
| ty::TypingMode::PostBorrowckAnalysis { .. }
210+
| ty::TypingMode::PostAnalysis => {
211+
queue_type(self, args.as_coroutine().witness());
212+
}
203213
}
204214
}
205215
ty::CoroutineWitness(def_id, args) => {
206216
if let Some(witness) = tcx.mir_coroutine_witnesses(def_id) {
207-
self.reveal_coroutine_witnesses = true;
208217
for field_ty in &witness.field_tys {
209218
queue_type(
210219
self,

compiler/rustc_type_ir/src/infer_ctxt.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,11 @@ impl<I: Interner> TypingMode<I> {
117117
}
118118

119119
pub fn borrowck(cx: I, body_def_id: I::LocalDefId) -> TypingMode<I> {
120-
let defining_opaque_types = cx.opaque_types_defined_by(body_def_id);
121-
if defining_opaque_types.is_empty() {
120+
// N.B. we can only use an analysis env if there are no coroutines defined.
121+
if cx.opaque_types_and_coroutines_defined_by(body_def_id).is_empty() {
122122
TypingMode::non_body_analysis()
123123
} else {
124-
TypingMode::Borrowck { defining_opaque_types }
124+
TypingMode::Borrowck { defining_opaque_types: cx.opaque_types_defined_by(body_def_id) }
125125
}
126126
}
127127

0 commit comments

Comments
 (0)