Skip to content

Commit a0971b8

Browse files
Only instantiate impl args
1 parent 47dbfcd commit a0971b8

File tree

2 files changed

+50
-3
lines changed

2 files changed

+50
-3
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 & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,11 @@ fn to_selection<'tcx>(
147147
return None;
148148
}
149149

150-
let (nested, impl_args) = cand.instantiate_nested_goals_and_opt_impl_args(span);
151-
let mut nested: ThinVec<_> = nested
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+
};
154+
let nested = nested
152155
.into_iter()
153156
.map(|nested| {
154157
Obligation::new(

0 commit comments

Comments
 (0)