refactor analyse visitor to instantiate states in order

This commit is contained in:
lcnr 2024-05-21 19:56:18 +00:00
parent 4d5a9bcb86
commit 13ce229042

View File

@ -89,10 +89,8 @@ impl<'tcx> NormalizesToTermHack<'tcx> {
pub struct InspectCandidate<'a, 'tcx> { pub struct InspectCandidate<'a, 'tcx> {
goal: &'a InspectGoal<'a, 'tcx>, goal: &'a InspectGoal<'a, 'tcx>,
kind: inspect::ProbeKind<TyCtxt<'tcx>>, kind: inspect::ProbeKind<TyCtxt<'tcx>>,
nested_goals: steps: Vec<&'a inspect::ProbeStep<TyCtxt<'tcx>>>,
Vec<(GoalSource, inspect::CanonicalState<TyCtxt<'tcx>, Goal<'tcx, ty::Predicate<'tcx>>>)>,
final_state: inspect::CanonicalState<TyCtxt<'tcx>, ()>, final_state: inspect::CanonicalState<TyCtxt<'tcx>, ()>,
impl_args: Option<inspect::CanonicalState<TyCtxt<'tcx>, ty::GenericArgsRef<'tcx>>>,
result: QueryResult<'tcx>, result: QueryResult<'tcx>,
shallow_certainty: Certainty, shallow_certainty: Certainty,
} }
@ -148,7 +146,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
#[instrument( #[instrument(
level = "debug", level = "debug",
skip_all, skip_all,
fields(goal = ?self.goal.goal, nested_goals = ?self.nested_goals) fields(goal = ?self.goal.goal, steps = ?self.steps)
)] )]
pub fn instantiate_nested_goals_and_opt_impl_args( pub fn instantiate_nested_goals_and_opt_impl_args(
&self, &self,
@ -157,22 +155,34 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
let infcx = self.goal.infcx; let infcx = self.goal.infcx;
let param_env = self.goal.goal.param_env; let param_env = self.goal.goal.param_env;
let mut orig_values = self.goal.orig_values.to_vec(); let mut orig_values = self.goal.orig_values.to_vec();
let instantiated_goals: Vec<_> = self
.nested_goals let mut instantiated_goals = vec![];
.iter() let mut opt_impl_args = None;
.map(|(source, goal)| { for step in &self.steps {
( match **step {
*source, inspect::ProbeStep::AddGoal(source, goal) => instantiated_goals.push((
source,
canonical::instantiate_canonical_state( canonical::instantiate_canonical_state(
infcx, infcx,
span, span,
param_env, param_env,
&mut orig_values, &mut orig_values,
*goal, goal,
), ),
) )),
}) inspect::ProbeStep::RecordImplArgs { impl_args } => {
.collect(); opt_impl_args = Some(canonical::instantiate_canonical_state(
infcx,
span,
param_env,
&mut orig_values,
impl_args,
));
}
inspect::ProbeStep::MakeCanonicalResponse { .. }
| inspect::ProbeStep::NestedProbe(_) => unreachable!(),
}
}
let () = canonical::instantiate_canonical_state( let () = canonical::instantiate_canonical_state(
infcx, infcx,
@ -182,17 +192,6 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
self.final_state, self.final_state,
); );
let impl_args = self.impl_args.map(|impl_args| {
canonical::instantiate_canonical_state(
infcx,
span,
param_env,
&mut orig_values,
impl_args,
)
.fold_with(&mut EagerResolver::new(infcx))
});
if let Some(term_hack) = self.goal.normalizes_to_term_hack { if let Some(term_hack) = self.goal.normalizes_to_term_hack {
// FIXME: We ignore the expected term of `NormalizesTo` goals // FIXME: We ignore the expected term of `NormalizesTo` goals
// when computing the result of its candidates. This is // when computing the result of its candidates. This is
@ -200,6 +199,9 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
let _ = term_hack.constrain(infcx, span, param_env); let _ = term_hack.constrain(infcx, span, param_env);
} }
let opt_impl_args =
opt_impl_args.map(|impl_args| impl_args.fold_with(&mut EagerResolver::new(infcx)));
let goals = instantiated_goals let goals = instantiated_goals
.into_iter() .into_iter()
.map(|(source, goal)| match goal.predicate.kind().no_bound_vars() { .map(|(source, goal)| match goal.predicate.kind().no_bound_vars() {
@ -249,7 +251,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
}) })
.collect(); .collect();
(goals, impl_args) (goals, opt_impl_args)
} }
/// Visit all nested goals of this candidate, rolling back /// Visit all nested goals of this candidate, rolling back
@ -279,17 +281,18 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
fn candidates_recur( fn candidates_recur(
&'a self, &'a self,
candidates: &mut Vec<InspectCandidate<'a, 'tcx>>, candidates: &mut Vec<InspectCandidate<'a, 'tcx>>,
nested_goals: &mut Vec<( steps: &mut Vec<&'a inspect::ProbeStep<TyCtxt<'tcx>>>,
GoalSource, probe: &'a inspect::Probe<TyCtxt<'tcx>>,
inspect::CanonicalState<TyCtxt<'tcx>, Goal<'tcx, ty::Predicate<'tcx>>>,
)>,
probe: &inspect::Probe<TyCtxt<'tcx>>,
) { ) {
let mut shallow_certainty = None; let mut shallow_certainty = None;
let mut impl_args = None;
for step in &probe.steps { for step in &probe.steps {
match *step { match *step {
inspect::ProbeStep::AddGoal(source, goal) => nested_goals.push((source, goal)), inspect::ProbeStep::AddGoal(..) | inspect::ProbeStep::RecordImplArgs { .. } => {
steps.push(step)
}
inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty: c } => {
assert_eq!(shallow_certainty.replace(c), None);
}
inspect::ProbeStep::NestedProbe(ref probe) => { inspect::ProbeStep::NestedProbe(ref probe) => {
match probe.kind { match probe.kind {
// These never assemble candidates for the goal we're trying to solve. // These never assemble candidates for the goal we're trying to solve.
@ -305,18 +308,12 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
// Nested probes have to prove goals added in their parent // Nested probes have to prove goals added in their parent
// but do not leak them, so we truncate the added goals // but do not leak them, so we truncate the added goals
// afterwards. // afterwards.
let num_goals = nested_goals.len(); let num_steps = steps.len();
self.candidates_recur(candidates, nested_goals, probe); self.candidates_recur(candidates, steps, probe);
nested_goals.truncate(num_goals); steps.truncate(num_steps);
} }
} }
} }
inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty: c } => {
assert_eq!(shallow_certainty.replace(c), None);
}
inspect::ProbeStep::RecordImplArgs { impl_args: i } => {
assert_eq!(impl_args.replace(i), None);
}
} }
} }
@ -338,11 +335,10 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
candidates.push(InspectCandidate { candidates.push(InspectCandidate {
goal: self, goal: self,
kind: probe.kind, kind: probe.kind,
nested_goals: nested_goals.clone(), steps: steps.clone(),
final_state: probe.final_state, final_state: probe.final_state,
result,
shallow_certainty, shallow_certainty,
impl_args, result,
}); });
} }
} }