@@ -2,9 +2,12 @@ use smallvec::smallvec;
2
2
3
3
use rustc_data_structures:: fx:: FxHashSet ;
4
4
use rustc_middle:: ty:: outlives:: Component ;
5
- use rustc_middle:: ty:: { self , ToPolyTraitRef , TyCtxt } ;
5
+ use rustc_middle:: ty:: { self , ToPolyTraitRef , ToPredicate , TyCtxt , WithConstness } ;
6
6
7
- fn anonymize_predicate < ' tcx > ( tcx : TyCtxt < ' tcx > , pred : & ty:: Predicate < ' tcx > ) -> ty:: Predicate < ' tcx > {
7
+ pub fn anonymize_predicate < ' tcx > (
8
+ tcx : TyCtxt < ' tcx > ,
9
+ pred : & ty:: Predicate < ' tcx > ,
10
+ ) -> ty:: Predicate < ' tcx > {
8
11
match * pred {
9
12
ty:: Predicate :: Trait ( ref data, constness) => {
10
13
ty:: Predicate :: Trait ( tcx. anonymize_late_bound_regions ( data) , constness)
@@ -88,6 +91,21 @@ pub struct Elaborator<'tcx> {
88
91
visited : PredicateSet < ' tcx > ,
89
92
}
90
93
94
+ pub fn elaborate_trait_ref < ' tcx > (
95
+ tcx : TyCtxt < ' tcx > ,
96
+ trait_ref : ty:: PolyTraitRef < ' tcx > ,
97
+ ) -> Elaborator < ' tcx > {
98
+ elaborate_predicates ( tcx, vec ! [ trait_ref. without_const( ) . to_predicate( ) ] )
99
+ }
100
+
101
+ pub fn elaborate_trait_refs < ' tcx > (
102
+ tcx : TyCtxt < ' tcx > ,
103
+ trait_refs : impl Iterator < Item = ty:: PolyTraitRef < ' tcx > > ,
104
+ ) -> Elaborator < ' tcx > {
105
+ let predicates = trait_refs. map ( |trait_ref| trait_ref. without_const ( ) . to_predicate ( ) ) . collect ( ) ;
106
+ elaborate_predicates ( tcx, predicates)
107
+ }
108
+
91
109
pub fn elaborate_predicates < ' tcx > (
92
110
tcx : TyCtxt < ' tcx > ,
93
111
mut predicates : Vec < ty:: Predicate < ' tcx > > ,
@@ -98,6 +116,10 @@ pub fn elaborate_predicates<'tcx>(
98
116
}
99
117
100
118
impl Elaborator < ' tcx > {
119
+ pub fn filter_to_traits ( self ) -> FilterToTraits < Self > {
120
+ FilterToTraits :: new ( self )
121
+ }
122
+
101
123
fn elaborate ( & mut self , predicate : & ty:: Predicate < ' tcx > ) {
102
124
let tcx = self . visited . tcx ;
103
125
match * predicate {
@@ -223,3 +245,57 @@ impl Iterator for Elaborator<'tcx> {
223
245
}
224
246
}
225
247
}
248
+
249
+ ///////////////////////////////////////////////////////////////////////////
250
+ // Supertrait iterator
251
+ ///////////////////////////////////////////////////////////////////////////
252
+
253
+ pub type Supertraits < ' tcx > = FilterToTraits < Elaborator < ' tcx > > ;
254
+
255
+ pub fn supertraits < ' tcx > (
256
+ tcx : TyCtxt < ' tcx > ,
257
+ trait_ref : ty:: PolyTraitRef < ' tcx > ,
258
+ ) -> Supertraits < ' tcx > {
259
+ elaborate_trait_ref ( tcx, trait_ref) . filter_to_traits ( )
260
+ }
261
+
262
+ pub fn transitive_bounds < ' tcx > (
263
+ tcx : TyCtxt < ' tcx > ,
264
+ bounds : impl Iterator < Item = ty:: PolyTraitRef < ' tcx > > ,
265
+ ) -> Supertraits < ' tcx > {
266
+ elaborate_trait_refs ( tcx, bounds) . filter_to_traits ( )
267
+ }
268
+
269
+ ///////////////////////////////////////////////////////////////////////////
270
+ // Other
271
+ ///////////////////////////////////////////////////////////////////////////
272
+
273
+ /// A filter around an iterator of predicates that makes it yield up
274
+ /// just trait references.
275
+ pub struct FilterToTraits < I > {
276
+ base_iterator : I ,
277
+ }
278
+
279
+ impl < I > FilterToTraits < I > {
280
+ fn new ( base : I ) -> FilterToTraits < I > {
281
+ FilterToTraits { base_iterator : base }
282
+ }
283
+ }
284
+
285
+ impl < ' tcx , I : Iterator < Item = ty:: Predicate < ' tcx > > > Iterator for FilterToTraits < I > {
286
+ type Item = ty:: PolyTraitRef < ' tcx > ;
287
+
288
+ fn next ( & mut self ) -> Option < ty:: PolyTraitRef < ' tcx > > {
289
+ while let Some ( pred) = self . base_iterator . next ( ) {
290
+ if let ty:: Predicate :: Trait ( data, _) = pred {
291
+ return Some ( data. to_poly_trait_ref ( ) ) ;
292
+ }
293
+ }
294
+ None
295
+ }
296
+
297
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
298
+ let ( _, upper) = self . base_iterator . size_hint ( ) ;
299
+ ( 0 , upper)
300
+ }
301
+ }
0 commit comments