Skip to content

Commit 0b7ded5

Browse files
More
1 parent 7c1661f commit 0b7ded5

File tree

19 files changed

+142
-162
lines changed

19 files changed

+142
-162
lines changed

compiler/rustc_infer/src/infer/mod.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -967,7 +967,9 @@ impl<'tcx> InferCtxt<'tcx> {
967967
pub fn can_define_opaque_ty(&self, id: impl Into<DefId>) -> bool {
968968
debug_assert!(!self.next_trait_solver());
969969
match self.typing_mode() {
970-
TypingMode::Analysis { defining_opaque_types, stalled_generators: _ }
970+
TypingMode::Analysis {
971+
defining_opaque_types_and_generators: defining_opaque_types,
972+
}
971973
| TypingMode::Borrowck { defining_opaque_types } => {
972974
id.into().as_local().is_some_and(|def_id| defining_opaque_types.contains(&def_id))
973975
}
@@ -1262,7 +1264,7 @@ impl<'tcx> InferCtxt<'tcx> {
12621264
// to handle them without proper canonicalization. This means we may cause cycle
12631265
// errors and fail to reveal opaques while inside of bodies. We should rename this
12641266
// function and require explicit comments on all use-sites in the future.
1265-
ty::TypingMode::Analysis { defining_opaque_types: _, stalled_generators: _ }
1267+
ty::TypingMode::Analysis { defining_opaque_types_and_generators: _ }
12661268
| ty::TypingMode::Borrowck { defining_opaque_types: _ } => {
12671269
TypingMode::non_body_analysis()
12681270
}

compiler/rustc_middle/src/query/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ rustc_queries! {
391391
key: LocalDefId
392392
) -> &'tcx ty::List<LocalDefId> {
393393
desc {
394-
|tcx| "computing the opaque types defined by `{}`",
394+
|tcx| "computing the coroutines defined within `{}`",
395395
tcx.def_path_str(key.to_def_id())
396396
}
397397
}

compiler/rustc_middle/src/query/plumbing.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -366,11 +366,11 @@ macro_rules! define_callbacks {
366366

367367
pub type Storage<'tcx> = <$($K)* as keys::Key>::Cache<Erase<$V>>;
368368

369-
// Ensure that keys grow no larger than 96 bytes by accident.
369+
// Ensure that keys grow no larger than 88 bytes by accident.
370370
// Increase this limit if necessary, but do try to keep the size low if possible
371371
#[cfg(target_pointer_width = "64")]
372372
const _: () = {
373-
if size_of::<Key<'static>>() > 96 {
373+
if size_of::<Key<'static>>() > 88 {
374374
panic!("{}", concat!(
375375
"the query `",
376376
stringify!($name),

compiler/rustc_middle/src/ty/context.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -678,11 +678,18 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
678678
self.opaque_types_defined_by(defining_anchor)
679679
}
680680

681-
fn stalled_generators_within(self, defining_anchor: Self::LocalDefId) -> Self::LocalDefIds {
681+
fn opaque_types_and_generators_defined_by(
682+
self,
683+
defining_anchor: Self::LocalDefId,
684+
) -> Self::LocalDefIds {
682685
if self.next_trait_solver_globally() {
683-
self.stalled_generators_within(defining_anchor)
686+
self.mk_local_def_ids_from_iter(
687+
self.opaque_types_defined_by(defining_anchor)
688+
.iter()
689+
.chain(self.stalled_generators_within(defining_anchor)),
690+
)
684691
} else {
685-
ty::List::empty()
692+
self.opaque_types_defined_by(defining_anchor)
686693
}
687694
}
688695
}
@@ -2914,11 +2921,11 @@ impl<'tcx> TyCtxt<'tcx> {
29142921
self.interners.intern_clauses(clauses)
29152922
}
29162923

2917-
pub fn mk_local_def_ids(self, clauses: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2924+
pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
29182925
// FIXME consider asking the input slice to be sorted to avoid
29192926
// re-interning permutations, in which case that would be asserted
29202927
// here.
2921-
self.intern_local_def_ids(clauses)
2928+
self.intern_local_def_ids(def_ids)
29222929
}
29232930

29242931
pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output

compiler/rustc_next_trait_solver/src/solve/mod.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -329,10 +329,7 @@ where
329329
TypingMode::Coherence | TypingMode::PostAnalysis => false,
330330
// During analysis, opaques are rigid unless they may be defined by
331331
// the current body.
332-
TypingMode::Analysis {
333-
defining_opaque_types: non_rigid_opaques,
334-
stalled_generators: _,
335-
}
332+
TypingMode::Analysis { defining_opaque_types_and_generators: non_rigid_opaques }
336333
| TypingMode::Borrowck { defining_opaque_types: non_rigid_opaques }
337334
| TypingMode::PostBorrowckAnalysis { defined_opaque_types: non_rigid_opaques } => {
338335
!def_id.as_local().is_some_and(|def_id| non_rigid_opaques.contains(&def_id))

compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ where
3333
);
3434
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
3535
}
36-
TypingMode::Analysis { defining_opaque_types, stalled_generators: _ } => {
36+
TypingMode::Analysis { defining_opaque_types_and_generators } => {
3737
let Some(def_id) = opaque_ty
3838
.def_id
3939
.as_local()
40-
.filter(|&def_id| defining_opaque_types.contains(&def_id))
40+
.filter(|&def_id| defining_opaque_types_and_generators.contains(&def_id))
4141
else {
4242
self.structurally_instantiate_normalizes_to_term(goal, goal.predicate.alias);
4343
return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);

compiler/rustc_next_trait_solver/src/solve/trait_goals.rs

+30-28
Original file line numberDiff line numberDiff line change
@@ -208,20 +208,9 @@ where
208208
}
209209
}
210210

211-
// TODO:
212-
if let ty::CoroutineWitness(def_id, _) = goal.predicate.self_ty().kind() {
213-
match ecx.typing_mode() {
214-
TypingMode::Analysis { stalled_generators, defining_opaque_types: _ } => {
215-
if def_id.as_local().is_some_and(|def_id| stalled_generators.contains(&def_id))
216-
{
217-
return ecx.forced_ambiguity(MaybeCause::Ambiguity);
218-
}
219-
}
220-
TypingMode::Coherence
221-
| TypingMode::PostAnalysis
222-
| TypingMode::Borrowck { defining_opaque_types: _ }
223-
| TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ } => {}
224-
}
211+
// We need to make sure to stall any coroutines we are inferring to avoid query cycles.
212+
if let Some(cand) = ecx.try_stall_coroutine_witness(goal.predicate.self_ty()) {
213+
return cand;
225214
}
226215

227216
ecx.probe_and_evaluate_goal_for_constituent_tys(
@@ -275,20 +264,9 @@ where
275264
return Err(NoSolution);
276265
}
277266

278-
// TODO:
279-
if let ty::CoroutineWitness(def_id, _) = goal.predicate.self_ty().kind() {
280-
match ecx.typing_mode() {
281-
TypingMode::Analysis { stalled_generators, defining_opaque_types: _ } => {
282-
if def_id.as_local().is_some_and(|def_id| stalled_generators.contains(&def_id))
283-
{
284-
return ecx.forced_ambiguity(MaybeCause::Ambiguity);
285-
}
286-
}
287-
TypingMode::Coherence
288-
| TypingMode::PostAnalysis
289-
| TypingMode::Borrowck { defining_opaque_types: _ }
290-
| TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ } => {}
291-
}
267+
// We need to make sure to stall any coroutines we are inferring to avoid query cycles.
268+
if let Some(cand) = ecx.try_stall_coroutine_witness(goal.predicate.self_ty()) {
269+
return cand;
292270
}
293271

294272
ecx.probe_and_evaluate_goal_for_constituent_tys(
@@ -1400,4 +1378,28 @@ where
14001378
let candidates = self.assemble_and_evaluate_candidates(goal, AssembleCandidatesFrom::All);
14011379
self.merge_trait_candidates(goal, candidates)
14021380
}
1381+
1382+
fn try_stall_coroutine_witness(
1383+
&mut self,
1384+
self_ty: I::Ty,
1385+
) -> Option<Result<Candidate<I>, NoSolution>> {
1386+
if let ty::CoroutineWitness(def_id, _) = self_ty.kind() {
1387+
match self.typing_mode() {
1388+
TypingMode::Analysis {
1389+
defining_opaque_types_and_generators: stalled_generators,
1390+
} => {
1391+
if def_id.as_local().is_some_and(|def_id| stalled_generators.contains(&def_id))
1392+
{
1393+
return Some(self.forced_ambiguity(MaybeCause::Ambiguity));
1394+
}
1395+
}
1396+
TypingMode::Coherence
1397+
| TypingMode::PostAnalysis
1398+
| TypingMode::Borrowck { defining_opaque_types: _ }
1399+
| TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ } => {}
1400+
}
1401+
}
1402+
1403+
None
1404+
}
14031405
}

compiler/rustc_trait_selection/src/solve/fulfill.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use rustc_middle::ty::{
1414
};
1515
use rustc_next_trait_solver::solve::{GenerateProofTree, HasChanged, SolverDelegateEvalExt as _};
1616
use rustc_span::Span;
17+
use rustc_type_ir::data_structures::DelayedSet;
1718
use tracing::instrument;
1819

1920
use self::derive_errors::*;
@@ -219,8 +220,8 @@ where
219220
) -> PredicateObligations<'tcx> {
220221
self.obligations.drain_pending(|obl| {
221222
let stalled_generators = match infcx.typing_mode() {
222-
TypingMode::Analysis { defining_opaque_types: _, stalled_generators } => {
223-
stalled_generators
223+
TypingMode::Analysis { defining_opaque_types_and_generators } => {
224+
defining_opaque_types_and_generators
224225
}
225226
TypingMode::Coherence
226227
| TypingMode::Borrowck { defining_opaque_types: _ }
@@ -236,7 +237,11 @@ where
236237
infcx
237238
.visit_proof_tree(
238239
obl.as_goal(),
239-
&mut StalledOnCoroutines { stalled_generators, span: obl.cause.span },
240+
&mut StalledOnCoroutines {
241+
stalled_generators,
242+
span: obl.cause.span,
243+
cache: Default::default(),
244+
},
240245
)
241246
.is_break()
242247
})
@@ -247,7 +252,7 @@ where
247252
struct StalledOnCoroutines<'tcx> {
248253
stalled_generators: &'tcx ty::List<LocalDefId>,
249254
span: Span,
250-
// TODO: Cache
255+
cache: DelayedSet<Ty<'tcx>>,
251256
}
252257

253258
impl<'tcx> inspect::ProofTreeVisitor<'tcx> for StalledOnCoroutines<'tcx> {
@@ -272,6 +277,10 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for StalledOnCoroutines<'tcx> {
272277
type Result = ControlFlow<()>;
273278

274279
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
280+
if !self.cache.insert(ty) {
281+
return ControlFlow::Continue(());
282+
}
283+
275284
if let ty::CoroutineWitness(def_id, _) = *ty.kind()
276285
&& def_id.as_local().is_some_and(|def_id| self.stalled_generators.contains(&def_id))
277286
{

compiler/rustc_trait_selection/src/solve/normalize.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ where
6060
/// entered before passing `value` to the function. This is currently needed for
6161
/// `normalize_erasing_regions`, which skips binders as it walks through a type.
6262
///
63-
/// TODO: doc
63+
/// This returns a set of stalled obligations if the typing mode of the underlying infcx
64+
/// has any stalled coroutine def ids.
6465
pub fn deeply_normalize_with_skipped_universes_and_ambiguous_goals<'tcx, T, E>(
6566
at: At<'_, 'tcx>,
6667
value: T,

compiler/rustc_trait_selection/src/traits/select/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1498,7 +1498,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
14981498
// However, if we disqualify *all* goals from being cached, perf suffers.
14991499
// This is likely fixed by better caching in general in the new solver.
15001500
// See: <https://github.com/rust-lang/rust/issues/132064>.
1501-
TypingMode::Analysis { defining_opaque_types, stalled_generators: _ }
1501+
TypingMode::Analysis {
1502+
defining_opaque_types_and_generators: defining_opaque_types,
1503+
}
15021504
| TypingMode::Borrowck { defining_opaque_types } => {
15031505
defining_opaque_types.is_empty() || !pred.has_opaque_types()
15041506
}

compiler/rustc_ty_utils/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ mod needs_drop;
3232
mod opaque_types;
3333
mod representability;
3434
pub mod sig_types;
35+
mod stalled_generators;
3536
mod structural_match;
3637
mod ty;
3738

@@ -50,4 +51,5 @@ pub fn provide(providers: &mut Providers) {
5051
ty::provide(providers);
5152
instance::provide(providers);
5253
structural_match::provide(providers);
54+
stalled_generators::provide(providers);
5355
}

compiler/rustc_ty_utils/src/opaque_types.rs

+2-48
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use rustc_data_structures::fx::FxHashSet;
2-
use rustc_hir as hir;
32
use rustc_hir::def::DefKind;
4-
use rustc_hir::def_id::{DefId, LocalDefId};
3+
use rustc_hir::def_id::LocalDefId;
54
use rustc_hir::intravisit;
65
use rustc_hir::intravisit::Visitor;
76
use rustc_middle::query::Providers;
@@ -356,51 +355,6 @@ fn opaque_types_defined_by<'tcx>(
356355
tcx.mk_local_def_ids(&collector.opaques)
357356
}
358357

359-
// TODO: Move this out of `opaque_types`
360-
fn stalled_generators_within<'tcx>(
361-
tcx: TyCtxt<'tcx>,
362-
item: LocalDefId,
363-
) -> &'tcx ty::List<LocalDefId> {
364-
if !tcx.next_trait_solver_globally() {
365-
return ty::List::empty();
366-
}
367-
368-
let body = tcx.hir_body_owned_by(item);
369-
let mut collector =
370-
StalledGeneratorVisitor { tcx, root_def_id: item.to_def_id(), stalled_coroutines: vec![] };
371-
collector.visit_body(body);
372-
tcx.mk_local_def_ids(&collector.stalled_coroutines)
373-
}
374-
375-
struct StalledGeneratorVisitor<'tcx> {
376-
tcx: TyCtxt<'tcx>,
377-
root_def_id: DefId,
378-
stalled_coroutines: Vec<LocalDefId>,
379-
}
380-
381-
impl<'tcx> Visitor<'tcx> for StalledGeneratorVisitor<'tcx> {
382-
fn visit_nested_body(&mut self, id: hir::BodyId) {
383-
if self.tcx.typeck_root_def_id(self.tcx.hir_body_owner_def_id(id).to_def_id())
384-
== self.root_def_id
385-
{
386-
let body = self.tcx.hir_body(id);
387-
self.visit_body(body);
388-
}
389-
}
390-
391-
fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
392-
if let hir::ExprKind::Closure(&hir::Closure {
393-
def_id,
394-
kind: hir::ClosureKind::Coroutine(_),
395-
..
396-
}) = ex.kind
397-
{
398-
self.stalled_coroutines.push(def_id);
399-
}
400-
intravisit::walk_expr(self, ex);
401-
}
402-
}
403-
404358
pub(super) fn provide(providers: &mut Providers) {
405-
*providers = Providers { opaque_types_defined_by, stalled_generators_within, ..*providers };
359+
*providers = Providers { opaque_types_defined_by, ..*providers };
406360
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
use rustc_hir as hir;
2+
use rustc_hir::def_id::{DefId, LocalDefId};
3+
use rustc_hir::intravisit;
4+
use rustc_hir::intravisit::Visitor;
5+
use rustc_middle::query::Providers;
6+
use rustc_middle::ty::{self, TyCtxt};
7+
8+
fn stalled_generators_within<'tcx>(
9+
tcx: TyCtxt<'tcx>,
10+
item: LocalDefId,
11+
) -> &'tcx ty::List<LocalDefId> {
12+
if !tcx.next_trait_solver_globally() {
13+
return ty::List::empty();
14+
}
15+
16+
let body = tcx.hir_body_owned_by(item);
17+
let mut collector =
18+
StalledGeneratorVisitor { tcx, root_def_id: item.to_def_id(), stalled_coroutines: vec![] };
19+
collector.visit_body(body);
20+
tcx.mk_local_def_ids(&collector.stalled_coroutines)
21+
}
22+
23+
struct StalledGeneratorVisitor<'tcx> {
24+
tcx: TyCtxt<'tcx>,
25+
root_def_id: DefId,
26+
stalled_coroutines: Vec<LocalDefId>,
27+
}
28+
29+
impl<'tcx> Visitor<'tcx> for StalledGeneratorVisitor<'tcx> {
30+
fn visit_nested_body(&mut self, id: hir::BodyId) {
31+
if self.tcx.typeck_root_def_id(self.tcx.hir_body_owner_def_id(id).to_def_id())
32+
== self.root_def_id
33+
{
34+
let body = self.tcx.hir_body(id);
35+
self.visit_body(body);
36+
}
37+
}
38+
39+
fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
40+
if let hir::ExprKind::Closure(&hir::Closure {
41+
def_id,
42+
kind: hir::ClosureKind::Coroutine(_),
43+
..
44+
}) = ex.kind
45+
{
46+
self.stalled_coroutines.push(def_id);
47+
}
48+
intravisit::walk_expr(self, ex);
49+
}
50+
}
51+
52+
pub(super) fn provide(providers: &mut Providers) {
53+
*providers = Providers { stalled_generators_within, ..*providers };
54+
}

0 commit comments

Comments
 (0)