Skip to content

Commit 15ba27d

Browse files
committed
consider the sub_unification_table in stalled_on
1 parent 7ad23f4 commit 15ba27d

File tree

2 files changed

+33
-24
lines changed
  • compiler/rustc_next_trait_solver/src/solve

2 files changed

+33
-24
lines changed

compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -407,20 +407,21 @@ where
407407
// If we have run this goal before, and it was stalled, check that any of the goal's
408408
// args have changed. Otherwise, we don't need to re-run the goal because it'll remain
409409
// stalled, since it'll canonicalize the same way and evaluation is pure.
410-
if let Some(stalled_on) = stalled_on
411-
&& !stalled_on.stalled_vars.iter().any(|value| self.delegate.is_changed_arg(*value))
412-
&& !self
413-
.delegate
414-
.opaque_types_storage_num_entries()
415-
.needs_reevaluation(stalled_on.num_opaques)
410+
if let Some(GoalStalledOn { num_opaques, ref stalled_vars, ref sub_roots, stalled_cause }) =
411+
stalled_on
412+
&& !stalled_vars.iter().any(|value| self.delegate.is_changed_arg(*value))
413+
&& !sub_roots
414+
.iter()
415+
.any(|&vid| self.delegate.sub_unification_table_root_var(vid) != vid)
416+
&& !self.delegate.opaque_types_storage_num_entries().needs_reevaluation(num_opaques)
416417
{
417418
return Ok((
418419
NestedNormalizationGoals::empty(),
419420
GoalEvaluation {
420421
goal,
421-
certainty: Certainty::Maybe(stalled_on.stalled_cause),
422+
certainty: Certainty::Maybe(stalled_cause),
422423
has_changed: HasChanged::No,
423-
stalled_on: Some(stalled_on),
424+
stalled_on,
424425
},
425426
));
426427
}
@@ -476,16 +477,6 @@ where
476477
HasChanged::No => {
477478
let mut stalled_vars = orig_values;
478479

479-
// Remove the canonicalized universal vars, since we only care about stalled existentials.
480-
stalled_vars.retain(|arg| match arg.kind() {
481-
ty::GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Infer(_)),
482-
ty::GenericArgKind::Const(ct) => {
483-
matches!(ct.kind(), ty::ConstKind::Infer(_))
484-
}
485-
// Lifetimes can never stall goals.
486-
ty::GenericArgKind::Lifetime(_) => false,
487-
});
488-
489480
// Remove the unconstrained RHS arg, which is expected to have changed.
490481
if let Some(normalizes_to) = goal.predicate.as_normalizes_to() {
491482
let normalizes_to = normalizes_to.skip_binder();
@@ -497,6 +488,27 @@ where
497488
stalled_vars.swap_remove(idx);
498489
}
499490

491+
// Remove the canonicalized universal vars, since we only care about stalled existentials.
492+
let mut sub_roots = Vec::new();
493+
stalled_vars.retain(|arg| match arg.kind() {
494+
// Lifetimes can never stall goals.
495+
ty::GenericArgKind::Lifetime(_) => false,
496+
ty::GenericArgKind::Type(ty) => match ty.kind() {
497+
ty::Infer(ty::TyVar(vid)) => {
498+
sub_roots.push(self.delegate.sub_unification_table_root_var(vid));
499+
true
500+
}
501+
ty::Infer(_) => true,
502+
ty::Param(_) | ty::Placeholder(_) => false,
503+
_ => unreachable!("unexpected orig_value: {ty:?}"),
504+
},
505+
ty::GenericArgKind::Const(ct) => match ct.kind() {
506+
ty::ConstKind::Infer(_) => true,
507+
ty::ConstKind::Param(_) | ty::ConstKind::Placeholder(_) => false,
508+
_ => unreachable!("unexpected orig_value: {ct:?}"),
509+
},
510+
});
511+
500512
Some(GoalStalledOn {
501513
num_opaques: canonical_goal
502514
.canonical
@@ -505,6 +517,7 @@ where
505517
.opaque_types
506518
.len(),
507519
stalled_vars,
520+
sub_roots,
508521
stalled_cause,
509522
})
510523
}

compiler/rustc_next_trait_solver/src/solve/mod.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ mod trait_goals;
2424
use derive_where::derive_where;
2525
use rustc_type_ir::inherent::*;
2626
pub use rustc_type_ir::solve::*;
27-
use rustc_type_ir::{self as ty, Interner, TypingMode};
27+
use rustc_type_ir::{self as ty, Interner, TyVid, TypingMode};
2828
use tracing::instrument;
2929

3030
pub use self::eval_ctxt::{
@@ -418,11 +418,6 @@ pub struct GoalEvaluation<I: Interner> {
418418
pub has_changed: HasChanged,
419419
/// If the [`Certainty`] was `Maybe`, then keep track of whether the goal has changed
420420
/// before rerunning it.
421-
///
422-
/// We knowingly ignore the `sub_root` of our inference variables here. This means we
423-
/// may not reevaluate a goal even though a change to the `sub_root` could cause a goal
424-
/// to make progress. Tracking them adds additional complexity for an incredibly minor
425-
/// type inference improvement. We could look into properly handling this in the future.
426421
pub stalled_on: Option<GoalStalledOn<I>>,
427422
}
428423

@@ -431,6 +426,7 @@ pub struct GoalEvaluation<I: Interner> {
431426
pub struct GoalStalledOn<I: Interner> {
432427
pub num_opaques: usize,
433428
pub stalled_vars: Vec<I::GenericArg>,
429+
pub sub_roots: Vec<TyVid>,
434430
/// The cause that will be returned on subsequent evaluations if this goal remains stalled.
435431
pub stalled_cause: MaybeCause,
436432
}

0 commit comments

Comments
 (0)