include a Name and Span for each item in the HIR of the impl
This commit is contained in:
parent
26d1500e13
commit
629f5ffb23
@ -205,6 +205,9 @@ pub trait Visitor<'v> : Sized {
|
||||
fn visit_impl_item(&mut self, ii: &'v ImplItem) {
|
||||
walk_impl_item(self, ii)
|
||||
}
|
||||
fn visit_impl_item_ref(&mut self, ii: &'v ImplItemRef) {
|
||||
walk_impl_item_ref(self, ii)
|
||||
}
|
||||
fn visit_trait_ref(&mut self, t: &'v TraitRef) {
|
||||
walk_trait_ref(self, t)
|
||||
}
|
||||
@ -399,13 +402,13 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
|
||||
visitor.visit_id(item.id);
|
||||
visitor.visit_trait_ref(trait_ref)
|
||||
}
|
||||
ItemImpl(.., ref type_parameters, ref opt_trait_reference, ref typ, ref impl_item_ids) => {
|
||||
ItemImpl(.., ref type_parameters, ref opt_trait_reference, ref typ, ref impl_item_refs) => {
|
||||
visitor.visit_id(item.id);
|
||||
visitor.visit_generics(type_parameters);
|
||||
walk_list!(visitor, visit_trait_ref, opt_trait_reference);
|
||||
visitor.visit_ty(typ);
|
||||
for &impl_item_id in impl_item_ids {
|
||||
visitor.visit_nested_impl_item(impl_item_id);
|
||||
for impl_item_ref in impl_item_refs {
|
||||
visitor.visit_impl_item_ref(impl_item_ref);
|
||||
}
|
||||
}
|
||||
ItemStruct(ref struct_definition, ref generics) |
|
||||
@ -763,6 +766,12 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, impl_item_ref: &'v ImplItemRef) {
|
||||
visitor.visit_nested_impl_item(impl_item_ref.id);
|
||||
visitor.visit_name(impl_item_ref.span, impl_item_ref.name);
|
||||
}
|
||||
|
||||
|
||||
pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V, struct_definition: &'v VariantData) {
|
||||
visitor.visit_id(struct_definition.id());
|
||||
walk_list!(visitor, visit_struct_field, struct_definition.fields());
|
||||
|
@ -116,7 +116,7 @@ impl<'a> LoweringContext<'a> {
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, item: &ImplItem) {
|
||||
let id = self.lctx.lower_impl_item_id(item);
|
||||
let id = self.lctx.lower_impl_item_ref(item).id;
|
||||
self.impl_items.insert(id, self.lctx.lower_impl_item(item));
|
||||
visit::walk_impl_item(self, item);
|
||||
}
|
||||
@ -641,7 +641,7 @@ impl<'a> LoweringContext<'a> {
|
||||
}
|
||||
ItemKind::Impl(unsafety, polarity, ref generics, ref ifce, ref ty, ref impl_items) => {
|
||||
let new_impl_items = impl_items.iter()
|
||||
.map(|item| self.lower_impl_item_id(item))
|
||||
.map(|item| self.lower_impl_item_ref(item))
|
||||
.collect();
|
||||
let ifce = ifce.as_ref().map(|trait_ref| self.lower_trait_ref(trait_ref));
|
||||
hir::ItemImpl(self.lower_unsafety(unsafety),
|
||||
@ -717,8 +717,24 @@ impl<'a> LoweringContext<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
fn lower_impl_item_id(&mut self, i: &ImplItem) -> hir::ImplItemId {
|
||||
hir::ImplItemId { id: i.id }
|
||||
fn lower_impl_item_ref(&mut self, i: &ImplItem) -> hir::ImplItemRef {
|
||||
hir::ImplItemRef {
|
||||
id: hir::ImplItemId { node_id: i.id },
|
||||
name: i.ident.name,
|
||||
span: i.span,
|
||||
vis: self.lower_visibility(&i.vis),
|
||||
defaultness: self.lower_defaultness(i.defaultness),
|
||||
kind: match i.node {
|
||||
ImplItemKind::Const(..) => hir::AssociatedItemKind::Const,
|
||||
ImplItemKind::Type(..) => hir::AssociatedItemKind::Type,
|
||||
ImplItemKind::Method(ref sig, _) => hir::AssociatedItemKind::Method {
|
||||
has_self: sig.decl.get_self().is_some(),
|
||||
},
|
||||
ImplItemKind::Macro(..) => unimplemented!(),
|
||||
},
|
||||
// since `default impl` is not yet implemented, this is always true in impls
|
||||
has_value: true,
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_mod(&mut self, m: &Mod) -> hir::Mod {
|
||||
|
@ -93,7 +93,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
|
||||
/// deep walking so that we walk nested items in the context of
|
||||
/// their outer items.
|
||||
|
||||
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'v>> {
|
||||
fn nested_visit_map(&mut self) -> Option<&map::Map<'ast>> {
|
||||
panic!("visit_nested_xxx must be manually implemented in this visitor")
|
||||
}
|
||||
|
||||
|
@ -384,7 +384,7 @@ impl<'ast> Map<'ast> {
|
||||
}
|
||||
|
||||
pub fn impl_item(&self, id: ImplItemId) -> &'ast ImplItem {
|
||||
self.read(id.id);
|
||||
self.read(id.node_id);
|
||||
|
||||
// NB: intentionally bypass `self.forest.krate()` so that we
|
||||
// do not trigger a read of the whole krate here
|
||||
|
@ -1057,7 +1057,7 @@ pub enum TraitItem_ {
|
||||
// so it can fetched later.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub struct ImplItemId {
|
||||
pub id: NodeId,
|
||||
pub node_id: NodeId,
|
||||
}
|
||||
|
||||
/// Represents anything within an `impl` block
|
||||
@ -1546,7 +1546,7 @@ pub enum Item_ {
|
||||
Generics,
|
||||
Option<TraitRef>, // (optional) trait this impl implements
|
||||
P<Ty>, // self
|
||||
HirVec<ImplItemId>),
|
||||
HirVec<ImplItemRef>),
|
||||
}
|
||||
|
||||
impl Item_ {
|
||||
@ -1570,6 +1570,30 @@ impl Item_ {
|
||||
}
|
||||
}
|
||||
|
||||
/// A reference from an impl to one of its associated items. This
|
||||
/// contains the item's id, naturally, but also the item's name and
|
||||
/// some other high-level details (like whether it is an associated
|
||||
/// type or method, and whether it is public). This allows other
|
||||
/// passes to find the impl they want without loading the id (which
|
||||
/// means fewer edges in the incremental compilation graph).
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub struct ImplItemRef {
|
||||
pub id: ImplItemId,
|
||||
pub name: Name,
|
||||
pub kind: AssociatedItemKind,
|
||||
pub span: Span,
|
||||
pub vis: Visibility,
|
||||
pub defaultness: Defaultness,
|
||||
pub has_value: bool,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub enum AssociatedItemKind {
|
||||
Const,
|
||||
Method { has_self: bool },
|
||||
Type,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub struct ForeignItem {
|
||||
pub name: Name,
|
||||
|
@ -808,8 +808,8 @@ impl<'a> State<'a> {
|
||||
space(&mut self.s)?;
|
||||
self.bopen()?;
|
||||
self.print_inner_attributes(&item.attrs)?;
|
||||
for &impl_item in impl_items {
|
||||
self.print_impl_item_id(impl_item)?;
|
||||
for impl_item in impl_items {
|
||||
self.print_impl_item_ref(impl_item)?;
|
||||
}
|
||||
self.bclose(item.span)?;
|
||||
}
|
||||
@ -1020,10 +1020,10 @@ impl<'a> State<'a> {
|
||||
self.ann.post(self, NodeSubItem(ti.id))
|
||||
}
|
||||
|
||||
pub fn print_impl_item_id(&mut self, item_id: hir::ImplItemId) -> io::Result<()> {
|
||||
pub fn print_impl_item_ref(&mut self, item_ref: &hir::ImplItemRef) -> io::Result<()> {
|
||||
if let Some(krate) = self.krate {
|
||||
// skip nested items if krate context was not provided
|
||||
let item = &krate.impl_item(item_id);
|
||||
let item = &krate.impl_item(item_ref.id);
|
||||
self.print_impl_item(item)
|
||||
} else {
|
||||
Ok(())
|
||||
|
@ -359,12 +359,12 @@ impl<'v, 'k> ItemLikeVisitor<'v> for LifeSeeder<'k> {
|
||||
}
|
||||
}
|
||||
}
|
||||
hir::ItemImpl(.., ref opt_trait, _, ref impl_item_ids) => {
|
||||
for &impl_item_id in impl_item_ids {
|
||||
let impl_item = self.krate.impl_item(impl_item_id);
|
||||
hir::ItemImpl(.., ref opt_trait, _, ref impl_item_refs) => {
|
||||
for impl_item_ref in impl_item_refs {
|
||||
let impl_item = self.krate.impl_item(impl_item_ref.id);
|
||||
if opt_trait.is_some() ||
|
||||
has_allow_dead_code_or_lang_attr(&impl_item.attrs) {
|
||||
self.worklist.push(impl_item_id.id);
|
||||
self.worklist.push(impl_item_ref.id.node_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -328,10 +328,10 @@ struct CollectPrivateImplItemsVisitor<'a> {
|
||||
impl<'a, 'v> ItemLikeVisitor<'v> for CollectPrivateImplItemsVisitor<'a> {
|
||||
fn visit_item(&mut self, item: &hir::Item) {
|
||||
// We need only trait impls here, not inherent impls, and only non-exported ones
|
||||
if let hir::ItemImpl(.., Some(_), _, ref impl_items) = item.node {
|
||||
if let hir::ItemImpl(.., Some(_), _, ref impl_item_refs) = item.node {
|
||||
if !self.access_levels.is_reachable(item.id) {
|
||||
for impl_item in impl_items {
|
||||
self.worklist.push(impl_item.id);
|
||||
for impl_item_ref in impl_item_refs {
|
||||
self.worklist.push(impl_item_ref.id.node_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -525,10 +525,10 @@ pub fn check_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
// For implementations of traits, check the stability of each item
|
||||
// individually as it's possible to have a stable trait with unstable
|
||||
// items.
|
||||
hir::ItemImpl(.., Some(ref t), _, ref impl_item_ids) => {
|
||||
hir::ItemImpl(.., Some(ref t), _, ref impl_item_refs) => {
|
||||
let trait_did = tcx.expect_def(t.ref_id).def_id();
|
||||
for &impl_item_id in impl_item_ids {
|
||||
let impl_item = tcx.map.impl_item(impl_item_id);
|
||||
for impl_item_ref in impl_item_refs {
|
||||
let impl_item = tcx.map.impl_item(impl_item_ref.id);
|
||||
let item = tcx.associated_items(trait_did)
|
||||
.find(|item| item.name == impl_item.name).unwrap();
|
||||
if warn_about_defns {
|
||||
|
@ -2190,9 +2190,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
self.map.local_def_id(trait_item.id)
|
||||
}).collect())
|
||||
}
|
||||
hir::ItemImpl(.., ref impl_items) => {
|
||||
Rc::new(impl_items.iter().map(|impl_item| {
|
||||
self.map.local_def_id(impl_item.id)
|
||||
hir::ItemImpl(.., ref impl_item_refs) => {
|
||||
Rc::new(impl_item_refs.iter().map(|impl_item_ref| {
|
||||
self.map.local_def_id(impl_item_ref.id.node_id)
|
||||
}).collect())
|
||||
}
|
||||
_ => span_bug!(item.span, "associated_item_def_ids: not impl or trait")
|
||||
|
@ -387,7 +387,7 @@ impl LateLintPass for MissingDoc {
|
||||
"a trait"
|
||||
}
|
||||
hir::ItemTy(..) => "a type alias",
|
||||
hir::ItemImpl(.., Some(ref trait_ref), _, ref impl_items) => {
|
||||
hir::ItemImpl(.., Some(ref trait_ref), _, ref impl_item_refs) => {
|
||||
// If the trait is private, add the impl items to private_traits so they don't get
|
||||
// reported for missing docs.
|
||||
let real_trait = cx.tcx.expect_def(trait_ref.ref_id).def_id();
|
||||
@ -395,8 +395,8 @@ impl LateLintPass for MissingDoc {
|
||||
match cx.tcx.map.find(node_id) {
|
||||
Some(hir_map::NodeItem(item)) => {
|
||||
if item.vis == hir::Visibility::Inherited {
|
||||
for itm in impl_items {
|
||||
self.private_traits.insert(itm.id);
|
||||
for impl_item_ref in impl_item_refs {
|
||||
self.private_traits.insert(impl_item_ref.id.node_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -277,12 +277,12 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
|
||||
.and_then(|impl_node_id| self.tcx.map.find(impl_node_id))
|
||||
.map(|node| {
|
||||
if let hir_map::NodeItem(item) = node {
|
||||
if let hir::ItemImpl(_, _, _, _, _, ref impl_item_ids) = item.node {
|
||||
span = impl_item_ids.first()
|
||||
.map(|&impl_item_id| {
|
||||
self.tcx.map.impl_item(impl_item_id)
|
||||
.span
|
||||
});
|
||||
if let hir::ItemImpl(.., ref impl_item_refs) = item.node {
|
||||
span = impl_item_refs.first()
|
||||
.map(|iiref| {
|
||||
self.tcx.map.impl_item(iiref.id)
|
||||
.span
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -158,17 +158,17 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
hir::ItemImpl(.., None, _, ref impl_item_ids) => {
|
||||
for &impl_item_id in impl_item_ids {
|
||||
let impl_item = self.tcx.map.impl_item(impl_item_id);
|
||||
hir::ItemImpl(.., None, _, ref impl_item_refs) => {
|
||||
for impl_item_ref in impl_item_refs {
|
||||
let impl_item = self.tcx.map.impl_item(impl_item_ref.id);
|
||||
if impl_item.vis == hir::Public {
|
||||
self.update(impl_item.id, item_level);
|
||||
}
|
||||
}
|
||||
}
|
||||
hir::ItemImpl(.., Some(_), _, ref impl_item_ids) => {
|
||||
for &impl_item_id in impl_item_ids {
|
||||
let impl_item = self.tcx.map.impl_item(impl_item_id);
|
||||
hir::ItemImpl(.., Some(_), _, ref impl_item_refs) => {
|
||||
for impl_item_ref in impl_item_refs {
|
||||
let impl_item = self.tcx.map.impl_item(impl_item_ref.id);
|
||||
self.update(impl_item.id, item_level);
|
||||
}
|
||||
}
|
||||
@ -251,12 +251,12 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
|
||||
// The interface is empty
|
||||
hir::ItemDefaultImpl(..) => {}
|
||||
// Visit everything except for private impl items
|
||||
hir::ItemImpl(.., ref generics, None, _, ref impl_item_ids) => {
|
||||
hir::ItemImpl(.., ref generics, None, _, ref impl_item_refs) => {
|
||||
if item_level.is_some() {
|
||||
self.reach().visit_generics(generics);
|
||||
for &impl_item_id in impl_item_ids {
|
||||
if self.get(impl_item_id.id).is_some() {
|
||||
let impl_item = self.tcx.map.impl_item(impl_item_id);
|
||||
for impl_item_ref in impl_item_refs {
|
||||
if self.get(impl_item_ref.id.node_id).is_some() {
|
||||
let impl_item = self.tcx.map.impl_item(impl_item_ref.id);
|
||||
self.reach().visit_impl_item(impl_item);
|
||||
}
|
||||
}
|
||||
@ -656,7 +656,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
|
||||
// (i.e. we could just return here to not check them at
|
||||
// all, or some worse estimation of whether an impl is
|
||||
// publicly visible).
|
||||
hir::ItemImpl(.., ref g, ref trait_ref, ref self_, ref impl_item_ids) => {
|
||||
hir::ItemImpl(.., ref g, ref trait_ref, ref self_, ref impl_item_refs) => {
|
||||
// `impl [... for] Private` is never visible.
|
||||
let self_contains_private;
|
||||
// impl [... for] Public<...>, but not `impl [... for]
|
||||
@ -701,9 +701,9 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
|
||||
// are private (because `T` won't be visible externally).
|
||||
let trait_or_some_public_method =
|
||||
trait_ref.is_some() ||
|
||||
impl_item_ids.iter()
|
||||
.any(|&impl_item_id| {
|
||||
let impl_item = self.tcx.map.impl_item(impl_item_id);
|
||||
impl_item_refs.iter()
|
||||
.any(|impl_item_ref| {
|
||||
let impl_item = self.tcx.map.impl_item(impl_item_ref.id);
|
||||
match impl_item.node {
|
||||
hir::ImplItemKind::Const(..) |
|
||||
hir::ImplItemKind::Method(..) => {
|
||||
@ -721,13 +721,13 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
|
||||
|
||||
match *trait_ref {
|
||||
None => {
|
||||
for &impl_item_id in impl_item_ids {
|
||||
for impl_item_ref in impl_item_refs {
|
||||
// This is where we choose whether to walk down
|
||||
// further into the impl to check its items. We
|
||||
// should only walk into public items so that we
|
||||
// don't erroneously report errors for private
|
||||
// types in private items.
|
||||
let impl_item = self.tcx.map.impl_item(impl_item_id);
|
||||
let impl_item = self.tcx.map.impl_item(impl_item_ref.id);
|
||||
match impl_item.node {
|
||||
hir::ImplItemKind::Const(..) |
|
||||
hir::ImplItemKind::Method(..)
|
||||
@ -759,8 +759,8 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
|
||||
intravisit::walk_path(self, &tr.path);
|
||||
|
||||
// Those in 3. are warned with this call.
|
||||
for &impl_item_id in impl_item_ids {
|
||||
let impl_item = self.tcx.map.impl_item(impl_item_id);
|
||||
for impl_item_ref in impl_item_refs {
|
||||
let impl_item = self.tcx.map.impl_item(impl_item_ref.id);
|
||||
if let hir::ImplItemKind::Type(ref ty) = impl_item.node {
|
||||
self.visit_ty(ty);
|
||||
}
|
||||
@ -771,8 +771,8 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
|
||||
// impl Public<Private> { ... }. Any public static
|
||||
// methods will be visible as `Public::foo`.
|
||||
let mut found_pub_static = false;
|
||||
for &impl_item_id in impl_item_ids {
|
||||
let impl_item = self.tcx.map.impl_item(impl_item_id);
|
||||
for impl_item_ref in impl_item_refs {
|
||||
let impl_item = self.tcx.map.impl_item(impl_item_ref.id);
|
||||
match impl_item.node {
|
||||
hir::ImplItemKind::Const(..) => {
|
||||
if self.item_is_public(&impl_item.id, &impl_item.vis) {
|
||||
@ -1099,13 +1099,13 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for PrivateItemsInPublicInterfacesVisitor
|
||||
hir::ItemDefaultImpl(..) => {}
|
||||
// An inherent impl is public when its type is public
|
||||
// Subitems of inherent impls have their own publicity
|
||||
hir::ItemImpl(.., ref generics, None, ref ty, ref impl_item_ids) => {
|
||||
hir::ItemImpl(.., ref generics, None, ref ty, ref impl_item_refs) => {
|
||||
let ty_vis = self.ty_visibility(ty);
|
||||
check.required_visibility = ty_vis;
|
||||
check.visit_generics(generics);
|
||||
|
||||
for &impl_item_id in impl_item_ids {
|
||||
let impl_item = self.tcx.map.impl_item(impl_item_id);
|
||||
for impl_item_ref in impl_item_refs {
|
||||
let impl_item = self.tcx.map.impl_item(impl_item_ref.id);
|
||||
let impl_item_vis =
|
||||
ty::Visibility::from_hir(&impl_item.vis, item.id, self.tcx);
|
||||
check.required_visibility = min(impl_item_vis, ty_vis);
|
||||
@ -1114,12 +1114,12 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for PrivateItemsInPublicInterfacesVisitor
|
||||
}
|
||||
// A trait impl is public when both its type and its trait are public
|
||||
// Subitems of trait impls have inherited publicity
|
||||
hir::ItemImpl(.., ref generics, Some(ref trait_ref), ref ty, ref impl_item_ids) => {
|
||||
hir::ItemImpl(.., ref generics, Some(ref trait_ref), ref ty, ref impl_item_refs) => {
|
||||
let vis = min(self.ty_visibility(ty), self.trait_ref_visibility(trait_ref));
|
||||
check.required_visibility = vis;
|
||||
check.visit_generics(generics);
|
||||
for &impl_item_id in impl_item_ids {
|
||||
let impl_item = self.tcx.map.impl_item(impl_item_id);
|
||||
for impl_item_ref in impl_item_refs {
|
||||
let impl_item = self.tcx.map.impl_item(impl_item_ref.id);
|
||||
check.visit_impl_item(impl_item);
|
||||
}
|
||||
}
|
||||
|
@ -1135,7 +1135,7 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(scx: &SharedCrateContext<'a, '
|
||||
_,
|
||||
ref generics,
|
||||
..,
|
||||
ref items) => {
|
||||
ref impl_item_refs) => {
|
||||
if generics.is_type_parameterized() {
|
||||
return
|
||||
}
|
||||
@ -1148,10 +1148,9 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(scx: &SharedCrateContext<'a, '
|
||||
if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) {
|
||||
let callee_substs = tcx.erase_regions(&trait_ref.substs);
|
||||
let overridden_methods: FxHashSet<_> =
|
||||
items.iter()
|
||||
.map(|&id| tcx.map.impl_item(id))
|
||||
.map(|item| item.name)
|
||||
.collect();
|
||||
impl_item_refs.iter()
|
||||
.map(|iiref| iiref.name)
|
||||
.collect();
|
||||
for method in tcx.provided_trait_methods(trait_ref.def_id) {
|
||||
if overridden_methods.contains(&method.name) {
|
||||
continue;
|
||||
|
@ -16,13 +16,13 @@ use CrateCtxt;
|
||||
|
||||
/// Enforce that we do not have two items in an impl with the same name.
|
||||
pub fn enforce_impl_items_are_distinct<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
impl_item_ids: &[hir::ImplItemId])
|
||||
impl_item_refs: &[hir::ImplItemRef])
|
||||
{
|
||||
let tcx = ccx.tcx;
|
||||
let mut seen_type_items = FxHashMap();
|
||||
let mut seen_value_items = FxHashMap();
|
||||
for &impl_item_id in impl_item_ids {
|
||||
let impl_item = tcx.map.impl_item(impl_item_id);
|
||||
for &impl_item_ref in impl_item_refs {
|
||||
let impl_item = tcx.map.impl_item(impl_item_ref.id);
|
||||
let seen_items = match impl_item.node {
|
||||
hir::ImplItemKind::Type(_) => &mut seen_type_items,
|
||||
_ => &mut seen_value_items,
|
||||
|
@ -51,7 +51,7 @@ use CrateCtxt;
|
||||
pub fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
impl_hir_generics: &hir::Generics,
|
||||
impl_def_id: DefId,
|
||||
impl_item_ids: &[hir::ImplItemId])
|
||||
impl_item_refs: &[hir::ImplItemRef])
|
||||
{
|
||||
// Every lifetime used in an associated type must be constrained.
|
||||
let impl_scheme = ccx.tcx.lookup_item_type(impl_def_id);
|
||||
@ -71,8 +71,8 @@ pub fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
}
|
||||
|
||||
// Disallow unconstrained lifetimes, but only if they appear in assoc types.
|
||||
let lifetimes_in_associated_types: FxHashSet<_> = impl_item_ids.iter()
|
||||
.map(|item_id| ccx.tcx.map.local_def_id(item_id.id))
|
||||
let lifetimes_in_associated_types: FxHashSet<_> = impl_item_refs.iter()
|
||||
.map(|item_ref| ccx.tcx.map.local_def_id(item_ref.id.node_id))
|
||||
.filter(|&def_id| {
|
||||
let item = ccx.tcx.associated_item(def_id);
|
||||
item.kind == ty::AssociatedKind::Type && item.has_value
|
||||
|
@ -817,7 +817,7 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
|
||||
it.id);
|
||||
}
|
||||
hir::ItemFn(..) => {} // entirely within check_item_body
|
||||
hir::ItemImpl(_, _, ref hir_generics, _, _, ref impl_item_ids) => {
|
||||
hir::ItemImpl(_, _, ref hir_generics, _, _, ref impl_item_refs) => {
|
||||
debug!("ItemImpl {} with id {}", it.name, it.id);
|
||||
let impl_def_id = ccx.tcx.map.local_def_id(it.id);
|
||||
if let Some(impl_trait_ref) = ccx.tcx.impl_trait_ref(impl_def_id) {
|
||||
@ -825,7 +825,7 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
|
||||
it.span,
|
||||
impl_def_id,
|
||||
impl_trait_ref,
|
||||
impl_item_ids);
|
||||
impl_item_refs);
|
||||
let trait_def_id = impl_trait_ref.def_id;
|
||||
check_on_unimplemented(ccx, trait_def_id, it);
|
||||
}
|
||||
@ -833,10 +833,10 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
|
||||
impl_parameters_used::enforce_impl_params_are_constrained(ccx,
|
||||
hir_generics,
|
||||
impl_def_id,
|
||||
impl_item_ids);
|
||||
impl_item_refs);
|
||||
|
||||
impl_item_duplicate::enforce_impl_items_are_distinct(ccx,
|
||||
impl_item_ids);
|
||||
impl_item_refs);
|
||||
}
|
||||
hir::ItemTrait(..) => {
|
||||
let def_id = ccx.tcx.map.local_def_id(it.id);
|
||||
@ -895,11 +895,11 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
|
||||
hir::ItemFn(ref decl, .., ref body) => {
|
||||
check_bare_fn(ccx, &decl, &body, it.id, it.span);
|
||||
}
|
||||
hir::ItemImpl(.., ref impl_item_ids) => {
|
||||
hir::ItemImpl(.., ref impl_item_refs) => {
|
||||
debug!("ItemImpl {} with id {}", it.name, it.id);
|
||||
|
||||
for &impl_item_id in impl_item_ids {
|
||||
let impl_item = ccx.tcx.map.impl_item(impl_item_id);
|
||||
for impl_item_ref in impl_item_refs {
|
||||
let impl_item = ccx.tcx.map.impl_item(impl_item_ref.id);
|
||||
match impl_item.node {
|
||||
hir::ImplItemKind::Const(_, ref expr) => {
|
||||
check_const(ccx, &expr, impl_item.id)
|
||||
@ -1036,7 +1036,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
impl_span: Span,
|
||||
impl_id: DefId,
|
||||
impl_trait_ref: ty::TraitRef<'tcx>,
|
||||
impl_item_ids: &[hir::ImplItemId]) {
|
||||
impl_item_refs: &[hir::ImplItemRef]) {
|
||||
// If the trait reference itself is erroneous (so the compilation is going
|
||||
// to fail), skip checking the items here -- the `impl_item` table in `tcx`
|
||||
// isn't populated for such impls.
|
||||
@ -1047,7 +1047,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
let trait_def = tcx.lookup_trait_def(impl_trait_ref.def_id);
|
||||
let mut overridden_associated_type = None;
|
||||
|
||||
let impl_items = || impl_item_ids.iter().map(|&id| ccx.tcx.map.impl_item(id));
|
||||
let impl_items = || impl_item_refs.iter().map(|iiref| ccx.tcx.map.impl_item(iiref.id));
|
||||
|
||||
// Check existing impl methods to see if they are both present in trait
|
||||
// and compatible with trait signature
|
||||
|
Loading…
Reference in New Issue
Block a user