Skip to content

Commit b67bb92

Browse files
Fast path for subtype and coercion goals
1 parent 6f69710 commit b67bb92

File tree

4 files changed

+32
-16
lines changed

4 files changed

+32
-16
lines changed

compiler/rustc_next_trait_solver/src/delegate.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ use std::ops::Deref;
33
use rustc_type_ir::solve::{Certainty, Goal, NoSolution};
44
use rustc_type_ir::{self as ty, InferCtxtLike, Interner, TypeFoldable};
55

6-
use crate::solve::HasChanged;
7-
86
pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
97
type Infcx: InferCtxtLike<Interner = Self::Interner>;
108
type Interner: Interner;
@@ -23,7 +21,7 @@ pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
2321
&self,
2422
goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
2523
span: <Self::Interner as Interner>::Span,
26-
) -> Option<HasChanged>;
24+
) -> Option<Certainty>;
2725

2826
fn fresh_var_for_kind_with_span(
2927
&self,

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -671,10 +671,13 @@ where
671671
// If this loop did not result in any progress, what's our final certainty.
672672
let mut unchanged_certainty = Some(Certainty::Yes);
673673
for (source, goal, stalled_on) in mem::take(&mut self.nested_goals) {
674-
if let Some(has_changed) = self.delegate.compute_goal_fast_path(goal, self.origin_span)
675-
{
676-
if matches!(has_changed, HasChanged::Yes) {
677-
unchanged_certainty = None;
674+
if let Some(certainty) = self.delegate.compute_goal_fast_path(goal, self.origin_span) {
675+
match certainty {
676+
Certainty::Yes => {}
677+
Certainty::Maybe(_) => {
678+
self.nested_goals.push((source, goal, None));
679+
unchanged_certainty = unchanged_certainty.map(|c| c.and(certainty));
680+
}
678681
}
679682
continue;
680683
}

compiler/rustc_trait_selection/src/solve/delegate.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use rustc_infer::traits::solve::Goal;
1212
use rustc_middle::traits::query::NoSolution;
1313
use rustc_middle::traits::solve::Certainty;
1414
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitableExt as _, TypingMode};
15-
use rustc_next_trait_solver::solve::HasChanged;
1615
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
1716

1817
use crate::traits::{EvaluateConstErr, ObligationCause, specialization_graph};
@@ -61,19 +60,19 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
6160
&self,
6261
goal: Goal<'tcx, ty::Predicate<'tcx>>,
6362
span: Span,
64-
) -> Option<HasChanged> {
63+
) -> Option<Certainty> {
6564
let pred = goal.predicate.kind();
6665
match pred.no_bound_vars()? {
6766
ty::PredicateKind::DynCompatible(def_id) if self.0.tcx.is_dyn_compatible(def_id) => {
68-
Some(HasChanged::No)
67+
Some(Certainty::Yes)
6968
}
7069
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(outlives)) => {
7170
self.0.sub_regions(
7271
SubregionOrigin::RelateRegionParamBound(span, None),
7372
outlives.1,
7473
outlives.0,
7574
);
76-
Some(HasChanged::No)
75+
Some(Certainty::Yes)
7776
}
7877
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(outlives)) => {
7978
self.0.register_type_outlives_constraint(
@@ -82,23 +81,34 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
8281
&ObligationCause::dummy_with_span(span),
8382
);
8483

85-
Some(HasChanged::No)
84+
Some(Certainty::Yes)
8685
}
8786
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) => {
8887
match self.0.tcx.as_lang_item(trait_pred.def_id()) {
8988
Some(LangItem::Sized)
9089
if trait_pred.self_ty().is_trivially_sized(self.0.tcx) =>
9190
{
92-
Some(HasChanged::No)
91+
Some(Certainty::Yes)
9392
}
9493
Some(LangItem::Copy | LangItem::Clone)
9594
if trait_pred.self_ty().is_trivially_pure_clone_copy() =>
9695
{
97-
Some(HasChanged::No)
96+
Some(Certainty::Yes)
9897
}
9998
_ => None,
10099
}
101100
}
101+
ty::PredicateKind::Subtype(ty::SubtypePredicate { a, b, .. })
102+
| ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) => {
103+
if self.shallow_resolve(a).is_ty_var() && self.shallow_resolve(b).is_ty_var() {
104+
// FIXME: We also need to register a subtype relation between these vars
105+
// when those are added, and if they aren't in the same sub root then
106+
// we should mark this goal as `has_changed`.
107+
Some(Certainty::AMBIGUOUS)
108+
} else {
109+
None
110+
}
111+
}
102112
_ => None,
103113
}
104114
}

compiler/rustc_trait_selection/src/solve/fulfill.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,15 @@ where
195195

196196
let goal = obligation.as_goal();
197197
let delegate = <&SolverDelegate<'tcx>>::from(infcx);
198-
if let Some(fast_path_has_changed) =
198+
if let Some(certainty) =
199199
delegate.compute_goal_fast_path(goal, obligation.cause.span)
200200
{
201-
any_changed |= matches!(fast_path_has_changed, HasChanged::Yes);
201+
match certainty {
202+
Certainty::Yes => {}
203+
Certainty::Maybe(_) => {
204+
self.obligations.register(obligation, None);
205+
}
206+
}
202207
continue;
203208
}
204209

0 commit comments

Comments
 (0)