integrate trait aliases into def-paths / metadata
Co-authored-by: Alexander Regueiro <alexreg@me.com>
This commit is contained in:
parent
430553bc77
commit
1336b8e8c7
@ -120,10 +120,10 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
||||
let def_data = match i.node {
|
||||
ItemKind::Impl(..) => DefPathData::Impl,
|
||||
ItemKind::Trait(..) => DefPathData::Trait(i.ident.as_interned_str()),
|
||||
ItemKind::TraitAlias(..) => DefPathData::TraitAlias(i.ident.as_interned_str()),
|
||||
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) |
|
||||
ItemKind::TraitAlias(..) | ItemKind::Existential(..) |
|
||||
ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::Ty(..) =>
|
||||
DefPathData::TypeNs(i.ident.as_interned_str()),
|
||||
ItemKind::Existential(..) | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) |
|
||||
ItemKind::Ty(..) => DefPathData::TypeNs(i.ident.as_interned_str()),
|
||||
ItemKind::Mod(..) if i.ident == keywords::Invalid.ident() => {
|
||||
return visit::walk_item(self, i);
|
||||
}
|
||||
|
@ -373,7 +373,9 @@ pub enum DefPathData {
|
||||
/// GlobalMetaData identifies a piece of crate metadata that is global to
|
||||
/// a whole crate (as opposed to just one item). GlobalMetaData components
|
||||
/// are only supposed to show up right below the crate root.
|
||||
GlobalMetaData(InternedString)
|
||||
GlobalMetaData(InternedString),
|
||||
/// A trait alias.
|
||||
TraitAlias(InternedString),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug,
|
||||
@ -615,6 +617,7 @@ impl DefPathData {
|
||||
match *self {
|
||||
TypeNs(name) |
|
||||
Trait(name) |
|
||||
TraitAlias(name) |
|
||||
AssocTypeInTrait(name) |
|
||||
AssocTypeInImpl(name) |
|
||||
AssocExistentialInImpl(name) |
|
||||
@ -642,6 +645,7 @@ impl DefPathData {
|
||||
let s = match *self {
|
||||
TypeNs(name) |
|
||||
Trait(name) |
|
||||
TraitAlias(name) |
|
||||
AssocTypeInTrait(name) |
|
||||
AssocTypeInImpl(name) |
|
||||
AssocExistentialInImpl(name) |
|
||||
|
@ -2154,7 +2154,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
|
||||
let def_id = obligation.predicate.def_id();
|
||||
|
||||
if ty::is_trait_alias(self.tcx(), def_id) {
|
||||
if self.tcx().is_trait_alias(def_id) {
|
||||
candidates.vec.push(TraitAliasCandidate(def_id.clone()));
|
||||
}
|
||||
|
||||
|
@ -311,6 +311,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
data @ DefPathData::Misc |
|
||||
data @ DefPathData::TypeNs(..) |
|
||||
data @ DefPathData::Trait(..) |
|
||||
data @ DefPathData::TraitAlias(..) |
|
||||
data @ DefPathData::AssocTypeInTrait(..) |
|
||||
data @ DefPathData::AssocTypeInImpl(..) |
|
||||
data @ DefPathData::AssocExistentialInImpl(..) |
|
||||
|
@ -3178,18 +3178,6 @@ pub fn is_impl_trait_defn(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Option<DefI
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns `true` if `def_id` is a trait alias.
|
||||
pub fn is_trait_alias(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> bool {
|
||||
if let Some(node_id) = tcx.hir().as_local_node_id(def_id) {
|
||||
if let Node::Item(item) = tcx.hir().get(node_id) {
|
||||
if let hir::ItemKind::TraitAlias(..) = item.node {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// See `ParamEnv` struct definition for details.
|
||||
fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
def_id: DefId)
|
||||
|
@ -526,6 +526,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// True if `def_id` refers to a trait alias (i.e., `trait Foo = ...;`).
|
||||
pub fn is_trait_alias(self, def_id: DefId) -> bool {
|
||||
if let DefPathData::TraitAlias(_) = self.def_key(def_id).disambiguated_data.data {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// True if this def-id refers to the implicit constructor for
|
||||
/// a tuple struct like `struct Foo(u32)`.
|
||||
pub fn is_struct_constructor(self, def_id: DefId) -> bool {
|
||||
|
@ -409,6 +409,7 @@ impl PrintContext {
|
||||
DefPathData::AssocTypeInImpl(_) |
|
||||
DefPathData::AssocExistentialInImpl(_) |
|
||||
DefPathData::Trait(_) |
|
||||
DefPathData::TraitAlias(_) |
|
||||
DefPathData::Impl |
|
||||
DefPathData::TypeNs(_) => {
|
||||
break;
|
||||
|
@ -418,6 +418,7 @@ impl<'tcx> EntryKind<'tcx> {
|
||||
EntryKind::Mod(_) => Def::Mod(did),
|
||||
EntryKind::Variant(_) => Def::Variant(did),
|
||||
EntryKind::Trait(_) => Def::Trait(did),
|
||||
EntryKind::TraitAlias(_) => Def::TraitAlias(did),
|
||||
EntryKind::Enum(..) => Def::Enum(did),
|
||||
EntryKind::MacroDef(_) => Def::Macro(did, MacroKind::Bang),
|
||||
EntryKind::ForeignType => Def::ForeignTy(did),
|
||||
@ -520,17 +521,26 @@ impl<'a, 'tcx> CrateMetadata {
|
||||
}
|
||||
|
||||
pub fn get_trait_def(&self, item_id: DefIndex, sess: &Session) -> ty::TraitDef {
|
||||
let data = match self.entry(item_id).kind {
|
||||
EntryKind::Trait(data) => data.decode((self, sess)),
|
||||
_ => bug!(),
|
||||
};
|
||||
|
||||
ty::TraitDef::new(self.local_def_id(item_id),
|
||||
data.unsafety,
|
||||
data.paren_sugar,
|
||||
data.has_auto_impl,
|
||||
data.is_marker,
|
||||
self.def_path_table.def_path_hash(item_id))
|
||||
match self.entry(item_id).kind {
|
||||
EntryKind::Trait(data) => {
|
||||
let data = data.decode((self, sess));
|
||||
ty::TraitDef::new(self.local_def_id(item_id),
|
||||
data.unsafety,
|
||||
data.paren_sugar,
|
||||
data.has_auto_impl,
|
||||
data.is_marker,
|
||||
self.def_path_table.def_path_hash(item_id))
|
||||
},
|
||||
EntryKind::TraitAlias(_) => {
|
||||
ty::TraitDef::new(self.local_def_id(item_id),
|
||||
hir::Unsafety::Normal,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
self.def_path_table.def_path_hash(item_id))
|
||||
},
|
||||
_ => bug!("def-index does not refer to trait or trait alias"),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_variant(&self,
|
||||
@ -615,10 +625,13 @@ impl<'a, 'tcx> CrateMetadata {
|
||||
item_id: DefIndex,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>)
|
||||
-> ty::GenericPredicates<'tcx> {
|
||||
match self.entry(item_id).kind {
|
||||
EntryKind::Trait(data) => data.decode(self).super_predicates.decode((self, tcx)),
|
||||
_ => bug!(),
|
||||
}
|
||||
let super_predicates = match self.entry(item_id).kind {
|
||||
EntryKind::Trait(data) => data.decode(self).super_predicates,
|
||||
EntryKind::TraitAlias(data) => data.decode(self).super_predicates,
|
||||
_ => bug!("def-index does not refer to trait or trait alias"),
|
||||
};
|
||||
|
||||
super_predicates.decode((self, tcx))
|
||||
}
|
||||
|
||||
pub fn get_generics(&self,
|
||||
@ -1014,7 +1027,8 @@ impl<'a, 'tcx> CrateMetadata {
|
||||
}
|
||||
def_key.parent.and_then(|parent_index| {
|
||||
match self.entry(parent_index).kind {
|
||||
EntryKind::Trait(_) => Some(self.local_def_id(parent_index)),
|
||||
EntryKind::Trait(_) |
|
||||
EntryKind::TraitAlias(_) => Some(self.local_def_id(parent_index)),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
|
@ -1131,8 +1131,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
||||
|
||||
EntryKind::Impl(self.lazy(&data))
|
||||
}
|
||||
hir::ItemKind::Trait(..) |
|
||||
hir::ItemKind::TraitAlias(..) => {
|
||||
hir::ItemKind::Trait(..) => {
|
||||
let trait_def = tcx.trait_def(def_id);
|
||||
let data = TraitData {
|
||||
unsafety: trait_def.unsafety,
|
||||
@ -1144,6 +1143,13 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
||||
|
||||
EntryKind::Trait(self.lazy(&data))
|
||||
}
|
||||
hir::ItemKind::TraitAlias(..) => {
|
||||
let data = TraitAliasData {
|
||||
super_predicates: self.lazy(&tcx.super_predicates_of(def_id)),
|
||||
};
|
||||
|
||||
EntryKind::TraitAlias(self.lazy(&data))
|
||||
}
|
||||
hir::ItemKind::ExternCrate(_) |
|
||||
hir::ItemKind::Use(..) => bug!("cannot encode info for item {:?}", item),
|
||||
};
|
||||
@ -1217,6 +1223,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
||||
hir::ItemKind::Impl(..) |
|
||||
hir::ItemKind::Existential(..) |
|
||||
hir::ItemKind::Trait(..) => Some(self.encode_generics(def_id)),
|
||||
hir::ItemKind::TraitAlias(..) => Some(self.encode_generics(def_id)),
|
||||
_ => None,
|
||||
},
|
||||
predicates: match item.node {
|
||||
@ -1229,7 +1236,8 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
||||
hir::ItemKind::Union(..) |
|
||||
hir::ItemKind::Impl(..) |
|
||||
hir::ItemKind::Existential(..) |
|
||||
hir::ItemKind::Trait(..) => Some(self.encode_predicates(def_id)),
|
||||
hir::ItemKind::Trait(..) |
|
||||
hir::ItemKind::TraitAlias(..) => Some(self.encode_predicates(def_id)),
|
||||
_ => None,
|
||||
},
|
||||
|
||||
@ -1239,7 +1247,8 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
||||
// hack. (No reason not to expand it in the future if
|
||||
// necessary.)
|
||||
predicates_defined_on: match item.node {
|
||||
hir::ItemKind::Trait(..) => Some(self.encode_predicates_defined_on(def_id)),
|
||||
hir::ItemKind::Trait(..) |
|
||||
hir::ItemKind::TraitAlias(..) => Some(self.encode_predicates_defined_on(def_id)),
|
||||
_ => None, // not *wrong* for other kinds of items, but not needed
|
||||
},
|
||||
|
||||
|
@ -316,6 +316,7 @@ pub enum EntryKind<'tcx> {
|
||||
AssociatedType(AssociatedContainer),
|
||||
AssociatedExistential(AssociatedContainer),
|
||||
AssociatedConst(AssociatedContainer, ConstQualif, Lazy<RenderedConst>),
|
||||
TraitAlias(Lazy<TraitAliasData<'tcx>>),
|
||||
}
|
||||
|
||||
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for EntryKind<'gcx> {
|
||||
@ -370,6 +371,9 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for EntryKind<'gcx> {
|
||||
EntryKind::Trait(ref trait_data) => {
|
||||
trait_data.hash_stable(hcx, hasher);
|
||||
}
|
||||
EntryKind::TraitAlias(ref trait_alias_data) => {
|
||||
trait_alias_data.hash_stable(hcx, hasher);
|
||||
}
|
||||
EntryKind::Impl(ref impl_data) => {
|
||||
impl_data.hash_stable(hcx, hasher);
|
||||
}
|
||||
@ -474,6 +478,15 @@ impl_stable_hash_for!(struct TraitData<'tcx> {
|
||||
super_predicates
|
||||
});
|
||||
|
||||
#[derive(RustcEncodable, RustcDecodable)]
|
||||
pub struct TraitAliasData<'tcx> {
|
||||
pub super_predicates: Lazy<ty::GenericPredicates<'tcx>>,
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(struct TraitAliasData<'tcx> {
|
||||
super_predicates
|
||||
});
|
||||
|
||||
#[derive(RustcEncodable, RustcDecodable)]
|
||||
pub struct ImplData<'tcx> {
|
||||
pub polarity: hir::ImplPolarity,
|
||||
|
@ -673,6 +673,9 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
module.populated.set(true);
|
||||
}
|
||||
Def::TraitAlias(..) => {
|
||||
self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion));
|
||||
}
|
||||
Def::Struct(..) | Def::Union(..) => {
|
||||
self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion));
|
||||
|
||||
|
@ -158,7 +158,8 @@ crate fn program_clauses_for<'a, 'tcx>(
|
||||
def_id: DefId,
|
||||
) -> Clauses<'tcx> {
|
||||
match tcx.def_key(def_id).disambiguated_data.data {
|
||||
DefPathData::Trait(_) => program_clauses_for_trait(tcx, def_id),
|
||||
DefPathData::Trait(_) |
|
||||
DefPathData::TraitAlias(_) => program_clauses_for_trait(tcx, def_id),
|
||||
DefPathData::Impl => program_clauses_for_impl(tcx, def_id),
|
||||
DefPathData::AssocTypeInImpl(..) => program_clauses_for_associated_type_value(tcx, def_id),
|
||||
DefPathData::AssocTypeInTrait(..) => program_clauses_for_associated_type_def(tcx, def_id),
|
||||
|
@ -706,7 +706,7 @@ fn super_predicates_of<'a, 'tcx>(
|
||||
// In the case of trait aliases, however, we include all bounds in the where clause,
|
||||
// so e.g., `trait Foo = where u32: PartialEq<Self>` would include `u32: PartialEq<Self>`
|
||||
// as one of its "superpredicates".
|
||||
let is_trait_alias = ty::is_trait_alias(tcx, trait_def_id);
|
||||
let is_trait_alias = tcx.is_trait_alias(trait_def_id);
|
||||
let superbounds2 = icx.type_parameter_bounds_in_generics(
|
||||
generics, item.id, self_param_ty, OnlySelfBounds(!is_trait_alias));
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user