1 use rustc_data_structures
::stable_set
::FxHashSet
;
3 use crate::ty
::{PolyTraitRef, TyCtxt}
;
5 /// Given a PolyTraitRef, get the PolyTraitRefs of the trait's (transitive) supertraits.
7 /// A simplified version of the same function at `rustc_infer::traits::util::supertraits`.
8 pub fn supertraits
<'tcx
>(
10 trait_ref
: PolyTraitRef
<'tcx
>,
11 ) -> impl Iterator
<Item
= PolyTraitRef
<'tcx
>> {
12 Elaborator { tcx, visited: FxHashSet::from_iter([trait_ref]), stack: vec![trait_ref] }
15 struct Elaborator
<'tcx
> {
17 visited
: FxHashSet
<PolyTraitRef
<'tcx
>>,
18 stack
: Vec
<PolyTraitRef
<'tcx
>>,
21 impl<'tcx
> Elaborator
<'tcx
> {
22 fn elaborate(&mut self, trait_ref
: PolyTraitRef
<'tcx
>) {
23 let supertrait_refs
= self
25 .super_predicates_of(trait_ref
.def_id())
28 .flat_map(|(pred
, _
)| {
29 pred
.subst_supertrait(self.tcx
, &trait_ref
).to_opt_poly_trait_pred()
31 .map(|t
| t
.map_bound(|pred
| pred
.trait_ref
))
32 .filter(|supertrait_ref
| self.visited
.insert(*supertrait_ref
));
34 self.stack
.extend(supertrait_refs
);
38 impl<'tcx
> Iterator
for Elaborator
<'tcx
> {
39 type Item
= PolyTraitRef
<'tcx
>;
41 fn next(&mut self) -> Option
<PolyTraitRef
<'tcx
>> {
42 if let Some(trait_ref
) = self.stack
.pop() {
43 self.elaborate(trait_ref
);