Skip to content

Commit ba651ad

Browse files
Auto merge of #146759 - lcnr:obligations_for_self_ty-perf, r=<try>
obligations_for_self_ty: skip irrelevant goals
2 parents 2f4dfc7 + 452fdbf commit ba651ad

File tree

4 files changed

+66
-10
lines changed

4 files changed

+66
-10
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3737
) -> bool {
3838
match predicate.kind().skip_binder() {
3939
ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
40-
self.type_matches_expected_vid(expected_vid, data.self_ty())
40+
self.type_matches_expected_vid(data.self_ty(), expected_vid)
4141
}
4242
ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => {
43-
self.type_matches_expected_vid(expected_vid, data.projection_term.self_ty())
43+
self.type_matches_expected_vid(data.projection_term.self_ty(), expected_vid)
4444
}
4545
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
4646
| ty::PredicateKind::Subtype(..)
@@ -60,7 +60,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
6060
}
6161

6262
#[instrument(level = "debug", skip(self), ret)]
63-
fn type_matches_expected_vid(&self, expected_vid: ty::TyVid, ty: Ty<'tcx>) -> bool {
63+
fn type_matches_expected_vid(&self, ty: Ty<'tcx>, expected_vid: ty::TyVid) -> bool {
6464
let ty = self.shallow_resolve(ty);
6565
debug!(?ty);
6666

@@ -76,7 +76,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
7676
&self,
7777
self_ty: ty::TyVid,
7878
) -> PredicateObligations<'tcx> {
79-
let obligations = self.fulfillment_cx.borrow().pending_obligations();
79+
let sub_root_var = self.sub_unification_table_root_var(self_ty);
80+
let obligations = self
81+
.fulfillment_cx
82+
.borrow()
83+
.pending_obligations_potentially_referencing_sub_root(sub_root_var);
8084
debug!(?obligations);
8185
let mut obligations_for_self_ty = PredicateObligations::new();
8286
for obligation in obligations {
@@ -125,6 +129,18 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for NestedObligationsForSelfTy<'a, 'tcx> {
125129
return;
126130
}
127131

132+
// We don't care about any pending goals which don't actually
133+
// use the self type.
134+
if !inspect_goal
135+
.orig_values()
136+
.iter()
137+
.filter_map(|arg| arg.as_type())
138+
.any(|ty| self.fcx.type_matches_expected_vid(ty, self.self_ty))
139+
{
140+
debug!(goal = ?inspect_goal.goal(), "goal does not mention self type");
141+
return;
142+
}
143+
128144
let tcx = self.fcx.tcx;
129145
let goal = inspect_goal.goal();
130146
if self.fcx.predicate_has_self_ty(goal.predicate, self.self_ty)

compiler/rustc_infer/src/traits/engine.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::fmt::Debug;
22

33
use rustc_hir::def_id::DefId;
4-
use rustc_middle::ty::{self, Ty, Upcast};
4+
use rustc_middle::ty::{self, Ty, TyVid, Upcast};
55

66
use super::{ObligationCause, PredicateObligation, PredicateObligations};
77
use crate::infer::InferCtxt;
@@ -106,6 +106,15 @@ pub trait TraitEngine<'tcx, E: 'tcx>: 'tcx {
106106
fn has_pending_obligations(&self) -> bool;
107107

108108
fn pending_obligations(&self) -> PredicateObligations<'tcx>;
109+
// Returning all pending obligations which reference an inference
110+
// variable with `_sub_root`. This assumes that no type inference
111+
// progress has been made since the last `select_where_possible` call.
112+
fn pending_obligations_potentially_referencing_sub_root(
113+
&self,
114+
_sub_root: TyVid,
115+
) -> PredicateObligations<'tcx> {
116+
self.pending_obligations()
117+
}
109118

110119
/// Among all pending obligations, collect those are stalled on a inference variable which has
111120
/// changed since the last call to `select_where_possible`. Those obligations are marked as

compiler/rustc_trait_selection/src/solve/fulfill.rs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use rustc_infer::traits::{
1010
FromSolverError, PredicateObligation, PredicateObligations, TraitEngine,
1111
};
1212
use rustc_middle::ty::{
13-
self, DelayedSet, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
14-
TypingMode,
13+
self, DelayedSet, Ty, TyCtxt, TyVid, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
14+
TypeVisitor, TypingMode,
1515
};
1616
use rustc_next_trait_solver::delegate::SolverDelegate as _;
1717
use rustc_next_trait_solver::solve::{
@@ -85,8 +85,27 @@ impl<'tcx> ObligationStorage<'tcx> {
8585
obligations.extend(self.overflowed.iter().cloned());
8686
obligations
8787
}
88+
fn clone_pending_potentially_referencing_sub_root(
89+
&self,
90+
vid: TyVid,
91+
) -> PredicateObligations<'tcx> {
92+
let mut obligations: PredicateObligations<'tcx> = self
93+
.pending
94+
.iter()
95+
.filter(|(_, stalled_on)| {
96+
if let Some(stalled_on) = stalled_on {
97+
stalled_on.sub_roots.iter().any(|&r| r == vid)
98+
} else {
99+
true
100+
}
101+
})
102+
.map(|(o, _)| o.clone())
103+
.collect();
104+
obligations.extend(self.overflowed.iter().cloned());
105+
obligations
106+
}
88107

89-
fn drain_pending(
108+
fn drain_pending_ignoring_overflowed(
90109
&mut self,
91110
cond: impl Fn(&PredicateObligation<'tcx>) -> bool,
92111
) -> PendingObligations<'tcx> {
@@ -184,7 +203,9 @@ where
184203
let mut errors = Vec::new();
185204
loop {
186205
let mut any_changed = false;
187-
for (mut obligation, stalled_on) in self.obligations.drain_pending(|_| true) {
206+
for (mut obligation, stalled_on) in
207+
self.obligations.drain_pending_ignoring_overflowed(|_| true)
208+
{
188209
if !infcx.tcx.recursion_limit().value_within_limit(obligation.recursion_depth) {
189210
self.obligations.on_fulfillment_overflow(infcx);
190211
// Only return true errors that we have accumulated while processing.
@@ -277,6 +298,12 @@ where
277298
fn pending_obligations(&self) -> PredicateObligations<'tcx> {
278299
self.obligations.clone_pending()
279300
}
301+
fn pending_obligations_potentially_referencing_sub_root(
302+
&self,
303+
vid: ty::TyVid,
304+
) -> PredicateObligations<'tcx> {
305+
self.obligations.clone_pending_potentially_referencing_sub_root(vid)
306+
}
280307

281308
fn drain_stalled_obligations_for_coroutines(
282309
&mut self,
@@ -297,7 +324,7 @@ where
297324
}
298325

299326
self.obligations
300-
.drain_pending(|obl| {
327+
.drain_pending_ignoring_overflowed(|obl| {
301328
infcx.probe(|_| {
302329
infcx
303330
.visit_proof_tree(

compiler/rustc_trait_selection/src/solve/inspect/analyse.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,10 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
317317
self.depth
318318
}
319319

320+
pub fn orig_values(&self) -> &[ty::GenericArg<'tcx>] {
321+
&self.orig_values
322+
}
323+
320324
fn candidates_recur(
321325
&'a self,
322326
candidates: &mut Vec<InspectCandidate<'a, 'tcx>>,

0 commit comments

Comments
 (0)