Skip to content

Commit d163097

Browse files
committed
Split the predicates listing out of TraitDef and TypeScheme and into a separate map, tcx.predicates, that is used for both traits and other kinds of items. Also use two newtypes to distinguish
instantiated predicates from the raw, unsubstituted predicates extracted from the map.
1 parent bea8b81 commit d163097

File tree

1 file changed

+54
-21
lines changed

1 file changed

+54
-21
lines changed

src/librustc/middle/ty.rs

+54-21
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,8 @@ impl ImplOrTraitItemId {
192192
#[derive(Clone, Debug)]
193193
pub struct Method<'tcx> {
194194
pub name: ast::Name,
195-
pub generics: ty::Generics<'tcx>,
195+
pub generics: Generics<'tcx>,
196+
pub predicates: GenericPredicates<'tcx>,
196197
pub fty: BareFnTy<'tcx>,
197198
pub explicit_self: ExplicitSelfCategory,
198199
pub vis: ast::Visibility,
@@ -206,6 +207,7 @@ pub struct Method<'tcx> {
206207
impl<'tcx> Method<'tcx> {
207208
pub fn new(name: ast::Name,
208209
generics: ty::Generics<'tcx>,
210+
predicates: GenericPredicates<'tcx>,
209211
fty: BareFnTy<'tcx>,
210212
explicit_self: ExplicitSelfCategory,
211213
vis: ast::Visibility,
@@ -216,6 +218,7 @@ impl<'tcx> Method<'tcx> {
216218
Method {
217219
name: name,
218220
generics: generics,
221+
predicates: predicates,
219222
fty: fty,
220223
explicit_self: explicit_self,
221224
vis: vis,
@@ -710,6 +713,10 @@ pub struct ctxt<'tcx> {
710713
pub trait_refs: RefCell<NodeMap<Rc<TraitRef<'tcx>>>>,
711714
pub trait_defs: RefCell<DefIdMap<Rc<TraitDef<'tcx>>>>,
712715

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+
713720
/// Maps from node-id of a trait object cast (like `foo as
714721
/// Box<Trait>`) to the trait reference.
715722
pub object_cast_map: ObjectCastMap<'tcx>,
@@ -1782,33 +1789,45 @@ impl RegionParameterDef {
17821789
pub struct Generics<'tcx> {
17831790
pub types: VecPerParamSpace<TypeParameterDef<'tcx>>,
17841791
pub regions: VecPerParamSpace<RegionParameterDef>,
1785-
pub predicates: VecPerParamSpace<Predicate<'tcx>>,
17861792
}
17871793

17881794
impl<'tcx> Generics<'tcx> {
17891795
pub fn empty() -> Generics<'tcx> {
17901796
Generics {
17911797
types: VecPerParamSpace::empty(),
17921798
regions: VecPerParamSpace::empty(),
1793-
predicates: VecPerParamSpace::empty(),
17941799
}
17951800
}
17961801

1802+
pub fn is_empty(&self) -> bool {
1803+
self.types.is_empty() && self.regions.is_empty()
1804+
}
1805+
17971806
pub fn has_type_params(&self, space: subst::ParamSpace) -> bool {
17981807
!self.types.is_empty_in(space)
17991808
}
18001809

18011810
pub fn has_region_params(&self, space: subst::ParamSpace) -> bool {
18021811
!self.regions.is_empty_in(space)
18031812
}
1813+
}
18041814

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+
}
18071826
}
18081827

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 {
18121831
predicates: self.predicates.subst(tcx, substs),
18131832
}
18141833
}
@@ -2022,11 +2041,11 @@ impl<'tcx> Predicate<'tcx> {
20222041

20232042
/// Represents the bounds declared on a particular set of type
20242043
/// 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
20302049
/// represented a set of bounds for some particular instantiation,
20312050
/// meaning that the generic parameters have been substituted with
20322051
/// their values.
@@ -2035,18 +2054,18 @@ impl<'tcx> Predicate<'tcx> {
20352054
///
20362055
/// struct Foo<T,U:Bar<T>> { ... }
20372056
///
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
20392058
/// `[[], [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 `[[],
20412060
/// [uint:Bar<int>]]`.
20422061
#[derive(Clone, Debug)]
2043-
pub struct GenericBounds<'tcx> {
2062+
pub struct InstantiatedPredicates<'tcx> {
20442063
pub predicates: VecPerParamSpace<Predicate<'tcx>>,
20452064
}
20462065

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() }
20502069
}
20512070

20522071
pub fn has_escaping_regions(&self) -> bool {
@@ -2248,10 +2267,13 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
22482267
/// stray references in a comment or something). We try to reserve the
22492268
/// "poly" prefix to refer to higher-ranked things, as in
22502269
/// `PolyTraitRef`.
2270+
///
2271+
/// Note that each item also comes with predicates, see
2272+
/// `lookup_predicates`.
22512273
#[derive(Clone, Debug)]
22522274
pub struct TypeScheme<'tcx> {
22532275
pub generics: Generics<'tcx>,
2254-
pub ty: Ty<'tcx>
2276+
pub ty: Ty<'tcx>,
22552277
}
22562278

22572279
/// As `TypeScheme` but for a trait ref.
@@ -2393,6 +2415,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
23932415
item_substs: RefCell::new(NodeMap()),
23942416
trait_refs: RefCell::new(NodeMap()),
23952417
trait_defs: RefCell::new(DefIdMap()),
2418+
predicates: RefCell::new(DefIdMap()),
23962419
object_cast_map: RefCell::new(NodeMap()),
23972420
map: map,
23982421
intrinsic_defs: RefCell::new(DefIdMap()),
@@ -5378,13 +5401,23 @@ pub fn lookup_item_type<'tcx>(cx: &ctxt<'tcx>,
53785401

53795402
/// Given the did of a trait, returns its canonical trait ref.
53805403
pub fn lookup_trait_def<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
5381-
-> Rc<ty::TraitDef<'tcx>> {
5404+
-> Rc<TraitDef<'tcx>> {
53825405
memoized(&cx.trait_defs, did, |did: DefId| {
53835406
assert!(did.krate != ast::LOCAL_CRATE);
53845407
Rc::new(csearch::get_trait_def(cx, did))
53855408
})
53865409
}
53875410

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+
53885421
/// Given a reference to a trait, returns the "superbounds" declared
53895422
/// on the trait, with appropriate substitutions applied. Basically,
53905423
/// this applies a filter to the where clauses on the trait, returning

0 commit comments

Comments
 (0)