Rollup merge of #124936 - lcnr:cool-beans, r=compiler-errors
analyse visitor: build proof tree in probe see inline comments fixes #124791 fixes #124702 r? ```@compiler-errors```
This commit is contained in:
commit
43ddd1d963
8 changed files with 113 additions and 34 deletions
|
@ -409,6 +409,7 @@ pub(in crate::solve) fn make_canonical_state<'tcx, T: TypeFoldable<TyCtxt<'tcx>>
|
|||
/// This currently assumes that unifying the var values trivially succeeds.
|
||||
/// Adding any inference constraints which weren't present when originally
|
||||
/// computing the canonical query can result in bugs.
|
||||
#[instrument(level = "debug", skip(infcx, span, param_env))]
|
||||
pub(in crate::solve) fn instantiate_canonical_state<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
span: Span,
|
||||
|
|
|
@ -146,6 +146,11 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
|
|||
/// inference constraints, and optionally the args of an impl if this candidate
|
||||
/// came from a `CandidateSource::Impl`. This function modifies the state of the
|
||||
/// `infcx`.
|
||||
#[instrument(
|
||||
level = "debug",
|
||||
skip_all,
|
||||
fields(goal = ?self.goal.goal, nested_goals = ?self.nested_goals)
|
||||
)]
|
||||
pub fn instantiate_nested_goals_and_opt_impl_args(
|
||||
&self,
|
||||
span: Span,
|
||||
|
@ -213,10 +218,23 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
|
|||
};
|
||||
let goal =
|
||||
goal.with(infcx.tcx, ty::NormalizesTo { alias, term: unconstrained_term });
|
||||
let proof_tree = EvalCtxt::enter_root(infcx, GenerateProofTree::Yes, |ecx| {
|
||||
ecx.evaluate_goal_raw(GoalEvaluationKind::Root, GoalSource::Misc, goal)
|
||||
})
|
||||
.1;
|
||||
// We have to use a `probe` here as evaluating a `NormalizesTo` can constrain the
|
||||
// expected term. This means that candidates which only fail due to nested goals
|
||||
// and which normalize to a different term then the final result could ICE: when
|
||||
// building their proof tree, the expected term was unconstrained, but when
|
||||
// instantiating the candidate it is already constrained to the result of another
|
||||
// candidate.
|
||||
let proof_tree = infcx
|
||||
.probe(|_| {
|
||||
EvalCtxt::enter_root(infcx, GenerateProofTree::Yes, |ecx| {
|
||||
ecx.evaluate_goal_raw(
|
||||
GoalEvaluationKind::Root,
|
||||
GoalSource::Misc,
|
||||
goal,
|
||||
)
|
||||
})
|
||||
})
|
||||
.1;
|
||||
InspectGoal::new(
|
||||
infcx,
|
||||
self.goal.depth + 1,
|
||||
|
@ -225,13 +243,17 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
|
|||
source,
|
||||
)
|
||||
}
|
||||
_ => InspectGoal::new(
|
||||
infcx,
|
||||
self.goal.depth + 1,
|
||||
infcx.evaluate_root_goal(goal, GenerateProofTree::Yes).1.unwrap(),
|
||||
None,
|
||||
source,
|
||||
),
|
||||
_ => {
|
||||
// We're using a probe here as evaluating a goal could constrain
|
||||
// inference variables by choosing one candidate. If we then recurse
|
||||
// into another candidate who ends up with different inference
|
||||
// constraints, we get an ICE if we already applied the constraints
|
||||
// from the chosen candidate.
|
||||
let proof_tree = infcx
|
||||
.probe(|_| infcx.evaluate_root_goal(goal, GenerateProofTree::Yes).1)
|
||||
.unwrap();
|
||||
InspectGoal::new(infcx, self.goal.depth + 1, proof_tree, None, source)
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue