Skip to content

Commit

Permalink
Rollup merge of #108424 - megakorre:elaborator_refactor, r=compiler-e…
Browse files Browse the repository at this point in the history
…rrors

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.
  • Loading branch information
matthiaskrgr committed Feb 26, 2023
2 parents 786a75a + 3d34538 commit c815e03
Showing 1 changed file with 15 additions and 16 deletions.
31 changes: 15 additions & 16 deletions compiler/rustc_infer/src/traits/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>(
Expand All @@ -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)
}
Expand Down Expand Up @@ -172,15 +181,7 @@ impl<'tcx> Elaborator<'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,
Expand Down Expand Up @@ -237,10 +238,9 @@ impl<'tcx> Elaborator<'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 {
Expand Down Expand Up @@ -280,7 +280,6 @@ impl<'tcx> Elaborator<'tcx> {
.map(|predicate_kind| {
bound_predicate.rebind(predicate_kind).to_predicate(tcx)
})
.filter(|&predicate| visited.insert(predicate))
.map(|predicate| {
predicate_obligation(
predicate,
Expand Down

0 comments on commit c815e03

Please sign in to comment.