@@ -192,7 +192,8 @@ impl ImplOrTraitItemId {
192
192
#[ derive( Clone , Debug ) ]
193
193
pub struct Method < ' tcx > {
194
194
pub name : ast:: Name ,
195
- pub generics : ty:: Generics < ' tcx > ,
195
+ pub generics : Generics < ' tcx > ,
196
+ pub predicates : GenericPredicates < ' tcx > ,
196
197
pub fty : BareFnTy < ' tcx > ,
197
198
pub explicit_self : ExplicitSelfCategory ,
198
199
pub vis : ast:: Visibility ,
@@ -206,6 +207,7 @@ pub struct Method<'tcx> {
206
207
impl < ' tcx > Method < ' tcx > {
207
208
pub fn new ( name : ast:: Name ,
208
209
generics : ty:: Generics < ' tcx > ,
210
+ predicates : GenericPredicates < ' tcx > ,
209
211
fty : BareFnTy < ' tcx > ,
210
212
explicit_self : ExplicitSelfCategory ,
211
213
vis : ast:: Visibility ,
@@ -216,6 +218,7 @@ impl<'tcx> Method<'tcx> {
216
218
Method {
217
219
name : name,
218
220
generics : generics,
221
+ predicates : predicates,
219
222
fty : fty,
220
223
explicit_self : explicit_self,
221
224
vis : vis,
@@ -710,6 +713,10 @@ pub struct ctxt<'tcx> {
710
713
pub trait_refs : RefCell < NodeMap < Rc < TraitRef < ' tcx > > > > ,
711
714
pub trait_defs : RefCell < DefIdMap < Rc < TraitDef < ' tcx > > > > ,
712
715
716
+ /// Maps from the def-id of an item (trait/struct/enum/fn) to its
717
+ /// associated predicates.
718
+ pub predicates : RefCell < DefIdMap < GenericPredicates < ' tcx > > > ,
719
+
713
720
/// Maps from node-id of a trait object cast (like `foo as
714
721
/// Box<Trait>`) to the trait reference.
715
722
pub object_cast_map : ObjectCastMap < ' tcx > ,
@@ -1782,33 +1789,45 @@ impl RegionParameterDef {
1782
1789
pub struct Generics < ' tcx > {
1783
1790
pub types : VecPerParamSpace < TypeParameterDef < ' tcx > > ,
1784
1791
pub regions : VecPerParamSpace < RegionParameterDef > ,
1785
- pub predicates : VecPerParamSpace < Predicate < ' tcx > > ,
1786
1792
}
1787
1793
1788
1794
impl < ' tcx > Generics < ' tcx > {
1789
1795
pub fn empty ( ) -> Generics < ' tcx > {
1790
1796
Generics {
1791
1797
types : VecPerParamSpace :: empty ( ) ,
1792
1798
regions : VecPerParamSpace :: empty ( ) ,
1793
- predicates : VecPerParamSpace :: empty ( ) ,
1794
1799
}
1795
1800
}
1796
1801
1802
+ pub fn is_empty ( & self ) -> bool {
1803
+ self . types . is_empty ( ) && self . regions . is_empty ( )
1804
+ }
1805
+
1797
1806
pub fn has_type_params ( & self , space : subst:: ParamSpace ) -> bool {
1798
1807
!self . types . is_empty_in ( space)
1799
1808
}
1800
1809
1801
1810
pub fn has_region_params ( & self , space : subst:: ParamSpace ) -> bool {
1802
1811
!self . regions . is_empty_in ( space)
1803
1812
}
1813
+ }
1804
1814
1805
- pub fn is_empty ( & self ) -> bool {
1806
- self . types . is_empty ( ) && self . regions . is_empty ( )
1815
+ /// Bounds on generics.
1816
+ #[ derive( Clone , Debug ) ]
1817
+ pub struct GenericPredicates < ' tcx > {
1818
+ pub predicates : VecPerParamSpace < Predicate < ' tcx > > ,
1819
+ }
1820
+
1821
+ impl < ' tcx > GenericPredicates < ' tcx > {
1822
+ pub fn empty ( ) -> GenericPredicates < ' tcx > {
1823
+ GenericPredicates {
1824
+ predicates : VecPerParamSpace :: empty ( ) ,
1825
+ }
1807
1826
}
1808
1827
1809
- pub fn to_bounds ( & self , tcx : & ty:: ctxt < ' tcx > , substs : & Substs < ' tcx > )
1810
- -> GenericBounds < ' tcx > {
1811
- GenericBounds {
1828
+ pub fn instantiate ( & self , tcx : & ty:: ctxt < ' tcx > , substs : & Substs < ' tcx > )
1829
+ -> InstantiatedPredicates < ' tcx > {
1830
+ InstantiatedPredicates {
1812
1831
predicates : self . predicates . subst ( tcx, substs) ,
1813
1832
}
1814
1833
}
@@ -2022,11 +2041,11 @@ impl<'tcx> Predicate<'tcx> {
2022
2041
2023
2042
/// Represents the bounds declared on a particular set of type
2024
2043
/// parameters. Should eventually be generalized into a flag list of
2025
- /// where clauses. You can obtain a `GenericBounds ` list from a
2026
- /// `Generics ` by using the `to_bounds ` method. Note that this method
2027
- /// reflects an important semantic invariant of `GenericBounds `: while
2028
- /// the bounds in a `Generics ` are expressed in terms of the bound type
2029
- /// parameters of the impl/trait/whatever, a `GenericBounds ` instance
2044
+ /// where clauses. You can obtain a `InstantiatedPredicates ` list from a
2045
+ /// `GenericPredicates ` by using the `instantiate ` method. Note that this method
2046
+ /// reflects an important semantic invariant of `InstantiatedPredicates `: while
2047
+ /// the `GenericPredicates ` are expressed in terms of the bound type
2048
+ /// parameters of the impl/trait/whatever, an `InstantiatedPredicates ` instance
2030
2049
/// represented a set of bounds for some particular instantiation,
2031
2050
/// meaning that the generic parameters have been substituted with
2032
2051
/// their values.
@@ -2035,18 +2054,18 @@ impl<'tcx> Predicate<'tcx> {
2035
2054
///
2036
2055
/// struct Foo<T,U:Bar<T>> { ... }
2037
2056
///
2038
- /// Here, the `Generics ` for `Foo` would contain a list of bounds like
2057
+ /// Here, the `GenericPredicates ` for `Foo` would contain a list of bounds like
2039
2058
/// `[[], [U:Bar<T>]]`. Now if there were some particular reference
2040
- /// like `Foo<int,uint>`, then the `GenericBounds ` would be `[[],
2059
+ /// like `Foo<int,uint>`, then the `InstantiatedPredicates ` would be `[[],
2041
2060
/// [uint:Bar<int>]]`.
2042
2061
#[ derive( Clone , Debug ) ]
2043
- pub struct GenericBounds < ' tcx > {
2062
+ pub struct InstantiatedPredicates < ' tcx > {
2044
2063
pub predicates : VecPerParamSpace < Predicate < ' tcx > > ,
2045
2064
}
2046
2065
2047
- impl < ' tcx > GenericBounds < ' tcx > {
2048
- pub fn empty ( ) -> GenericBounds < ' tcx > {
2049
- GenericBounds { predicates : VecPerParamSpace :: empty ( ) }
2066
+ impl < ' tcx > InstantiatedPredicates < ' tcx > {
2067
+ pub fn empty ( ) -> InstantiatedPredicates < ' tcx > {
2068
+ InstantiatedPredicates { predicates : VecPerParamSpace :: empty ( ) }
2050
2069
}
2051
2070
2052
2071
pub fn has_escaping_regions ( & self ) -> bool {
@@ -2248,10 +2267,13 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
2248
2267
/// stray references in a comment or something). We try to reserve the
2249
2268
/// "poly" prefix to refer to higher-ranked things, as in
2250
2269
/// `PolyTraitRef`.
2270
+ ///
2271
+ /// Note that each item also comes with predicates, see
2272
+ /// `lookup_predicates`.
2251
2273
#[ derive( Clone , Debug ) ]
2252
2274
pub struct TypeScheme < ' tcx > {
2253
2275
pub generics : Generics < ' tcx > ,
2254
- pub ty : Ty < ' tcx >
2276
+ pub ty : Ty < ' tcx > ,
2255
2277
}
2256
2278
2257
2279
/// As `TypeScheme` but for a trait ref.
@@ -2393,6 +2415,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
2393
2415
item_substs : RefCell :: new ( NodeMap ( ) ) ,
2394
2416
trait_refs : RefCell :: new ( NodeMap ( ) ) ,
2395
2417
trait_defs : RefCell :: new ( DefIdMap ( ) ) ,
2418
+ predicates : RefCell :: new ( DefIdMap ( ) ) ,
2396
2419
object_cast_map : RefCell :: new ( NodeMap ( ) ) ,
2397
2420
map : map,
2398
2421
intrinsic_defs : RefCell :: new ( DefIdMap ( ) ) ,
@@ -5378,13 +5401,23 @@ pub fn lookup_item_type<'tcx>(cx: &ctxt<'tcx>,
5378
5401
5379
5402
/// Given the did of a trait, returns its canonical trait ref.
5380
5403
pub fn lookup_trait_def < ' tcx > ( cx : & ctxt < ' tcx > , did : ast:: DefId )
5381
- -> Rc < ty :: TraitDef < ' tcx > > {
5404
+ -> Rc < TraitDef < ' tcx > > {
5382
5405
memoized ( & cx. trait_defs , did, |did : DefId | {
5383
5406
assert ! ( did. krate != ast:: LOCAL_CRATE ) ;
5384
5407
Rc :: new ( csearch:: get_trait_def ( cx, did) )
5385
5408
} )
5386
5409
}
5387
5410
5411
+ /// Given the did of a trait, returns its full set of predicates.
5412
+ pub fn lookup_predicates < ' tcx > ( cx : & ctxt < ' tcx > , did : ast:: DefId )
5413
+ -> GenericPredicates < ' tcx >
5414
+ {
5415
+ memoized ( & cx. predicates , did, |did : DefId | {
5416
+ assert ! ( did. krate != ast:: LOCAL_CRATE ) ;
5417
+ csearch:: get_predicates ( cx, did)
5418
+ } )
5419
+ }
5420
+
5388
5421
/// Given a reference to a trait, returns the "superbounds" declared
5389
5422
/// on the trait, with appropriate substitutions applied. Basically,
5390
5423
/// this applies a filter to the where clauses on the trait, returning
0 commit comments