diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2015-02-11 06:54:05 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2015-02-12 13:02:37 -0500 |
| commit | d1630970deaf3fce2b0c4671acaeb8edfd07bc7e (patch) | |
| tree | 12b80d7415d9a8ed6355810917efc4aa1ad8f3f8 | |
| parent | bea8b81225372ebbcb42fc5a2b6f468b2df402ba (diff) | |
| download | rust-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.rs | 75 |
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 |
