Skip to content

Commit 507c995

Browse files
Auto merge of #141927 - compiler-errors:perf-select, r=<try>
[PERF] Clear nested candidates in select if certainty is yes Proving these goals is redundant.
2 parents 2398bd6 + a0971b8 commit 507c995

File tree

2 files changed

+54
-2
lines changed

2 files changed

+54
-2
lines changed

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

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ pub struct InspectGoal<'a, 'tcx> {
5050
/// not something we want to leak to users. We therefore
5151
/// treat `NormalizesTo` goals as if they apply the expected
5252
/// type at the end of each candidate.
53-
#[derive(Copy, Clone)]
53+
#[derive(Copy, Clone, Debug)]
5454
struct NormalizesToTermHack<'tcx> {
5555
term: ty::Term<'tcx>,
5656
unconstrained_term: ty::Term<'tcx>,
@@ -197,6 +197,50 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
197197
(goals, opt_impl_args)
198198
}
199199

200+
/// Instantiate the args of an impl if this candidate came from a
201+
/// `CandidateSource::Impl`. This function modifies the state of the
202+
/// `infcx`.
203+
#[instrument(
204+
level = "debug",
205+
skip_all,
206+
fields(goal = ?self.goal.goal, steps = ?self.steps)
207+
)]
208+
pub fn instantiate_opt_impl_args(&self, span: Span) -> Option<ty::GenericArgsRef<'tcx>> {
209+
let infcx = self.goal.infcx;
210+
let param_env = self.goal.goal.param_env;
211+
let mut orig_values = self.goal.orig_values.to_vec();
212+
213+
let mut opt_impl_args = None;
214+
for step in &self.steps {
215+
match **step {
216+
inspect::ProbeStep::RecordImplArgs { impl_args } => {
217+
opt_impl_args = Some(instantiate_canonical_state(
218+
infcx,
219+
span,
220+
param_env,
221+
&mut orig_values,
222+
impl_args,
223+
));
224+
}
225+
inspect::ProbeStep::AddGoal(..) => {}
226+
inspect::ProbeStep::MakeCanonicalResponse { .. }
227+
| inspect::ProbeStep::NestedProbe(_) => unreachable!(),
228+
}
229+
}
230+
231+
let () =
232+
instantiate_canonical_state(infcx, span, param_env, &mut orig_values, self.final_state);
233+
234+
if let Some(term_hack) = self.goal.normalizes_to_term_hack {
235+
// FIXME: We ignore the expected term of `NormalizesTo` goals
236+
// when computing the result of its candidates. This is
237+
// scuffed.
238+
let _ = term_hack.constrain(infcx, span, param_env);
239+
}
240+
241+
opt_impl_args.map(|impl_args| eager_resolve_vars(infcx, impl_args))
242+
}
243+
200244
pub fn instantiate_proof_tree_for_nested_goal(
201245
&self,
202246
source: GoalSource,

compiler/rustc_trait_selection/src/solve/select.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_infer::traits::{
1010
use rustc_macros::extension;
1111
use rustc_middle::{bug, span_bug};
1212
use rustc_span::Span;
13+
use thin_vec::ThinVec;
1314

1415
use crate::solve::inspect::{self, ProofTreeInferCtxtExt};
1516

@@ -146,7 +147,10 @@ fn to_selection<'tcx>(
146147
return None;
147148
}
148149

149-
let (nested, impl_args) = cand.instantiate_nested_goals_and_opt_impl_args(span);
150+
let (nested, impl_args) = match cand.result().expect("expected positive result") {
151+
Certainty::Yes => (vec![], cand.instantiate_opt_impl_args(span)),
152+
Certainty::Maybe(_) => cand.instantiate_nested_goals_and_opt_impl_args(span),
153+
};
150154
let nested = nested
151155
.into_iter()
152156
.map(|nested| {
@@ -159,6 +163,10 @@ fn to_selection<'tcx>(
159163
})
160164
.collect();
161165

166+
if let Ok(Certainty::Yes) = cand.result() {
167+
nested.clear();
168+
}
169+
162170
Some(match cand.kind() {
163171
ProbeKind::TraitCandidate { source, result: _ } => match source {
164172
CandidateSource::Impl(impl_def_id) => {

0 commit comments

Comments
 (0)