rustc: unify and simplify managing associated items.

This commit is contained in:
Eduard Burtescu 2016-11-10 02:06:34 +02:00
parent da2ce22768
commit de0ffadb67
45 changed files with 1035 additions and 1687 deletions

View file

@ -32,7 +32,7 @@ use rustc::hir::def::Def;
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc::hir::map::{Node, NodeItem};
use rustc::session::Session;
use rustc::ty::{self, TyCtxt, ImplOrTraitItem, ImplOrTraitItemContainer};
use rustc::ty::{self, TyCtxt, AssociatedItemContainer};
use std::collections::HashSet;
use std::collections::hash_map::DefaultHasher;
@ -402,19 +402,19 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
// with the right name.
if !self.span.filter_generated(Some(method_data.span), span) {
let container =
self.tcx.impl_or_trait_item(self.tcx.map.local_def_id(id)).container();
self.tcx.associated_item(self.tcx.map.local_def_id(id)).container;
let mut trait_id;
let mut decl_id = None;
match container {
ImplOrTraitItemContainer::ImplContainer(id) => {
AssociatedItemContainer::ImplContainer(id) => {
trait_id = self.tcx.trait_id_of_impl(id);
match trait_id {
Some(id) => {
for item in &**self.tcx.trait_items(id) {
if let &ImplOrTraitItem::MethodTraitItem(ref m) = item {
if m.name == name {
decl_id = Some(m.def_id);
for item in self.tcx.associated_items(id) {
if item.kind == ty::AssociatedKind::Method {
if item.name == name {
decl_id = Some(item.def_id);
break;
}
}
@ -429,7 +429,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
}
}
}
ImplOrTraitItemContainer::TraitContainer(id) => {
AssociatedItemContainer::TraitContainer(id) => {
trait_id = Some(id);
}
}
@ -916,11 +916,9 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
// Modules or types in the path prefix.
match self.tcx.expect_def(id) {
Def::Method(did) => {
let ti = self.tcx.impl_or_trait_item(did);
if let ty::MethodTraitItem(m) = ti {
if m.explicit_self == ty::ExplicitSelfCategory::Static {
self.write_sub_path_trait_truncated(path);
}
let ti = self.tcx.associated_item(did);
if ti.kind == ty::AssociatedKind::Method && ti.method_has_self_argument {
self.write_sub_path_trait_truncated(path);
}
}
Def::Fn(..) |

View file

@ -313,7 +313,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
name: ast::Name, span: Span) -> Option<FunctionData> {
// The qualname for a method is the trait name or name of the struct in an impl in
// which the method is declared in, followed by the method's name.
let (qualname, parent_scope, vis, docs) =
let (qualname, parent_scope, decl_id, vis, docs) =
match self.tcx.impl_of_method(self.tcx.map.local_def_id(id)) {
Some(impl_id) => match self.tcx.map.get_if_local(impl_id) {
Some(NodeItem(item)) => {
@ -323,12 +323,19 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
result.push_str(&rustc::hir::print::ty_to_string(&ty));
let trait_id = self.tcx.trait_id_of_impl(impl_id);
let mut decl_id = None;
if let Some(def_id) = trait_id {
result.push_str(" as ");
result.push_str(&self.tcx.item_path_str(def_id));
self.tcx.associated_items(def_id)
.find(|item| item.name == name)
.map(|item| decl_id = Some(item.def_id));
}
result.push_str(">");
(result, trait_id, From::from(&item.vis), docs_for_attrs(&item.attrs))
(result, trait_id, decl_id,
From::from(&item.vis),
docs_for_attrs(&item.attrs))
}
_ => {
span_bug!(span,
@ -351,7 +358,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
match self.tcx.map.get_if_local(def_id) {
Some(NodeItem(item)) => {
(format!("::{}", self.tcx.item_path_str(def_id)),
Some(def_id),
Some(def_id), None,
From::from(&item.vis),
docs_for_attrs(&item.attrs))
}
@ -373,15 +380,6 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
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_def_id| {
if new_def_id != def_id {
Some(new_def_id)
} else {
None
}
});
let sub_span = self.span_utils.sub_span_after_keyword(span, keywords::Fn);
filter!(self.span_utils, sub_span, span, None);
Some(FunctionData {
@ -473,7 +471,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
ast::ExprKind::MethodCall(..) => {
let method_call = ty::MethodCall::expr(expr.id);
let method_id = self.tcx.tables().method_map[&method_call].def_id;
let (def_id, decl_id) = match self.tcx.impl_or_trait_item(method_id).container() {
let (def_id, decl_id) = match self.tcx.associated_item(method_id).container {
ty::ImplContainer(_) => (Some(method_id), None),
ty::TraitContainer(_) => (None, Some(method_id)),
};
@ -535,21 +533,10 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
let sub_span = self.span_utils.sub_span_for_meth_name(path.span);
filter!(self.span_utils, sub_span, path.span, None);
let def_id = if decl_id.is_local() {
let ti = self.tcx.impl_or_trait_item(decl_id);
match ti.container() {
ty::TraitContainer(def_id) => {
self.tcx
.trait_items(def_id)
.iter()
.find(|mr| mr.name() == ti.name() && self.trait_method_has_body(mr))
.map(|mr| mr.def_id())
}
ty::ImplContainer(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())
}
}
let ti = self.tcx.associated_item(decl_id);
self.tcx.associated_items(ti.container.id())
.find(|item| item.name == ti.name && item.has_value)
.map(|item| item.def_id)
} else {
None
};
@ -582,20 +569,6 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
}
}
fn trait_method_has_body(&self, mr: &ty::ImplOrTraitItem) -> bool {
let def_id = mr.def_id();
if let Some(node_id) = self.tcx.map.as_local_node_id(def_id) {
let trait_item = self.tcx.map.expect_trait_item(node_id);
if let hir::TraitItem_::MethodTraitItem(_, Some(_)) = trait_item.node {
true
} else {
false
}
} else {
false
}
}
pub fn get_field_ref_data(&self,
field_ref: &ast::Field,
variant: ty::VariantDef,