ItemSignature(D),
FieldTy(D),
SizedConstraint(D),
- ImplOrTraitItemIds(D),
+ ImplOrTraitItemDefIds(D),
InherentImpls(D),
// The set of impls for a given trait. Ultimately, it would be
ImplOrTraitItems,
ItemSignature,
FieldTy,
- ImplOrTraitItemIds,
+ ImplOrTraitItemDefIds,
InherentImpls,
TraitImpls,
ReprHints,
ItemSignature(ref d) => op(d).map(ItemSignature),
FieldTy(ref d) => op(d).map(FieldTy),
SizedConstraint(ref d) => op(d).map(SizedConstraint),
- ImplOrTraitItemIds(ref d) => op(d).map(ImplOrTraitItemIds),
+ ImplOrTraitItemDefIds(ref d) => op(d).map(ImplOrTraitItemDefIds),
InherentImpls(ref d) => op(d).map(InherentImpls),
TraitImpls(ref d) => op(d).map(TraitImpls),
TraitItems(ref d) => op(d).map(TraitItems),
fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>;
// impl info
- fn impl_or_trait_items(&self, def_id: DefId) -> Vec<ty::ImplOrTraitItemId>;
+ fn impl_or_trait_items(&self, def_id: DefId) -> Vec<DefId>;
fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> Option<ty::TraitRef<'tcx>>;
fn impl_polarity(&self, def: DefId) -> hir::ImplPolarity;
}
// impl info
- fn impl_or_trait_items(&self, def_id: DefId) -> Vec<ty::ImplOrTraitItemId>
+ fn impl_or_trait_items(&self, def_id: DefId) -> Vec<DefId>
{ bug!("impl_or_trait_items") }
fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> Option<ty::TraitRef<'tcx>> { bug!("impl_trait_ref") }
// This is done to handle the case where, for example, the static
// method of a private type is used, but the type itself is never
// called directly.
- let impl_items = self.tcx.impl_or_trait_item_ids.borrow();
+ let impl_items = self.tcx.impl_or_trait_item_def_ids.borrow();
if let Some(impl_list) =
self.tcx.inherent_impls.borrow().get(&self.tcx.map.local_def_id(id)) {
for impl_did in impl_list.iter() {
- for item_did in impl_items.get(impl_did).unwrap().iter() {
- if let Some(item_node_id) =
- self.tcx.map.as_local_node_id(item_did.def_id()) {
+ for &item_did in &impl_items[impl_did][..] {
+ if let Some(item_node_id) = self.tcx.map.as_local_node_id(item_did) {
if self.live_symbols.contains(&item_node_id) {
return true;
}
fn is_staged_api<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> bool {
match tcx.trait_item_of_item(id) {
- Some(ty::MethodTraitItemId(trait_method_id))
- if trait_method_id != id => {
- is_staged_api(tcx, trait_method_id)
- }
+ Some(trait_method_id) if trait_method_id != id => {
+ is_staged_api(tcx, trait_method_id)
+ }
_ => {
*tcx.stability.borrow_mut().staged_api.entry(id.krate).or_insert_with(
|| tcx.sess.cstore.is_staged_api(id.krate))
/// An iterator over the items defined within a trait or impl.
pub struct NodeItems<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
- items: Rc<Vec<ty::ImplOrTraitItemId>>,
+ items: Rc<Vec<DefId>>,
idx: usize
}
type Item = ImplOrTraitItem<'tcx>;
fn next(&mut self) -> Option<ImplOrTraitItem<'tcx>> {
if self.idx < self.items.len() {
- let item_def_id = self.items[self.idx].def_id();
+ let item_def_id = self.items[self.idx];
let items_table = self.tcx.impl_or_trait_items.borrow();
let item = items_table[&item_def_id].clone();
self.idx += 1;
pub impl_or_trait_items: RefCell<DepTrackingMap<maps::ImplOrTraitItems<'tcx>>>,
/// Maps from an impl/trait def-id to a list of the def-ids of its items
- pub impl_or_trait_item_ids: RefCell<DepTrackingMap<maps::ImplOrTraitItemIds<'tcx>>>,
+ pub impl_or_trait_item_def_ids: RefCell<DepTrackingMap<maps::ImplOrTraitItemDefIds<'tcx>>>,
/// A cache for the trait_items() routine; note that the routine
/// itself pushes the `TraitItems` dependency node.
rcache: RefCell::new(FnvHashMap()),
tc_cache: RefCell::new(FnvHashMap()),
impl_or_trait_items: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
- impl_or_trait_item_ids: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
+ impl_or_trait_item_def_ids: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
trait_items_cache: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
ty_param_defs: RefCell::new(NodeMap()),
normalized_cache: RefCell::new(FnvHashMap()),
self.trait_items_cache.memoize(trait_did, || {
let def_ids = self.impl_or_trait_items(trait_did);
Rc::new(def_ids.iter()
- .map(|d| self.impl_or_trait_item(d.def_id()))
+ .map(|&def_id| self.impl_or_trait_item(def_id))
.collect())
})
}
dep_map_ty! { Generics: ItemSignature(DefId) -> &'tcx ty::Generics<'tcx> }
dep_map_ty! { Predicates: ItemSignature(DefId) -> ty::GenericPredicates<'tcx> }
dep_map_ty! { SuperPredicates: ItemSignature(DefId) -> ty::GenericPredicates<'tcx> }
-dep_map_ty! { ImplOrTraitItemIds: ImplOrTraitItemIds(DefId)
- -> Rc<Vec<ty::ImplOrTraitItemId>> }
+dep_map_ty! { ImplOrTraitItemDefIds: ImplOrTraitItemDefIds(DefId) -> Rc<Vec<DefId>> }
dep_map_ty! { ImplTraitRefs: ItemSignature(DefId) -> Option<ty::TraitRef<'tcx>> }
dep_map_ty! { TraitDefs: ItemSignature(DefId) -> &'tcx ty::TraitDef<'tcx> }
dep_map_ty! { AdtDefs: ItemSignature(DefId) -> ty::AdtDefMaster<'tcx> }
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-pub use self::ImplOrTraitItemId::*;
pub use self::Variance::*;
pub use self::DtorKind::*;
pub use self::ImplOrTraitItemContainer::*;
}
impl<'tcx> ImplOrTraitItem<'tcx> {
- fn id(&self) -> ImplOrTraitItemId {
- match *self {
- ConstTraitItem(ref associated_const) => {
- ConstTraitItemId(associated_const.def_id)
- }
- MethodTraitItem(ref method) => MethodTraitItemId(method.def_id),
- TypeTraitItem(ref associated_type) => {
- TypeTraitItemId(associated_type.def_id)
- }
- }
- }
-
pub fn def(&self) -> Def {
match *self {
ConstTraitItem(ref associated_const) => Def::AssociatedConst(associated_const.def_id),
}
}
-#[derive(Clone, Copy, Debug, RustcEncodable, RustcDecodable)]
-pub enum ImplOrTraitItemId {
- ConstTraitItemId(DefId),
- MethodTraitItemId(DefId),
- TypeTraitItemId(DefId),
-}
-
-impl ImplOrTraitItemId {
- pub fn def_id(&self) -> DefId {
- match *self {
- ConstTraitItemId(def_id) => def_id,
- MethodTraitItemId(def_id) => def_id,
- TypeTraitItemId(def_id) => def_id,
- }
- }
-}
-
#[derive(Clone, Debug, PartialEq, Eq, Copy, RustcEncodable, RustcDecodable)]
pub enum Visibility {
/// Visible everywhere (including in other crates).
}
pub fn provided_trait_methods(self, id: DefId) -> Vec<Rc<Method<'gcx>>> {
- self.impl_or_trait_items(id).iter().filter_map(|id| {
- match self.impl_or_trait_item(id.def_id()) {
+ self.impl_or_trait_items(id).iter().filter_map(|&def_id| {
+ match self.impl_or_trait_item(def_id) {
MethodTraitItem(ref m) if m.has_body => Some(m.clone()),
_ => None
}
.expect("missing ImplOrTraitItem in metadata"))
}
- pub fn impl_or_trait_items(self, id: DefId) -> Rc<Vec<ImplOrTraitItemId>> {
+ pub fn impl_or_trait_items(self, id: DefId) -> Rc<Vec<DefId>> {
lookup_locally_or_in_crate_store(
- "impl_or_trait_items", id, &self.impl_or_trait_item_ids,
+ "impl_or_trait_items", id, &self.impl_or_trait_item_def_ids,
|| Rc::new(self.sess.cstore.impl_or_trait_items(id)))
}
let impl_items = self.sess.cstore.impl_or_trait_items(primitive_def_id);
// Store the implementation info.
- self.impl_or_trait_item_ids.borrow_mut().insert(primitive_def_id, Rc::new(impl_items));
+ self.impl_or_trait_item_def_ids.borrow_mut().insert(primitive_def_id, Rc::new(impl_items));
self.populated_external_primitive_impls.borrow_mut().insert(primitive_def_id);
}
for &impl_def_id in &inherent_impls {
// Store the implementation info.
let impl_items = self.sess.cstore.impl_or_trait_items(impl_def_id);
- self.impl_or_trait_item_ids.borrow_mut().insert(impl_def_id, Rc::new(impl_items));
+ self.impl_or_trait_item_def_ids.borrow_mut().insert(impl_def_id, Rc::new(impl_items));
}
self.inherent_impls.borrow_mut().insert(type_id, inherent_impls);
// For any methods that use a default implementation, add them to
// the map. This is a bit unfortunate.
- for impl_item_def_id in &impl_items {
- let method_def_id = impl_item_def_id.def_id();
+ for &impl_item_def_id in &impl_items {
// load impl items eagerly for convenience
// FIXME: we may want to load these lazily
- self.impl_or_trait_item(method_def_id);
+ self.impl_or_trait_item(impl_item_def_id);
}
// Store the implementation info.
- self.impl_or_trait_item_ids.borrow_mut().insert(impl_def_id, Rc::new(impl_items));
+ self.impl_or_trait_item_def_ids.borrow_mut().insert(impl_def_id, Rc::new(impl_items));
}
def.flags.set(def.flags.get() | TraitFlags::IMPLS_VALID);
/// is already that of the original trait method, then the return value is
/// the same).
/// Otherwise, return `None`.
- pub fn trait_item_of_item(self, def_id: DefId) -> Option<ImplOrTraitItemId> {
+ pub fn trait_item_of_item(self, def_id: DefId) -> Option<DefId> {
let impl_or_trait_item = match self.impl_or_trait_items.borrow().get(&def_id) {
Some(m) => m.clone(),
None => return None,
};
match impl_or_trait_item.container() {
- TraitContainer(_) => Some(impl_or_trait_item.id()),
+ TraitContainer(_) => Some(impl_or_trait_item.def_id()),
ImplContainer(def_id) => {
self.trait_id_of_impl(def_id).and_then(|trait_did| {
let name = impl_or_trait_item.name();
self.trait_items(trait_did).iter()
.find(|item| item.name() == name)
- .map(|item| item.id())
+ .map(|item| item.def_id())
})
}
}
use ty::fast_reject;
use ty::{Ty, TyCtxt, TraitRef};
use std::cell::{Cell, RefCell};
-use syntax::ast::Name;
use hir;
use util::nodemap::FnvHashMap;
pub trait_ref: ty::TraitRef<'tcx>,
- /// A list of the associated types defined in this trait. Useful
- /// for resolving `X::Foo` type markers.
- pub associated_type_names: Vec<Name>,
-
// Impls of a trait. To allow for quicker lookup, the impls are indexed by a
// simplified version of their `Self` type: impls with a simplifiable `Self`
// are stored in `nonblanket_impls` keyed by it, while all other impls are
paren_sugar: bool,
generics: &'tcx ty::Generics<'tcx>,
trait_ref: ty::TraitRef<'tcx>,
- associated_type_names: Vec<Name>,
def_path_hash: u64)
-> TraitDef<'tcx> {
TraitDef {
unsafety: unsafety,
generics: generics,
trait_ref: trait_ref,
- associated_type_names: associated_type_names,
nonblanket_impls: RefCell::new(FnvHashMap()),
blanket_impls: RefCell::new(vec![]),
flags: Cell::new(ty::TraitFlags::NO_TRAIT_FLAGS),
match selection {
traits::VtableImpl(ref impl_data) => {
let ac = tcx.impl_or_trait_items(impl_data.impl_def_id)
- .iter().filter_map(|id| {
- match *id {
- ty::ConstTraitItemId(def_id) => {
- Some(tcx.impl_or_trait_item(def_id))
- }
+ .iter().filter_map(|&def_id| {
+ match tcx.impl_or_trait_item(def_id) {
+ ty::ConstTraitItem(ic) => Some(ic),
_ => None
}
- }).find(|ic| ic.name() == ti.name);
+ }).find(|ic| ic.name == ti.name);
match ac {
- Some(ic) => lookup_const_by_id(tcx, ic.def_id(), None),
+ Some(ic) => lookup_const_by_id(tcx, ic.def_id, None),
None => match ti.node {
hir::ConstTraitItem(ref ty, Some(ref expr)) => {
Some((&*expr, tcx.ast_ty_to_prim_ty(ty)))
pub const tag_unsafety: usize = 0x9a;
-pub const tag_associated_type_names: usize = 0x9b;
-pub const tag_associated_type_name: usize = 0x9c;
-
pub const tag_polarity: usize = 0x9d;
pub const tag_macro_defs: usize = 0x10e; // top-level only
result
}
- fn impl_or_trait_items(&self, def_id: DefId) -> Vec<ty::ImplOrTraitItemId> {
+ fn impl_or_trait_items(&self, def_id: DefId) -> Vec<DefId> {
self.dep_graph.read(DepNode::MetaData(def_id));
- let cdata = self.get_crate_data(def_id.krate);
- decoder::get_impl_or_trait_items(&cdata, def_id.index)
+ let mut result = vec![];
+ let crate_data = self.get_crate_data(def_id.krate);
+ let get_crate_data = |cnum| self.get_crate_data(cnum);
+ decoder::each_child_of_item(&crate_data, def_id.index, get_crate_data, |def, _, _| {
+ result.push(def.def_id());
+ });
+ result
}
fn impl_polarity(&self, def: DefId) -> hir::ImplPolarity
})
}
-fn parse_associated_type_names(item_doc: rbml::Doc) -> Vec<ast::Name> {
- item_doc.get(tag_associated_type_names).decoder().decode()
-}
-
pub fn get_trait_def<'a, 'tcx>(cdata: Cmd,
item_id: DefIndex,
tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::TraitDef<'tcx>
let item_doc = cdata.lookup_item(item_id);
let generics = doc_generics(item_doc, tcx, cdata);
let unsafety = item_doc.get(tag_unsafety).decoder().decode();
- let associated_type_names = parse_associated_type_names(item_doc);
let paren_sugar = item_doc.get(tag_paren_sugar).decoder().decode();
let trait_ref = doc_trait_ref(item_doc.get(tag_item_trait_ref), tcx, cdata);
let def_path = def_path(cdata, item_id).unwrap();
- ty::TraitDef::new(unsafety,
- paren_sugar,
- generics,
- trait_ref,
- associated_type_names,
+ ty::TraitDef::new(unsafety, paren_sugar, generics, trait_ref,
def_path.deterministic_hash(tcx))
}
dcx.decode()
}
-/// Returns the def IDs of all the items in the given implementation.
-pub fn get_impl_or_trait_items(cdata: Cmd, impl_id: DefIndex)
- -> Vec<ty::ImplOrTraitItemId> {
- let item = cdata.lookup_item(impl_id);
- let mut dcx = item.get(tag_mod_children).decoder();
- dcx.cdata = Some(cdata);
- dcx.seq().map(|def_id: DefId| {
- match item_to_def(cdata, cdata.lookup_item(def_id.index), def_id) {
- Some(Def::AssociatedConst(def_id)) => ty::ConstTraitItemId(def_id),
- Some(Def::Method(def_id)) => ty::MethodTraitItemId(def_id),
- Some(Def::AssociatedTy(_, def_id)) => ty::TypeTraitItemId(def_id),
- def => bug!("get_impl_or_trait_items: invalid def {:?}", def)
- }
- }).collect()
-}
-
pub fn get_trait_name(cdata: Cmd, id: DefIndex) -> ast::Name {
let doc = cdata.lookup_item(id);
item_name(doc)
}
self.start_tag(tag_mod_children);
- let items = tcx.impl_or_trait_items(def_id);
- self.seq(&items[..], |_, id| id.def_id());
+ tcx.impl_or_trait_items(def_id).encode(self).unwrap();
<[def::Export]>::encode(&[], self).unwrap();
self.end_tag();
tcx.trait_has_default_impl(def_id).encode(self).unwrap();
self.end_tag();
- encode_associated_type_names(self, &trait_def.associated_type_names);
self.encode_generics(&trait_def.generics, &trait_predicates);
self.encode_predicates(&tcx.lookup_super_predicates(def_id),
tag_item_super_predicates);
encode_deprecation(self, depr);
self.start_tag(tag_mod_children);
- let items = tcx.impl_or_trait_items(def_id);
- self.seq(&items[..], |_, id| id.def_id());
+ tcx.impl_or_trait_items(def_id).encode(self).unwrap();
<[def::Export]>::encode(&[], self).unwrap();
self.end_tag();
None
};
- let trait_item_def_id = trait_item_def_id.def_id();
self.record(trait_item_def_id,
EncodeContext::encode_info_for_impl_item,
(impl_id, trait_item_def_id, ast_item));
trait_items: &[hir::TraitItem]) {
// Now output the trait item info for each trait item.
let r = self.tcx.impl_or_trait_items(def_id);
- for (item_def_id, trait_item) in r.iter().zip(trait_items) {
- let item_def_id = item_def_id.def_id();
+ for (&item_def_id, trait_item) in r.iter().zip(trait_items) {
assert!(item_def_id.is_local());
self.record(item_def_id,
EncodeContext::encode_info_for_trait_item,
ecx.end_tag();
}
-fn encode_associated_type_names(ecx: &mut EncodeContext, names: &[Name]) {
- ecx.start_tag(tag_associated_type_names);
- names.encode(ecx).unwrap();
- ecx.end_tag();
-}
-
fn encode_crate_deps(ecx: &mut EncodeContext, cstore: &cstore::CStore) {
fn get_ordered_deps(cstore: &cstore::CStore)
-> Vec<(CrateNum, Rc<cstore::CrateMetadata>)> {
// info.
let trait_item_def_ids = self.session.cstore.impl_or_trait_items(def_id);
- for trait_item_def in &trait_item_def_ids {
+ for &trait_item_def in &trait_item_def_ids {
let trait_item_name =
- self.session.cstore.item_name(trait_item_def.def_id());
+ self.session.cstore.item_name(trait_item_def);
debug!("(building reduced graph for external crate) ... adding trait item \
'{}'",
let qualname = format!("{}::{}", qualname, name);
let def_id = self.tcx.map.local_def_id(id);
- let decl_id = self.tcx.trait_item_of_item(def_id).and_then(|new_id| {
- let new_def_id = new_id.def_id();
+ let decl_id = self.tcx.trait_item_of_item(def_id).and_then(|new_def_id| {
if new_def_id != def_id {
Some(new_def_id)
} else {
.map(|mr| mr.def_id())
}
ty::ImplContainer(def_id) => {
- let impl_items = self.tcx.impl_or_trait_items(def_id);
- Some(impl_items.iter()
- .find(|mr| {
- self.tcx.impl_or_trait_item(mr.def_id()).name() ==
- ti.name()
- })
- .unwrap()
- .def_id())
+ Some(*self.tcx.impl_or_trait_items(def_id).iter().find(|&&mr| {
+ self.tcx.impl_or_trait_item(mr).name() == ti.name()
+ }).unwrap())
}
}
} else {
.iter()
// Filter out non-method items.
- .filter_map(|item_def_id| {
- match *item_def_id {
- ty::MethodTraitItemId(def_id) => Some(def_id),
- _ => None,
+ .filter_map(|&item_def_id| {
+ match tcx.impl_or_trait_item(item_def_id) {
+ ty::MethodTraitItem(m) => Some(m),
+ _ => None
}
})
// Now produce pointers for each remaining method. If the
// method could never be called from this object, just supply
// null.
- .map(|trait_method_def_id| {
+ .map(|trait_method_type| {
debug!("get_vtable_methods: trait_method_def_id={:?}",
- trait_method_def_id);
+ trait_method_type.def_id);
- let trait_method_type = match tcx.impl_or_trait_item(trait_method_def_id) {
- ty::MethodTraitItem(m) => m,
- _ => bug!("should be a method, not other assoc item"),
- };
let name = trait_method_type.name;
// Some methods cannot be called on an object; skip those.
// the method may have some early-bound lifetimes, add
// regions for those
- let method_substs = Substs::for_item(tcx, trait_method_def_id,
+ let method_substs = Substs::for_item(tcx, trait_method_type.def_id,
|_, _| tcx.mk_region(ty::ReErased),
|_, _| tcx.types.err);
if let traits::VtableImpl(vtable_impl) = vtable {
let name = ccx.tcx().item_name(instance.def);
let ac = ccx.tcx().impl_or_trait_items(vtable_impl.impl_def_id)
- .iter().filter_map(|id| {
- match *id {
- ty::ConstTraitItemId(def_id) => {
- Some(ccx.tcx().impl_or_trait_item(def_id))
- }
+ .iter().filter_map(|&def_id| {
+ match ccx.tcx().impl_or_trait_item(def_id) {
+ ty::ConstTraitItem(ac) => Some(ac),
_ => None
}
- }).find(|ic| ic.name() == name);
+ }).find(|ic| ic.name == name);
if let Some(ac) = ac {
- instance = Instance::new(ac.def_id(), vtable_impl.substs);
+ instance = Instance::new(ac.def_id, vtable_impl.substs);
}
}
}
return tcx.types.err;
}
- let mut associated_types: FnvHashSet<(DefId, ast::Name)> =
- traits::supertraits(tcx, principal)
- .flat_map(|tr| {
- let trait_def = tcx.lookup_trait_def(tr.def_id());
- trait_def.associated_type_names
- .clone()
- .into_iter()
- .map(move |associated_type_name| (tr.def_id(), associated_type_name))
- })
- .collect();
+ let mut associated_types = FnvHashSet::default();
+ for tr in traits::supertraits(tcx, principal) {
+ if let Some(trait_id) = tcx.map.as_local_node_id(tr.def_id()) {
+ use collect::trait_associated_type_names;
+
+ associated_types.extend(trait_associated_type_names(tcx, trait_id)
+ .map(|name| (tr.def_id(), name)))
+ } else {
+ let trait_items = tcx.impl_or_trait_items(tr.def_id());
+ associated_types.extend(trait_items.iter().filter_map(|&def_id| {
+ match tcx.impl_or_trait_item(def_id) {
+ ty::TypeTraitItem(ref item) => Some(item.name),
+ _ => None
+ }
+ }).map(|name| (tr.def_id(), name)));
+ }
+ }
for projection_bound in &projection_bounds {
let pair = (projection_bound.0.projection_ty.trait_ref.def_id,
{
self.tcx.impl_or_trait_items(def_id)
.iter()
- .map(|&did| self.tcx.impl_or_trait_item(did.def_id()))
+ .map(|&did| self.tcx.impl_or_trait_item(did))
.find(|m| m.name() == item_name)
}
}
assoc_name: ast::Name)
-> bool
{
- let trait_def = self.tcx().lookup_trait_def(trait_def_id);
- trait_def.associated_type_names.contains(&assoc_name)
+ self.tcx().impl_or_trait_items(trait_def_id).iter().any(|&def_id| {
+ match self.tcx().impl_or_trait_item(def_id) {
+ ty::TypeTraitItem(ref item) => item.name == assoc_name,
+ _ => false
+ }
+ })
}
fn ty_infer(&self, _span: Span) -> Ty<'tcx> {
use rustc::ty::subst::Subst;
use rustc::ty::{self, TyCtxt, TypeFoldable};
use rustc::traits::{self, Reveal};
-use rustc::ty::{ImplOrTraitItemId, ConstTraitItemId};
-use rustc::ty::{MethodTraitItemId, TypeTraitItemId, ParameterEnvironment};
+use rustc::ty::{ParameterEnvironment};
use rustc::ty::{Ty, TyBool, TyChar, TyError};
use rustc::ty::{TyParam, TyRawPtr};
use rustc::ty::{TyRef, TyAdt, TyTrait, TyNever, TyTuple};
}
}
- tcx.impl_or_trait_item_ids.borrow_mut().insert(impl_did, Rc::new(impl_items));
+ tcx.impl_or_trait_item_def_ids.borrow_mut().insert(impl_did, Rc::new(impl_items));
}
fn add_inherent_impl(&self, base_def_id: DefId, impl_def_id: DefId) {
}
// Converts an implementation in the AST to a vector of items.
- fn create_impl_from_item(&self, item: &Item) -> Vec<ImplOrTraitItemId> {
+ fn create_impl_from_item(&self, item: &Item) -> Vec<DefId> {
match item.node {
ItemImpl(.., ref impl_items) => {
impl_items.iter().map(|impl_item| {
- let impl_def_id = self.crate_context.tcx.map.local_def_id(impl_item.id);
- match impl_item.node {
- hir::ImplItemKind::Const(..) => {
- ConstTraitItemId(impl_def_id)
- }
- hir::ImplItemKind::Method(..) => {
- MethodTraitItemId(impl_def_id)
- }
- hir::ImplItemKind::Type(_) => {
- TypeTraitItemId(impl_def_id)
- }
- }
+ self.crate_context.tcx.map.local_def_id(impl_item.id)
}).collect()
}
_ => {
tcx.populate_implementations_for_trait_if_necessary(drop_trait);
let drop_trait = tcx.lookup_trait_def(drop_trait);
- let impl_items = tcx.impl_or_trait_item_ids.borrow();
+ let impl_items = tcx.impl_or_trait_item_def_ids.borrow();
drop_trait.for_each_impl(tcx, |impl_did| {
let items = impl_items.get(&impl_did).unwrap();
let self_type = tcx.lookup_item_type(impl_did);
match self_type.ty.sty {
ty::TyAdt(type_def, _) => {
- type_def.set_destructor(method_def_id.def_id());
+ type_def.set_destructor(method_def_id);
}
_ => {
// Destructors only work on nominal types.
enum Namespace { Type, Value }
fn name_and_namespace<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
- item: &ty::ImplOrTraitItemId)
+ def_id: DefId)
-> (ast::Name, Namespace)
{
- let name = tcx.impl_or_trait_item(item.def_id()).name();
- (name, match *item {
- ty::TypeTraitItemId(..) => Namespace::Type,
- ty::ConstTraitItemId(..) => Namespace::Value,
- ty::MethodTraitItemId(..) => Namespace::Value,
+ let item = tcx.impl_or_trait_item(def_id);
+ (item.name(), match item {
+ ty::TypeTraitItem(..) => Namespace::Type,
+ ty::ConstTraitItem(..) => Namespace::Value,
+ ty::MethodTraitItem(..) => Namespace::Value,
})
}
- let impl_items = self.tcx.impl_or_trait_item_ids.borrow();
+ let impl_items = self.tcx.impl_or_trait_item_def_ids.borrow();
- for item1 in &impl_items[&impl1][..] {
+ for &item1 in &impl_items[&impl1][..] {
let (name, namespace) = name_and_namespace(self.tcx, item1);
- for item2 in &impl_items[&impl2][..] {
+ for &item2 in &impl_items[&impl2][..] {
if (name, namespace) == name_and_namespace(self.tcx, item2) {
let msg = format!("duplicate definitions with name `{}`", name);
- let node_id = self.tcx.map.as_local_node_id(item1.def_id()).unwrap();
+ let node_id = self.tcx.map.as_local_node_id(item1).unwrap();
self.tcx.sess.add_lint(lint::builtin::OVERLAPPING_INHERENT_IMPLS,
node_id,
- self.tcx.span_of_impl(item1.def_id()).unwrap(),
+ self.tcx.span_of_impl(item1).unwrap(),
msg);
}
}
-> bool
{
if let Some(trait_id) = self.tcx().map.as_local_node_id(trait_def_id) {
- trait_defines_associated_type_named(self.ccx, trait_id, assoc_name)
+ trait_associated_type_names(self.tcx(), trait_id)
+ .any(|name| name == assoc_name)
} else {
- let trait_def = self.tcx().lookup_trait_def(trait_def_id);
- trait_def.associated_type_names.contains(&assoc_name)
+ self.tcx().impl_or_trait_items(trait_def_id).iter().any(|&def_id| {
+ match self.tcx().impl_or_trait_item(def_id) {
+ ty::TypeTraitItem(ref item) => item.name == assoc_name,
+ _ => false
+ }
+ })
}
}
// Add an entry mapping
let trait_item_def_ids = Rc::new(trait_items.iter().map(|trait_item| {
- let def_id = ccx.tcx.map.local_def_id(trait_item.id);
- match trait_item.node {
- hir::ConstTraitItem(..) => ty::ConstTraitItemId(def_id),
- hir::MethodTraitItem(..) => ty::MethodTraitItemId(def_id),
- hir::TypeTraitItem(..) => ty::TypeTraitItemId(def_id)
- }
+ ccx.tcx.map.local_def_id(trait_item.id)
}).collect());
- tcx.impl_or_trait_item_ids.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
- trait_item_def_ids);
+ tcx.impl_or_trait_item_def_ids.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
+ trait_item_def_ids);
},
hir::ItemStruct(ref struct_def, _) |
hir::ItemUnion(ref struct_def, _) => {
return def.clone();
}
- let (unsafety, generics, items) = match it.node {
- hir::ItemTrait(unsafety, ref generics, _, ref items) => {
- (unsafety, generics, items)
+ let (unsafety, generics) = match it.node {
+ hir::ItemTrait(unsafety, ref generics, _, _) => {
+ (unsafety, generics)
}
_ => span_bug!(it.span, "trait_def_of_item invoked on non-trait"),
};
let ty_generics = generics_of_def_id(ccx, def_id);
let substs = mk_item_substs(&ccx.icx(generics), it.span, def_id);
- let associated_type_names: Vec<_> = items.iter().filter_map(|trait_item| {
- match trait_item.node {
- hir::TypeTraitItem(..) => Some(trait_item.name),
- _ => None,
- }
- }).collect();
-
let def_path_hash = tcx.def_path(def_id).deterministic_hash(tcx);
let trait_ref = ty::TraitRef::new(def_id, substs);
- let trait_def = ty::TraitDef::new(unsafety,
- paren_sugar,
- ty_generics,
- trait_ref,
- associated_type_names,
+ let trait_def = ty::TraitDef::new(unsafety, paren_sugar, ty_generics, trait_ref,
def_path_hash);
tcx.intern_trait_def(trait_def)
}
-fn trait_defines_associated_type_named(ccx: &CrateCtxt,
- trait_node_id: ast::NodeId,
- assoc_name: ast::Name)
- -> bool
+pub fn trait_associated_type_names<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
+ trait_node_id: ast::NodeId)
+ -> impl Iterator<Item=ast::Name> + 'a
{
- let item = match ccx.tcx.map.get(trait_node_id) {
+ let item = match tcx.map.get(trait_node_id) {
hir_map::NodeItem(item) => item,
_ => bug!("trait_node_id {} is not an item", trait_node_id)
};
_ => bug!("trait_node_id {} is not a trait", trait_node_id)
};
- trait_items.iter().any(|trait_item| {
+ trait_items.iter().filter_map(|trait_item| {
match trait_item.node {
- hir::TypeTraitItem(..) => trait_item.name == assoc_name,
- _ => false,
+ hir::TypeTraitItem(..) => Some(trait_item.name),
+ _ => None,
}
})
}
#![feature(box_patterns)]
#![feature(box_syntax)]
+#![feature(conservative_impl_trait)]
#![feature(dotdot_in_tuple_patterns)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
let predicates = tcx.lookup_predicates(did);
let trait_items = tcx.sess.cstore.impl_or_trait_items(did)
.iter()
- .filter_map(|did| {
- let did = did.def_id();
- let impl_item = tcx.impl_or_trait_item(did);
- match impl_item {
+ .filter_map(|&did| {
+ match tcx.impl_or_trait_item(did) {
ty::ConstTraitItem(ref assoc_const) => {
let did = assoc_const.def_id;
let type_scheme = tcx.lookup_item_type(did);