Rollup merge of #126404 - compiler-errors:alias-relate-terms, r=lcnr
Check that alias-relate terms are WF if reporting an error in alias-relate Check that each of the left/right term is WF when deriving a best error obligation for an alias-relate goal. This will make sure that given `<i32 as NotImplemented>::Assoc = ()` will drill down into `i32: NotImplemented` since we currently treat the projection as rigid. r? lcnr
This commit is contained in:
commit
709d862308
12 changed files with 59 additions and 168 deletions
|
@ -515,6 +515,32 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
|
|||
self.with_derived_obligation(obligation, |this| nested_goal.visit_with(this))?;
|
||||
}
|
||||
|
||||
// alias-relate may fail because the lhs or rhs can't be normalized,
|
||||
// and therefore is treated as rigid.
|
||||
if let Some(ty::PredicateKind::AliasRelate(lhs, rhs, _)) = pred_kind.no_bound_vars() {
|
||||
if let Some(obligation) = goal
|
||||
.infcx()
|
||||
.visit_proof_tree_at_depth(
|
||||
goal.goal().with(goal.infcx().tcx, ty::ClauseKind::WellFormed(lhs.into())),
|
||||
goal.depth() + 1,
|
||||
self,
|
||||
)
|
||||
.break_value()
|
||||
{
|
||||
return ControlFlow::Break(obligation);
|
||||
} else if let Some(obligation) = goal
|
||||
.infcx()
|
||||
.visit_proof_tree_at_depth(
|
||||
goal.goal().with(goal.infcx().tcx, ty::ClauseKind::WellFormed(rhs.into())),
|
||||
goal.depth() + 1,
|
||||
self,
|
||||
)
|
||||
.break_value()
|
||||
{
|
||||
return ControlFlow::Break(obligation);
|
||||
}
|
||||
}
|
||||
|
||||
ControlFlow::Break(self.obligation.clone())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -278,6 +278,10 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
|
|||
self.source
|
||||
}
|
||||
|
||||
pub fn depth(&self) -> usize {
|
||||
self.depth
|
||||
}
|
||||
|
||||
fn candidates_recur(
|
||||
&'a self,
|
||||
candidates: &mut Vec<InspectCandidate<'a, 'tcx>>,
|
||||
|
@ -435,9 +439,18 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
&self,
|
||||
goal: Goal<'tcx, ty::Predicate<'tcx>>,
|
||||
visitor: &mut V,
|
||||
) -> V::Result {
|
||||
self.visit_proof_tree_at_depth(goal, 0, visitor)
|
||||
}
|
||||
|
||||
fn visit_proof_tree_at_depth<V: ProofTreeVisitor<'tcx>>(
|
||||
&self,
|
||||
goal: Goal<'tcx, ty::Predicate<'tcx>>,
|
||||
depth: usize,
|
||||
visitor: &mut V,
|
||||
) -> V::Result {
|
||||
let (_, proof_tree) = self.evaluate_root_goal(goal, GenerateProofTree::Yes);
|
||||
let proof_tree = proof_tree.unwrap();
|
||||
visitor.visit_goal(&InspectGoal::new(self, 0, proof_tree, None, GoalSource::Misc))
|
||||
visitor.visit_goal(&InspectGoal::new(self, depth, proof_tree, None, GoalSource::Misc))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue