Rollup merge of #108424 - megakorre:elaborator_refactor, r=compiler-errors

rustc_infer: Consolidate obligation elaboration de-duplication

# Explanation

The obligations `Elaborator` is doing de-duplication of obligations in 3 different locations. 1 off which has a comment.
This PR consolidates the functionality and comment to a single function.
This commit is contained in:
Matthias Krüger 2023-02-26 12:04:59 +01:00 committed by GitHub
commit c815e03447
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -116,11 +116,11 @@ pub fn elaborate_predicates_with_span<'tcx>(
pub fn elaborate_obligations<'tcx>(
tcx: TyCtxt<'tcx>,
mut obligations: Vec<PredicateObligation<'tcx>>,
obligations: Vec<PredicateObligation<'tcx>>,
) -> Elaborator<'tcx> {
let mut visited = PredicateSet::new(tcx);
obligations.retain(|obligation| visited.insert(obligation.predicate));
Elaborator { stack: obligations, visited }
let mut elaborator = Elaborator { stack: Vec::new(), visited: PredicateSet::new(tcx) };
elaborator.extend_deduped(obligations);
elaborator
}
fn predicate_obligation<'tcx>(
@ -132,6 +132,15 @@ fn predicate_obligation<'tcx>(
}
impl<'tcx> Elaborator<'tcx> {
fn extend_deduped(&mut self, obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>) {
// Only keep those bounds that we haven't already seen.
// This is necessary to prevent infinite recursion in some
// cases. One common case is when people define
// `trait Sized: Sized { }` rather than `trait Sized { }`.
// let visited = &mut self.visited;
self.stack.extend(obligations.into_iter().filter(|o| self.visited.insert(o.predicate)));
}
pub fn filter_to_traits(self) -> FilterToTraits<Self> {
FilterToTraits::new(self)
}
@ -172,15 +181,7 @@ fn elaborate(&mut self, obligation: &PredicateObligation<'tcx>) {
)
});
debug!(?data, ?obligations, "super_predicates");
// Only keep those bounds that we haven't already seen.
// This is necessary to prevent infinite recursion in some
// cases. One common case is when people define
// `trait Sized: Sized { }` rather than `trait Sized { }`.
let visited = &mut self.visited;
let obligations = obligations.filter(|o| visited.insert(o.predicate));
self.stack.extend(obligations);
self.extend_deduped(obligations);
}
ty::PredicateKind::WellFormed(..) => {
// Currently, we do not elaborate WF predicates,
@ -237,10 +238,9 @@ fn elaborate(&mut self, obligation: &PredicateObligation<'tcx>) {
return;
}
let visited = &mut self.visited;
let mut components = smallvec![];
push_outlives_components(tcx, ty_max, &mut components);
self.stack.extend(
self.extend_deduped(
components
.into_iter()
.filter_map(|component| match component {
@ -280,7 +280,6 @@ fn elaborate(&mut self, obligation: &PredicateObligation<'tcx>) {
.map(|predicate_kind| {
bound_predicate.rebind(predicate_kind).to_predicate(tcx)
})
.filter(|&predicate| visited.insert(predicate))
.map(|predicate| {
predicate_obligation(
predicate,