Skip to content

Commit 2f2c8c3

Browse files
committed
Auto merge of #141927 - compiler-errors:perf-select, r=lcnr
Clear nested candidates in select if certainty is yes Proving these goals is redundant.
2 parents 5e0bdaa + 1e5cd12 commit 2f2c8c3

File tree

2 files changed

+70
-41
lines changed

2 files changed

+70
-41
lines changed

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

Lines changed: 53 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -133,45 +133,25 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
133133
/// Instantiate the nested goals for the candidate without rolling back their
134134
/// inference constraints. This function modifies the state of the `infcx`.
135135
///
136-
/// See [`Self::instantiate_nested_goals_and_opt_impl_args`] if you need the impl args too.
137-
pub fn instantiate_nested_goals(&self, span: Span) -> Vec<InspectGoal<'a, 'tcx>> {
138-
self.instantiate_nested_goals_and_opt_impl_args(span).0
139-
}
140-
141-
/// Instantiate the nested goals for the candidate without rolling back their
142-
/// inference constraints, and optionally the args of an impl if this candidate
143-
/// came from a `CandidateSource::Impl`. This function modifies the state of the
144-
/// `infcx`.
136+
/// See [`Self::instantiate_impl_args`] if you need the impl args too.
145137
#[instrument(
146138
level = "debug",
147139
skip_all,
148140
fields(goal = ?self.goal.goal, steps = ?self.steps)
149141
)]
150-
pub fn instantiate_nested_goals_and_opt_impl_args(
151-
&self,
152-
span: Span,
153-
) -> (Vec<InspectGoal<'a, 'tcx>>, Option<ty::GenericArgsRef<'tcx>>) {
142+
pub fn instantiate_nested_goals(&self, span: Span) -> Vec<InspectGoal<'a, 'tcx>> {
154143
let infcx = self.goal.infcx;
155144
let param_env = self.goal.goal.param_env;
156145
let mut orig_values = self.goal.orig_values.to_vec();
157146

158147
let mut instantiated_goals = vec![];
159-
let mut opt_impl_args = None;
160148
for step in &self.steps {
161149
match **step {
162150
inspect::ProbeStep::AddGoal(source, goal) => instantiated_goals.push((
163151
source,
164152
instantiate_canonical_state(infcx, span, param_env, &mut orig_values, goal),
165153
)),
166-
inspect::ProbeStep::RecordImplArgs { impl_args } => {
167-
opt_impl_args = Some(instantiate_canonical_state(
168-
infcx,
169-
span,
170-
param_env,
171-
&mut orig_values,
172-
impl_args,
173-
));
174-
}
154+
inspect::ProbeStep::RecordImplArgs { .. } => {}
175155
inspect::ProbeStep::MakeCanonicalResponse { .. }
176156
| inspect::ProbeStep::NestedProbe(_) => unreachable!(),
177157
}
@@ -187,14 +167,59 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
187167
let _ = term_hack.constrain(infcx, span, param_env);
188168
}
189169

190-
let opt_impl_args = opt_impl_args.map(|impl_args| eager_resolve_vars(infcx, impl_args));
191-
192-
let goals = instantiated_goals
170+
instantiated_goals
193171
.into_iter()
194172
.map(|(source, goal)| self.instantiate_proof_tree_for_nested_goal(source, goal, span))
195-
.collect();
173+
.collect()
174+
}
175+
176+
/// Instantiate the args of an impl if this candidate came from a
177+
/// `CandidateSource::Impl`. This function modifies the state of the
178+
/// `infcx`.
179+
#[instrument(
180+
level = "debug",
181+
skip_all,
182+
fields(goal = ?self.goal.goal, steps = ?self.steps)
183+
)]
184+
pub fn instantiate_impl_args(&self, span: Span) -> ty::GenericArgsRef<'tcx> {
185+
let infcx = self.goal.infcx;
186+
let param_env = self.goal.goal.param_env;
187+
let mut orig_values = self.goal.orig_values.to_vec();
188+
189+
for step in &self.steps {
190+
match **step {
191+
inspect::ProbeStep::RecordImplArgs { impl_args } => {
192+
let impl_args = instantiate_canonical_state(
193+
infcx,
194+
span,
195+
param_env,
196+
&mut orig_values,
197+
impl_args,
198+
);
199+
200+
let () = instantiate_canonical_state(
201+
infcx,
202+
span,
203+
param_env,
204+
&mut orig_values,
205+
self.final_state,
206+
);
207+
208+
// No reason we couldn't support this, but we don't need to for select.
209+
assert!(
210+
self.goal.normalizes_to_term_hack.is_none(),
211+
"cannot use `instantiate_impl_args` with a `NormalizesTo` goal"
212+
);
213+
214+
return eager_resolve_vars(infcx, impl_args);
215+
}
216+
inspect::ProbeStep::AddGoal(..) => {}
217+
inspect::ProbeStep::MakeCanonicalResponse { .. }
218+
| inspect::ProbeStep::NestedProbe(_) => unreachable!(),
219+
}
220+
}
196221

197-
(goals, opt_impl_args)
222+
bug!("expected impl args probe step for `instantiate_impl_args`");
198223
}
199224

200225
pub fn instantiate_proof_tree_for_nested_goal(

compiler/rustc_trait_selection/src/solve/select.rs

Lines changed: 17 additions & 13 deletions
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::thin_vec;
1314

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

@@ -146,18 +147,21 @@ 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 = nested
151-
.into_iter()
152-
.map(|nested| {
153-
Obligation::new(
154-
nested.infcx().tcx,
155-
ObligationCause::dummy_with_span(span),
156-
nested.goal().param_env,
157-
nested.goal().predicate,
158-
)
159-
})
160-
.collect();
150+
let nested = match cand.result().expect("expected positive result") {
151+
Certainty::Yes => thin_vec![],
152+
Certainty::Maybe(_) => cand
153+
.instantiate_nested_goals(span)
154+
.into_iter()
155+
.map(|nested| {
156+
Obligation::new(
157+
nested.infcx().tcx,
158+
ObligationCause::dummy_with_span(span),
159+
nested.goal().param_env,
160+
nested.goal().predicate,
161+
)
162+
})
163+
.collect(),
164+
};
161165

162166
Some(match cand.kind() {
163167
ProbeKind::TraitCandidate { source, result: _ } => match source {
@@ -166,7 +170,7 @@ fn to_selection<'tcx>(
166170
// For impl candidates, we do the rematch manually to compute the args.
167171
ImplSource::UserDefined(ImplSourceUserDefinedData {
168172
impl_def_id,
169-
args: impl_args.expect("expected recorded impl args for impl candidate"),
173+
args: cand.instantiate_impl_args(span),
170174
nested,
171175
})
172176
}

0 commit comments

Comments
 (0)