about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2015-02-11 06:54:05 -0500
committerNiko Matsakis <niko@alum.mit.edu>2015-02-12 13:02:37 -0500
commitd1630970deaf3fce2b0c4671acaeb8edfd07bc7e (patch)
tree12b80d7415d9a8ed6355810917efc4aa1ad8f3f8
parentbea8b81225372ebbcb42fc5a2b6f468b2df402ba (diff)
downloadrust-d1630970deaf3fce2b0c4671acaeb8edfd07bc7e.tar.gz
rust-d1630970deaf3fce2b0c4671acaeb8edfd07bc7e.zip
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.
-rw-r--r--src/librustc/middle/ty.rs75
1 files changed, 54 insertions, 21 deletions
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 8e94991f656..af80ce65474 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -192,7 +192,8 @@ impl ImplOrTraitItemId {
 #[derive(Clone, Debug)]
 pub struct Method<'tcx> {
     pub name: ast::Name,
-    pub generics: ty::Generics<'tcx>,
+    pub generics: Generics<'tcx>,
+    pub predicates: GenericPredicates<'tcx>,
     pub fty: BareFnTy<'tcx>,
     pub explicit_self: ExplicitSelfCategory,
     pub vis: ast::Visibility,
@@ -206,6 +207,7 @@ pub struct Method<'tcx> {
 impl<'tcx> Method<'tcx> {
     pub fn new(name: ast::Name,
                generics: ty::Generics<'tcx>,
+               predicates: GenericPredicates<'tcx>,
                fty: BareFnTy<'tcx>,
                explicit_self: ExplicitSelfCategory,
                vis: ast::Visibility,
@@ -216,6 +218,7 @@ impl<'tcx> Method<'tcx> {
        Method {
             name: name,
             generics: generics,
+            predicates: predicates,
             fty: fty,
             explicit_self: explicit_self,
             vis: vis,
@@ -710,6 +713,10 @@ pub struct ctxt<'tcx> {
     pub trait_refs: RefCell<NodeMap<Rc<TraitRef<'tcx>>>>,
     pub trait_defs: RefCell<DefIdMap<Rc<TraitDef<'tcx>>>>,
 
+    /// Maps from the def-id of an item (trait/struct/enum/fn) to its
+    /// associated predicates.
+    pub predicates: RefCell<DefIdMap<GenericPredicates<'tcx>>>,
+
     /// Maps from node-id of a trait object cast (like `foo as
     /// Box<Trait>`) to the trait reference.
     pub object_cast_map: ObjectCastMap<'tcx>,
@@ -1782,7 +1789,6 @@ impl RegionParameterDef {
 pub struct Generics<'tcx> {
     pub types: VecPerParamSpace<TypeParameterDef<'tcx>>,
     pub regions: VecPerParamSpace<RegionParameterDef>,
-    pub predicates: VecPerParamSpace<Predicate<'tcx>>,
 }
 
 impl<'tcx> Generics<'tcx> {
@@ -1790,10 +1796,13 @@ impl<'tcx> Generics<'tcx> {
         Generics {
             types: VecPerParamSpace::empty(),
             regions: VecPerParamSpace::empty(),
-            predicates: VecPerParamSpace::empty(),
         }
     }
 
+    pub fn is_empty(&self) -> bool {
+        self.types.is_empty() && self.regions.is_empty()
+    }
+
     pub fn has_type_params(&self, space: subst::ParamSpace) -> bool {
         !self.types.is_empty_in(space)
     }
@@ -1801,14 +1810,24 @@ impl<'tcx> Generics<'tcx> {
     pub fn has_region_params(&self, space: subst::ParamSpace) -> bool {
         !self.regions.is_empty_in(space)
     }
+}
 
-    pub fn is_empty(&self) -> bool {
-        self.types.is_empty() && self.regions.is_empty()
+/// Bounds on generics.
+#[derive(Clone, Debug)]
+pub struct GenericPredicates<'tcx> {
+    pub predicates: VecPerParamSpace<Predicate<'tcx>>,
+}
+
+impl<'tcx> GenericPredicates<'tcx> {
+    pub fn empty() -> GenericPredicates<'tcx> {
+        GenericPredicates {
+            predicates: VecPerParamSpace::empty(),
+        }
     }
 
-    pub fn to_bounds(&self, tcx: &ty::ctxt<'tcx>, substs: &Substs<'tcx>)
-                     -> GenericBounds<'tcx> {
-        GenericBounds {
+    pub fn instantiate(&self, tcx: &ty::ctxt<'tcx>, substs: &Substs<'tcx>)
+                       -> InstantiatedPredicates<'tcx> {
+        InstantiatedPredicates {
             predicates: self.predicates.subst(tcx, substs),
         }
     }
@@ -2022,11 +2041,11 @@ impl<'tcx> Predicate<'tcx> {
 
 /// Represents the bounds declared on a particular set of type
 /// parameters.  Should eventually be generalized into a flag list of
-/// where clauses.  You can obtain a `GenericBounds` list from a
-/// `Generics` by using the `to_bounds` method. Note that this method
-/// reflects an important semantic invariant of `GenericBounds`: while
-/// the bounds in a `Generics` are expressed in terms of the bound type
-/// parameters of the impl/trait/whatever, a `GenericBounds` instance
+/// where clauses.  You can obtain a `InstantiatedPredicates` list from a
+/// `GenericPredicates` by using the `instantiate` method. Note that this method
+/// reflects an important semantic invariant of `InstantiatedPredicates`: while
+/// the `GenericPredicates` are expressed in terms of the bound type
+/// parameters of the impl/trait/whatever, an `InstantiatedPredicates` instance
 /// represented a set of bounds for some particular instantiation,
 /// meaning that the generic parameters have been substituted with
 /// their values.
@@ -2035,18 +2054,18 @@ impl<'tcx> Predicate<'tcx> {
 ///
 ///     struct Foo<T,U:Bar<T>> { ... }
 ///
-/// Here, the `Generics` for `Foo` would contain a list of bounds like
+/// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like
 /// `[[], [U:Bar<T>]]`.  Now if there were some particular reference
-/// like `Foo<int,uint>`, then the `GenericBounds` would be `[[],
+/// like `Foo<int,uint>`, then the `InstantiatedPredicates` would be `[[],
 /// [uint:Bar<int>]]`.
 #[derive(Clone, Debug)]
-pub struct GenericBounds<'tcx> {
+pub struct InstantiatedPredicates<'tcx> {
     pub predicates: VecPerParamSpace<Predicate<'tcx>>,
 }
 
-impl<'tcx> GenericBounds<'tcx> {
-    pub fn empty() -> GenericBounds<'tcx> {
-        GenericBounds { predicates: VecPerParamSpace::empty() }
+impl<'tcx> InstantiatedPredicates<'tcx> {
+    pub fn empty() -> InstantiatedPredicates<'tcx> {
+        InstantiatedPredicates { predicates: VecPerParamSpace::empty() }
     }
 
     pub fn has_escaping_regions(&self) -> bool {
@@ -2248,10 +2267,13 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
 /// stray references in a comment or something). We try to reserve the
 /// "poly" prefix to refer to higher-ranked things, as in
 /// `PolyTraitRef`.
+///
+/// Note that each item also comes with predicates, see
+/// `lookup_predicates`.
 #[derive(Clone, Debug)]
 pub struct TypeScheme<'tcx> {
     pub generics: Generics<'tcx>,
-    pub ty: Ty<'tcx>
+    pub ty: Ty<'tcx>,
 }
 
 /// As `TypeScheme` but for a trait ref.
@@ -2393,6 +2415,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
         item_substs: RefCell::new(NodeMap()),
         trait_refs: RefCell::new(NodeMap()),
         trait_defs: RefCell::new(DefIdMap()),
+        predicates: RefCell::new(DefIdMap()),
         object_cast_map: RefCell::new(NodeMap()),
         map: map,
         intrinsic_defs: RefCell::new(DefIdMap()),
@@ -5378,13 +5401,23 @@ pub fn lookup_item_type<'tcx>(cx: &ctxt<'tcx>,
 
 /// Given the did of a trait, returns its canonical trait ref.
 pub fn lookup_trait_def<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
-                              -> Rc<ty::TraitDef<'tcx>> {
+                              -> Rc<TraitDef<'tcx>> {
     memoized(&cx.trait_defs, did, |did: DefId| {
         assert!(did.krate != ast::LOCAL_CRATE);
         Rc::new(csearch::get_trait_def(cx, did))
     })
 }
 
+/// Given the did of a trait, returns its full set of predicates.
+pub fn lookup_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
+                                -> GenericPredicates<'tcx>
+{
+    memoized(&cx.predicates, did, |did: DefId| {
+        assert!(did.krate != ast::LOCAL_CRATE);
+        csearch::get_predicates(cx, did)
+    })
+}
+
 /// Given a reference to a trait, returns the "superbounds" declared
 /// on the trait, with appropriate substitutions applied. Basically,
 /// this applies a filter to the where clauses on the trait, returning