Skip to content

Commit 8649282

Browse files
committed
rustc: separate TraitItem from their parent Item, just like ImplItem.
1 parent 6ebb6fd commit 8649282

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+601
-298
lines changed

src/librustc/dep_graph/visit.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,17 @@ pub fn visit_all_item_likes_in_krate<'a, 'tcx, V, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>
4545
debug!("Ended task {:?}", task_id);
4646
}
4747

48+
fn visit_trait_item(&mut self, i: &'tcx hir::TraitItem) {
49+
let trait_item_def_id = self.tcx.map.local_def_id(i.id);
50+
let task_id = (self.dep_node_fn)(trait_item_def_id);
51+
let _task = self.tcx.dep_graph.in_task(task_id.clone());
52+
debug!("Started task {:?}", task_id);
53+
assert!(!self.tcx.map.is_inlined_def_id(trait_item_def_id));
54+
self.tcx.dep_graph.read(DepNode::Hir(trait_item_def_id));
55+
self.visitor.visit_trait_item(i);
56+
debug!("Ended task {:?}", task_id);
57+
}
58+
4859
fn visit_impl_item(&mut self, i: &'tcx hir::ImplItem) {
4960
let impl_item_def_id = self.tcx.map.local_def_id(i.id);
5061
let task_id = (self.dep_node_fn)(impl_item_def_id);

src/librustc/hir/intravisit.rs

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,17 @@ pub trait Visitor<'v> : Sized {
177177
}
178178
}
179179

180+
/// Like `visit_nested_item()`, but for trait items. See
181+
/// `visit_nested_item()` for advice on when to override this
182+
/// method.
183+
#[allow(unused_variables)]
184+
fn visit_nested_trait_item(&mut self, id: TraitItemId) {
185+
let opt_item = self.nested_visit_map().inter().map(|map| map.trait_item(id));
186+
if let Some(item) = opt_item {
187+
self.visit_trait_item(item);
188+
}
189+
}
190+
180191
/// Like `visit_nested_item()`, but for impl items. See
181192
/// `visit_nested_item()` for advice on when to override this
182193
/// method.
@@ -273,6 +284,9 @@ pub trait Visitor<'v> : Sized {
273284
fn visit_trait_item(&mut self, ti: &'v TraitItem) {
274285
walk_trait_item(self, ti)
275286
}
287+
fn visit_trait_item_ref(&mut self, ii: &'v TraitItemRef) {
288+
walk_trait_item_ref(self, ii)
289+
}
276290
fn visit_impl_item(&mut self, ii: &'v ImplItem) {
277291
walk_impl_item(self, ii)
278292
}
@@ -469,21 +483,19 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
469483
visitor.visit_generics(type_parameters);
470484
walk_list!(visitor, visit_trait_ref, opt_trait_reference);
471485
visitor.visit_ty(typ);
472-
for impl_item_ref in impl_item_refs {
473-
visitor.visit_impl_item_ref(impl_item_ref);
474-
}
486+
walk_list!(visitor, visit_impl_item_ref, impl_item_refs);
475487
}
476488
ItemStruct(ref struct_definition, ref generics) |
477489
ItemUnion(ref struct_definition, ref generics) => {
478490
visitor.visit_generics(generics);
479491
visitor.visit_id(item.id);
480492
visitor.visit_variant_data(struct_definition, item.name, generics, item.id, item.span);
481493
}
482-
ItemTrait(_, ref generics, ref bounds, ref methods) => {
494+
ItemTrait(_, ref generics, ref bounds, ref trait_item_refs) => {
483495
visitor.visit_id(item.id);
484496
visitor.visit_generics(generics);
485497
walk_list!(visitor, visit_ty_param_bound, bounds);
486-
walk_list!(visitor, visit_trait_item, methods);
498+
walk_list!(visitor, visit_trait_item_ref, trait_item_refs);
487499
}
488500
}
489501
walk_list!(visitor, visit_attribute, &item.attrs);
@@ -788,17 +800,17 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
788800
visitor.visit_name(trait_item.span, trait_item.name);
789801
walk_list!(visitor, visit_attribute, &trait_item.attrs);
790802
match trait_item.node {
791-
ConstTraitItem(ref ty, ref default) => {
803+
TraitItemKind::Const(ref ty, ref default) => {
792804
visitor.visit_id(trait_item.id);
793805
visitor.visit_ty(ty);
794806
walk_list!(visitor, visit_expr, default);
795807
}
796-
MethodTraitItem(ref sig, None) => {
808+
TraitItemKind::Method(ref sig, None) => {
797809
visitor.visit_id(trait_item.id);
798810
visitor.visit_generics(&sig.generics);
799811
visitor.visit_fn_decl(&sig.decl);
800812
}
801-
MethodTraitItem(ref sig, Some(body_id)) => {
813+
TraitItemKind::Method(ref sig, Some(body_id)) => {
802814
visitor.visit_fn(FnKind::Method(trait_item.name,
803815
sig,
804816
None,
@@ -808,14 +820,23 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
808820
trait_item.span,
809821
trait_item.id);
810822
}
811-
TypeTraitItem(ref bounds, ref default) => {
823+
TraitItemKind::Type(ref bounds, ref default) => {
812824
visitor.visit_id(trait_item.id);
813825
walk_list!(visitor, visit_ty_param_bound, bounds);
814826
walk_list!(visitor, visit_ty, default);
815827
}
816828
}
817829
}
818830

831+
pub fn walk_trait_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_item_ref: &'v TraitItemRef) {
832+
// NB: Deliberately force a compilation error if/when new fields are added.
833+
let TraitItemRef { id, name, ref kind, span, ref defaultness } = *trait_item_ref;
834+
visitor.visit_nested_trait_item(id);
835+
visitor.visit_name(span, name);
836+
visitor.visit_associated_item_kind(kind);
837+
visitor.visit_defaultness(defaultness);
838+
}
839+
819840
pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem) {
820841
// NB: Deliberately force a compilation error if/when new fields are added.
821842
let ImplItem { id: _, name, ref vis, ref defaultness, ref attrs, ref node, span } = *impl_item;

src/librustc/hir/itemlikevisit.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use super::{Item, ImplItem};
11+
use super::{Item, ImplItem, TraitItem};
1212
use super::intravisit::Visitor;
1313

1414
/// The "item-like visitor" visitor defines only the top-level methods
@@ -58,6 +58,7 @@ use super::intravisit::Visitor;
5858
/// needed.
5959
pub trait ItemLikeVisitor<'hir> {
6060
fn visit_item(&mut self, item: &'hir Item);
61+
fn visit_trait_item(&mut self, trait_item: &'hir TraitItem);
6162
fn visit_impl_item(&mut self, impl_item: &'hir ImplItem);
6263
}
6364

@@ -80,6 +81,10 @@ impl<'v, 'hir, V> ItemLikeVisitor<'hir> for DeepVisitor<'v, V>
8081
self.visitor.visit_item(item);
8182
}
8283

84+
fn visit_trait_item(&mut self, trait_item: &'hir TraitItem) {
85+
self.visitor.visit_trait_item(trait_item);
86+
}
87+
8388
fn visit_impl_item(&mut self, impl_item: &'hir ImplItem) {
8489
self.visitor.visit_impl_item(impl_item);
8590
}

src/librustc/hir/lowering.rs

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ use rustc_data_structures::fnv::FnvHashMap;
5151

5252
use std::collections::BTreeMap;
5353
use std::iter;
54-
use std::mem;
5554

5655
use syntax::ast::*;
5756
use syntax::errors;
@@ -77,6 +76,7 @@ pub struct LoweringContext<'a> {
7776
/// The items being lowered are collected here.
7877
items: BTreeMap<NodeId, hir::Item>,
7978

79+
trait_items: BTreeMap<hir::TraitItemId, hir::TraitItem>,
8080
impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem>,
8181
}
8282

@@ -108,6 +108,7 @@ pub fn lower_crate(sess: &Session,
108108
exprs: FnvHashMap(),
109109
resolver: resolver,
110110
items: BTreeMap::new(),
111+
trait_items: BTreeMap::new(),
111112
impl_items: BTreeMap::new(),
112113
}.lower_crate(krate)
113114
}
@@ -133,8 +134,9 @@ impl<'a> LoweringContext<'a> {
133134
span: c.span,
134135
exported_macros: exported_macros,
135136
items: self.items,
137+
trait_items: self.trait_items,
136138
impl_items: self.impl_items,
137-
exprs: mem::replace(&mut self.exprs, FnvHashMap()),
139+
exprs: self.exprs,
138140
}
139141
}
140142

@@ -150,8 +152,15 @@ impl<'a> LoweringContext<'a> {
150152
visit::walk_item(self, item);
151153
}
152154

155+
fn visit_trait_item(&mut self, item: &'lcx TraitItem) {
156+
let id = hir::TraitItemId { node_id: item.id };
157+
let hir_item = self.lctx.lower_trait_item(item);
158+
self.lctx.trait_items.insert(id, hir_item);
159+
visit::walk_trait_item(self, item);
160+
}
161+
153162
fn visit_impl_item(&mut self, item: &'lcx ImplItem) {
154-
let id = self.lctx.lower_impl_item_ref(item).id;
163+
let id = hir::ImplItemId { node_id: item.id };
155164
let hir_item = self.lctx.lower_impl_item(item);
156165
self.lctx.impl_items.insert(id, hir_item);
157166
visit::walk_impl_item(self, item);
@@ -907,7 +916,7 @@ impl<'a> LoweringContext<'a> {
907916
}
908917
ItemKind::Trait(unsafety, ref generics, ref bounds, ref items) => {
909918
let bounds = self.lower_bounds(bounds);
910-
let items = items.iter().map(|item| self.lower_trait_item(item)).collect();
919+
let items = items.iter().map(|item| self.lower_trait_item_ref(item)).collect();
911920
hir::ItemTrait(self.lower_unsafety(unsafety),
912921
self.lower_generics(generics),
913922
bounds,
@@ -925,20 +934,20 @@ impl<'a> LoweringContext<'a> {
925934
attrs: this.lower_attrs(&i.attrs),
926935
node: match i.node {
927936
TraitItemKind::Const(ref ty, ref default) => {
928-
hir::ConstTraitItem(this.lower_ty(ty),
929-
default.as_ref().map(|x| P(this.lower_expr(x))))
937+
hir::TraitItemKind::Const(this.lower_ty(ty),
938+
default.as_ref().map(|x| P(this.lower_expr(x))))
930939
}
931940
TraitItemKind::Method(ref sig, ref body) => {
932-
hir::MethodTraitItem(this.lower_method_sig(sig),
933-
body.as_ref().map(|x| {
941+
hir::TraitItemKind::Method(this.lower_method_sig(sig),
942+
body.as_ref().map(|x| {
934943
let body = this.lower_block(x);
935944
let expr = this.expr_block(body, ThinVec::new());
936945
this.record_expr(expr)
937946
}))
938947
}
939948
TraitItemKind::Type(ref bounds, ref default) => {
940-
hir::TypeTraitItem(this.lower_bounds(bounds),
941-
default.as_ref().map(|x| this.lower_ty(x)))
949+
hir::TraitItemKind::Type(this.lower_bounds(bounds),
950+
default.as_ref().map(|x| this.lower_ty(x)))
942951
}
943952
TraitItemKind::Macro(..) => panic!("Shouldn't exist any more"),
944953
},
@@ -947,6 +956,30 @@ impl<'a> LoweringContext<'a> {
947956
})
948957
}
949958

959+
fn lower_trait_item_ref(&mut self, i: &TraitItem) -> hir::TraitItemRef {
960+
let (kind, has_default) = match i.node {
961+
TraitItemKind::Const(_, ref default) => {
962+
(hir::AssociatedItemKind::Const, default.is_some())
963+
}
964+
TraitItemKind::Type(_, ref default) => {
965+
(hir::AssociatedItemKind::Type, default.is_some())
966+
}
967+
TraitItemKind::Method(ref sig, ref default) => {
968+
(hir::AssociatedItemKind::Method {
969+
has_self: sig.decl.has_self(),
970+
}, default.is_some())
971+
}
972+
TraitItemKind::Macro(..) => unimplemented!(),
973+
};
974+
hir::TraitItemRef {
975+
id: hir::TraitItemId { node_id: i.id },
976+
name: i.ident.name,
977+
span: i.span,
978+
defaultness: self.lower_defaultness(Defaultness::Default, has_default),
979+
kind: kind,
980+
}
981+
}
982+
950983
fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
951984
self.with_parent_def(i.id, |this| {
952985
hir::ImplItem {

src/librustc/hir/map/blocks.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ impl MaybeFnLike for ast::Item {
6262

6363
impl MaybeFnLike for ast::TraitItem {
6464
fn is_fn_like(&self) -> bool {
65-
match self.node { ast::MethodTraitItem(_, Some(_)) => true, _ => false, }
65+
match self.node { ast::TraitItemKind::Method(_, Some(_)) => true, _ => false, }
6666
}
6767
}
6868

@@ -252,7 +252,7 @@ impl<'a> FnLikeNode<'a> {
252252
_ => bug!("item FnLikeNode that is not fn-like"),
253253
},
254254
map::NodeTraitItem(ti) => match ti.node {
255-
ast::MethodTraitItem(ref sig, Some(body)) => {
255+
ast::TraitItemKind::Method(ref sig, Some(body)) => {
256256
method(ti.id, ti.name, sig, None, body, ti.span, &ti.attrs)
257257
}
258258
_ => bug!("trait method FnLikeNode that is not fn-like"),

src/librustc/hir/map/collector.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
9898
}
9999
}
100100

101+
fn visit_nested_trait_item(&mut self, item_id: TraitItemId) {
102+
self.visit_trait_item(self.krate.trait_item(item_id))
103+
}
104+
101105
fn visit_nested_impl_item(&mut self, item_id: ImplItemId) {
102106
self.visit_impl_item(self.krate.impl_item(item_id))
103107
}

src/librustc/hir/map/mod.rs

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -257,10 +257,20 @@ impl<'ast> Map<'ast> {
257257

258258
if let Some(last_id) = last_expr {
259259
// The body of the item may have a separate dep node
260-
// (Note that trait items don't currently have
261-
// their own dep node, so there's also just one
262-
// HirBody node for all the items)
263-
if self.is_body(last_id, item) {
260+
if self.is_item_body(last_id, item) {
261+
return DepNode::HirBody(def_id);
262+
}
263+
}
264+
return DepNode::Hir(def_id);
265+
}
266+
267+
EntryTraitItem(_, item) => {
268+
let def_id = self.local_def_id(id);
269+
assert!(!self.is_inlined_def_id(def_id));
270+
271+
if let Some(last_id) = last_expr {
272+
// The body of the item may have a separate dep node
273+
if self.is_trait_item_body(last_id, item) {
264274
return DepNode::HirBody(def_id);
265275
}
266276
}
@@ -280,7 +290,6 @@ impl<'ast> Map<'ast> {
280290
}
281291

282292
EntryForeignItem(p, _) |
283-
EntryTraitItem(p, _) |
284293
EntryVariant(p, _) |
285294
EntryField(p, _) |
286295
EntryStmt(p, _) |
@@ -358,18 +367,16 @@ impl<'ast> Map<'ast> {
358367
}
359368
}
360369

361-
fn is_body(&self, node_id: NodeId, item: &Item) -> bool {
370+
fn is_item_body(&self, node_id: NodeId, item: &Item) -> bool {
362371
match item.node {
363372
ItemFn(_, _, _, _, _, body) => body.node_id() == node_id,
364-
// Since trait items currently don't get their own dep nodes,
365-
// we check here whether node_id is the body of any of the items.
366-
// If they get their own dep nodes, this can go away
367-
ItemTrait(_, _, _, ref trait_items) => {
368-
trait_items.iter().any(|trait_item| { match trait_item.node {
369-
MethodTraitItem(_, Some(body)) => body.node_id() == node_id,
370-
_ => false
371-
}})
372-
}
373+
_ => false
374+
}
375+
}
376+
377+
fn is_trait_item_body(&self, node_id: NodeId, item: &TraitItem) -> bool {
378+
match item.node {
379+
TraitItemKind::Method(_, Some(body)) => body.node_id() == node_id,
373380
_ => false
374381
}
375382
}
@@ -436,6 +443,14 @@ impl<'ast> Map<'ast> {
436443
self.forest.krate()
437444
}
438445

446+
pub fn trait_item(&self, id: TraitItemId) -> &'ast TraitItem {
447+
self.read(id.node_id);
448+
449+
// NB: intentionally bypass `self.forest.krate()` so that we
450+
// do not trigger a read of the whole krate here
451+
self.forest.krate.trait_item(id)
452+
}
453+
439454
pub fn impl_item(&self, id: ImplItemId) -> &'ast ImplItem {
440455
self.read(id.node_id);
441456

@@ -1045,9 +1060,9 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
10451060
}
10461061
Some(NodeTraitItem(ti)) => {
10471062
let kind = match ti.node {
1048-
ConstTraitItem(..) => "assoc constant",
1049-
MethodTraitItem(..) => "trait method",
1050-
TypeTraitItem(..) => "assoc type",
1063+
TraitItemKind::Const(..) => "assoc constant",
1064+
TraitItemKind::Method(..) => "trait method",
1065+
TraitItemKind::Type(..) => "assoc type",
10511066
};
10521067

10531068
format!("{} {} in {}{}", kind, ti.name, path_str(), id_str)

0 commit comments

Comments
 (0)