提交 d1630970 编写于 作者: N Niko Matsakis

Split the predicates listing out of `TraitDef` and `TypeScheme` and into a...

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.
上级 bea8b812
......@@ -192,7 +192,8 @@ pub fn def_id(&self) -> ast::DefId {
#[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 @@ pub fn new(name: ast::Name,
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 @@ pub fn to_early_bound_region(&self) -> ty::Region {
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 @@ pub fn empty() -> 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 @@ pub fn has_type_params(&self, space: subst::ParamSpace) -> bool {
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 @@ pub fn to_opt_poly_trait_ref(&self) -> Option<PolyTraitRef<'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 @@ pub fn to_opt_poly_trait_ref(&self) -> Option<PolyTraitRef<'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 @@ pub fn for_item(cx: &'a ctxt<'tcx>, id: NodeId) -> 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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册