Skip to content

Commit 9f0e50c

Browse files
Only instantiate impl args
1 parent 11125f7 commit 9f0e50c

File tree

2 files changed

+50
-8
lines changed

2 files changed

+50
-8
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: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ 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;
1413

1514
use crate::solve::inspect::{self, ProofTreeInferCtxtExt};
1615

@@ -147,8 +146,11 @@ fn to_selection<'tcx>(
147146
return None;
148147
}
149148

150-
let (nested, impl_args) = cand.instantiate_nested_goals_and_opt_impl_args(span);
151-
let mut nested: ThinVec<_> = nested
149+
let (nested, impl_args) = match cand.result().expect("expected positive result") {
150+
Certainty::Yes => (vec![], cand.instantiate_opt_impl_args(span)),
151+
Certainty::Maybe(_) => cand.instantiate_nested_goals_and_opt_impl_args(span),
152+
};
153+
let nested = nested
152154
.into_iter()
153155
.map(|nested| {
154156
Obligation::new(
@@ -160,10 +162,6 @@ fn to_selection<'tcx>(
160162
})
161163
.collect();
162164

163-
if let Ok(Certainty::Yes) = cand.result() {
164-
nested.clear();
165-
}
166-
167165
Some(match cand.kind() {
168166
ProbeKind::TraitCandidate { source, result: _ } => match source {
169167
CandidateSource::Impl(impl_def_id) => {

0 commit comments

Comments
 (0)