diff options
| author | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2016-12-04 04:21:06 +0200 |
|---|---|---|
| committer | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2016-12-28 11:21:45 +0200 |
| commit | 864928297d0fc0675c5eae62a58d8488941d58cf (patch) | |
| tree | 1ea528de95d704bc8ebfde9af807287477d5d3d9 /src/librustc | |
| parent | 6ebb6fdbee7f0d250e50e4d84d9aede293cf3bb3 (diff) | |
| download | rust-864928297d0fc0675c5eae62a58d8488941d58cf.tar.gz rust-864928297d0fc0675c5eae62a58d8488941d58cf.zip | |
rustc: separate TraitItem from their parent Item, just like ImplItem.
Diffstat (limited to 'src/librustc')
| -rw-r--r-- | src/librustc/dep_graph/visit.rs | 11 | ||||
| -rw-r--r-- | src/librustc/hir/intravisit.rs | 39 | ||||
| -rw-r--r-- | src/librustc/hir/itemlikevisit.rs | 7 | ||||
| -rw-r--r-- | src/librustc/hir/lowering.rs | 53 | ||||
| -rw-r--r-- | src/librustc/hir/map/blocks.rs | 4 | ||||
| -rw-r--r-- | src/librustc/hir/map/collector.rs | 4 | ||||
| -rw-r--r-- | src/librustc/hir/map/mod.rs | 51 | ||||
| -rw-r--r-- | src/librustc/hir/mod.rs | 63 | ||||
| -rw-r--r-- | src/librustc/hir/print.rs | 18 | ||||
| -rw-r--r-- | src/librustc/infer/error_reporting.rs | 2 | ||||
| -rw-r--r-- | src/librustc/middle/cstore.rs | 4 | ||||
| -rw-r--r-- | src/librustc/middle/dead.rs | 23 | ||||
| -rw-r--r-- | src/librustc/middle/entry.rs | 5 | ||||
| -rw-r--r-- | src/librustc/middle/intrinsicck.rs | 2 | ||||
| -rw-r--r-- | src/librustc/middle/lang_items.rs | 4 | ||||
| -rw-r--r-- | src/librustc/middle/reachable.rs | 18 | ||||
| -rw-r--r-- | src/librustc/middle/resolve_lifetime.rs | 2 | ||||
| -rw-r--r-- | src/librustc/mir/transform.rs | 2 | ||||
| -rw-r--r-- | src/librustc/ty/mod.rs | 46 |
19 files changed, 240 insertions, 118 deletions
diff --git a/src/librustc/dep_graph/visit.rs b/src/librustc/dep_graph/visit.rs index f6a22e47cf2..61f58fc8fe5 100644 --- a/src/librustc/dep_graph/visit.rs +++ b/src/librustc/dep_graph/visit.rs @@ -45,6 +45,17 @@ pub fn visit_all_item_likes_in_krate<'a, 'tcx, V, F>(tcx: TyCtxt<'a, 'tcx, 'tcx> debug!("Ended task {:?}", task_id); } + fn visit_trait_item(&mut self, i: &'tcx hir::TraitItem) { + let trait_item_def_id = self.tcx.map.local_def_id(i.id); + let task_id = (self.dep_node_fn)(trait_item_def_id); + let _task = self.tcx.dep_graph.in_task(task_id.clone()); + debug!("Started task {:?}", task_id); + assert!(!self.tcx.map.is_inlined_def_id(trait_item_def_id)); + self.tcx.dep_graph.read(DepNode::Hir(trait_item_def_id)); + self.visitor.visit_trait_item(i); + debug!("Ended task {:?}", task_id); + } + fn visit_impl_item(&mut self, i: &'tcx hir::ImplItem) { let impl_item_def_id = self.tcx.map.local_def_id(i.id); let task_id = (self.dep_node_fn)(impl_item_def_id); diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 474d7d508c4..e16c97f2d25 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -177,6 +177,17 @@ pub trait Visitor<'v> : Sized { } } + /// Like `visit_nested_item()`, but for trait items. See + /// `visit_nested_item()` for advice on when to override this + /// method. + #[allow(unused_variables)] + fn visit_nested_trait_item(&mut self, id: TraitItemId) { + let opt_item = self.nested_visit_map().inter().map(|map| map.trait_item(id)); + if let Some(item) = opt_item { + self.visit_trait_item(item); + } + } + /// Like `visit_nested_item()`, but for impl items. See /// `visit_nested_item()` for advice on when to override this /// method. @@ -273,6 +284,9 @@ pub trait Visitor<'v> : Sized { fn visit_trait_item(&mut self, ti: &'v TraitItem) { walk_trait_item(self, ti) } + fn visit_trait_item_ref(&mut self, ii: &'v TraitItemRef) { + walk_trait_item_ref(self, ii) + } fn visit_impl_item(&mut self, ii: &'v ImplItem) { walk_impl_item(self, ii) } @@ -469,9 +483,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { visitor.visit_generics(type_parameters); walk_list!(visitor, visit_trait_ref, opt_trait_reference); visitor.visit_ty(typ); - for impl_item_ref in impl_item_refs { - visitor.visit_impl_item_ref(impl_item_ref); - } + walk_list!(visitor, visit_impl_item_ref, impl_item_refs); } ItemStruct(ref struct_definition, ref generics) | ItemUnion(ref struct_definition, ref generics) => { @@ -479,11 +491,11 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { visitor.visit_id(item.id); visitor.visit_variant_data(struct_definition, item.name, generics, item.id, item.span); } - ItemTrait(_, ref generics, ref bounds, ref methods) => { + ItemTrait(_, ref generics, ref bounds, ref trait_item_refs) => { visitor.visit_id(item.id); visitor.visit_generics(generics); walk_list!(visitor, visit_ty_param_bound, bounds); - walk_list!(visitor, visit_trait_item, methods); + walk_list!(visitor, visit_trait_item_ref, trait_item_refs); } } 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 visitor.visit_name(trait_item.span, trait_item.name); walk_list!(visitor, visit_attribute, &trait_item.attrs); match trait_item.node { - ConstTraitItem(ref ty, ref default) => { + TraitItemKind::Const(ref ty, ref default) => { visitor.visit_id(trait_item.id); visitor.visit_ty(ty); walk_list!(visitor, visit_expr, default); } - MethodTraitItem(ref sig, None) => { + TraitItemKind::Method(ref sig, None) => { visitor.visit_id(trait_item.id); visitor.visit_generics(&sig.generics); visitor.visit_fn_decl(&sig.decl); } - MethodTraitItem(ref sig, Some(body_id)) => { + TraitItemKind::Method(ref sig, Some(body_id)) => { visitor.visit_fn(FnKind::Method(trait_item.name, sig, None, @@ -808,7 +820,7 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai trait_item.span, trait_item.id); } - TypeTraitItem(ref bounds, ref default) => { + TraitItemKind::Type(ref bounds, ref default) => { visitor.visit_id(trait_item.id); walk_list!(visitor, visit_ty_param_bound, bounds); walk_list!(visitor, visit_ty, default); @@ -816,6 +828,15 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai } } +pub fn walk_trait_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_item_ref: &'v TraitItemRef) { + // NB: Deliberately force a compilation error if/when new fields are added. + let TraitItemRef { id, name, ref kind, span, ref defaultness } = *trait_item_ref; + visitor.visit_nested_trait_item(id); + visitor.visit_name(span, name); + visitor.visit_associated_item_kind(kind); + visitor.visit_defaultness(defaultness); +} + pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem) { // NB: Deliberately force a compilation error if/when new fields are added. let ImplItem { id: _, name, ref vis, ref defaultness, ref attrs, ref node, span } = *impl_item; diff --git a/src/librustc/hir/itemlikevisit.rs b/src/librustc/hir/itemlikevisit.rs index 71ef7131440..f359ca20163 100644 --- a/src/librustc/hir/itemlikevisit.rs +++ b/src/librustc/hir/itemlikevisit.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use super::{Item, ImplItem}; +use super::{Item, ImplItem, TraitItem}; use super::intravisit::Visitor; /// The "item-like visitor" visitor defines only the top-level methods @@ -58,6 +58,7 @@ use super::intravisit::Visitor; /// needed. pub trait ItemLikeVisitor<'hir> { fn visit_item(&mut self, item: &'hir Item); + fn visit_trait_item(&mut self, trait_item: &'hir TraitItem); fn visit_impl_item(&mut self, impl_item: &'hir ImplItem); } @@ -80,6 +81,10 @@ impl<'v, 'hir, V> ItemLikeVisitor<'hir> for DeepVisitor<'v, V> self.visitor.visit_item(item); } + fn visit_trait_item(&mut self, trait_item: &'hir TraitItem) { + self.visitor.visit_trait_item(trait_item); + } + fn visit_impl_item(&mut self, impl_item: &'hir ImplItem) { self.visitor.visit_impl_item(impl_item); } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index d1fe19364b4..75228811813 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -51,7 +51,6 @@ use rustc_data_structures::fnv::FnvHashMap; use std::collections::BTreeMap; use std::iter; -use std::mem; use syntax::ast::*; use syntax::errors; @@ -77,6 +76,7 @@ pub struct LoweringContext<'a> { /// The items being lowered are collected here. items: BTreeMap<NodeId, hir::Item>, + trait_items: BTreeMap<hir::TraitItemId, hir::TraitItem>, impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem>, } @@ -108,6 +108,7 @@ pub fn lower_crate(sess: &Session, exprs: FnvHashMap(), resolver: resolver, items: BTreeMap::new(), + trait_items: BTreeMap::new(), impl_items: BTreeMap::new(), }.lower_crate(krate) } @@ -133,8 +134,9 @@ impl<'a> LoweringContext<'a> { span: c.span, exported_macros: exported_macros, items: self.items, + trait_items: self.trait_items, impl_items: self.impl_items, - exprs: mem::replace(&mut self.exprs, FnvHashMap()), + exprs: self.exprs, } } @@ -150,8 +152,15 @@ impl<'a> LoweringContext<'a> { visit::walk_item(self, item); } + fn visit_trait_item(&mut self, item: &'lcx TraitItem) { + let id = hir::TraitItemId { node_id: item.id }; + let hir_item = self.lctx.lower_trait_item(item); + self.lctx.trait_items.insert(id, hir_item); + visit::walk_trait_item(self, item); + } + fn visit_impl_item(&mut self, item: &'lcx ImplItem) { - let id = self.lctx.lower_impl_item_ref(item).id; + let id = hir::ImplItemId { node_id: item.id }; let hir_item = self.lctx.lower_impl_item(item); self.lctx.impl_items.insert(id, hir_item); visit::walk_impl_item(self, item); @@ -907,7 +916,7 @@ impl<'a> LoweringContext<'a> { } ItemKind::Trait(unsafety, ref generics, ref bounds, ref items) => { let bounds = self.lower_bounds(bounds); - let items = items.iter().map(|item| self.lower_trait_item(item)).collect(); + let items = items.iter().map(|item| self.lower_trait_item_ref(item)).collect(); hir::ItemTrait(self.lower_unsafety(unsafety), self.lower_generics(generics), bounds, @@ -925,20 +934,20 @@ impl<'a> LoweringContext<'a> { attrs: this.lower_attrs(&i.attrs), node: match i.node { TraitItemKind::Const(ref ty, ref default) => { - hir::ConstTraitItem(this.lower_ty(ty), - default.as_ref().map(|x| P(this.lower_expr(x)))) + hir::TraitItemKind::Const(this.lower_ty(ty), + default.as_ref().map(|x| P(this.lower_expr(x)))) } TraitItemKind::Method(ref sig, ref body) => { - hir::MethodTraitItem(this.lower_method_sig(sig), - body.as_ref().map(|x| { + hir::TraitItemKind::Method(this.lower_method_sig(sig), + body.as_ref().map(|x| { let body = this.lower_block(x); let expr = this.expr_block(body, ThinVec::new()); this.record_expr(expr) })) } TraitItemKind::Type(ref bounds, ref default) => { - hir::TypeTraitItem(this.lower_bounds(bounds), - default.as_ref().map(|x| this.lower_ty(x))) + hir::TraitItemKind::Type(this.lower_bounds(bounds), + default.as_ref().map(|x| this.lower_ty(x))) } TraitItemKind::Macro(..) => panic!("Shouldn't exist any more"), }, @@ -947,6 +956,30 @@ impl<'a> LoweringContext<'a> { }) } + fn lower_trait_item_ref(&mut self, i: &TraitItem) -> hir::TraitItemRef { + let (kind, has_default) = match i.node { + TraitItemKind::Const(_, ref default) => { + (hir::AssociatedItemKind::Const, default.is_some()) + } + TraitItemKind::Type(_, ref default) => { + (hir::AssociatedItemKind::Type, default.is_some()) + } + TraitItemKind::Method(ref sig, ref default) => { + (hir::AssociatedItemKind::Method { + has_self: sig.decl.has_self(), + }, default.is_some()) + } + TraitItemKind::Macro(..) => unimplemented!(), + }; + hir::TraitItemRef { + id: hir::TraitItemId { node_id: i.id }, + name: i.ident.name, + span: i.span, + defaultness: self.lower_defaultness(Defaultness::Default, has_default), + kind: kind, + } + } + fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem { self.with_parent_def(i.id, |this| { hir::ImplItem { diff --git a/src/librustc/hir/map/blocks.rs b/src/librustc/hir/map/blocks.rs index 068e7ed8624..8df4d669d0c 100644 --- a/src/librustc/hir/map/blocks.rs +++ b/src/librustc/hir/map/blocks.rs @@ -62,7 +62,7 @@ impl MaybeFnLike for ast::Item { impl MaybeFnLike for ast::TraitItem { fn is_fn_like(&self) -> bool { - match self.node { ast::MethodTraitItem(_, Some(_)) => true, _ => false, } + match self.node { ast::TraitItemKind::Method(_, Some(_)) => true, _ => false, } } } @@ -252,7 +252,7 @@ impl<'a> FnLikeNode<'a> { _ => bug!("item FnLikeNode that is not fn-like"), }, map::NodeTraitItem(ti) => match ti.node { - ast::MethodTraitItem(ref sig, Some(body)) => { + ast::TraitItemKind::Method(ref sig, Some(body)) => { method(ti.id, ti.name, sig, None, body, ti.span, &ti.attrs) } _ => bug!("trait method FnLikeNode that is not fn-like"), diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 45988886a60..9a4047f70e3 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -98,6 +98,10 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { } } + fn visit_nested_trait_item(&mut self, item_id: TraitItemId) { + self.visit_trait_item(self.krate.trait_item(item_id)) + } + fn visit_nested_impl_item(&mut self, item_id: ImplItemId) { self.visit_impl_item(self.krate.impl_item(item_id)) } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 4546f6d8c27..a6ead8efe51 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -257,10 +257,20 @@ impl<'ast> Map<'ast> { if let Some(last_id) = last_expr { // The body of the item may have a separate dep node - // (Note that trait items don't currently have - // their own dep node, so there's also just one - // HirBody node for all the items) - if self.is_body(last_id, item) { + if self.is_item_body(last_id, item) { + return DepNode::HirBody(def_id); + } + } + return DepNode::Hir(def_id); + } + + EntryTraitItem(_, item) => { + let def_id = self.local_def_id(id); + assert!(!self.is_inlined_def_id(def_id)); + + if let Some(last_id) = last_expr { + // The body of the item may have a separate dep node + if self.is_trait_item_body(last_id, item) { return DepNode::HirBody(def_id); } } @@ -280,7 +290,6 @@ impl<'ast> Map<'ast> { } EntryForeignItem(p, _) | - EntryTraitItem(p, _) | EntryVariant(p, _) | EntryField(p, _) | EntryStmt(p, _) | @@ -358,18 +367,16 @@ impl<'ast> Map<'ast> { } } - fn is_body(&self, node_id: NodeId, item: &Item) -> bool { + fn is_item_body(&self, node_id: NodeId, item: &Item) -> bool { match item.node { ItemFn(_, _, _, _, _, body) => body.node_id() == node_id, - // Since trait items currently don't get their own dep nodes, - // we check here whether node_id is the body of any of the items. - // If they get their own dep nodes, this can go away - ItemTrait(_, _, _, ref trait_items) => { - trait_items.iter().any(|trait_item| { match trait_item.node { - MethodTraitItem(_, Some(body)) => body.node_id() == node_id, - _ => false - }}) - } + _ => false + } + } + + fn is_trait_item_body(&self, node_id: NodeId, item: &TraitItem) -> bool { + match item.node { + TraitItemKind::Method(_, Some(body)) => body.node_id() == node_id, _ => false } } @@ -436,6 +443,14 @@ impl<'ast> Map<'ast> { self.forest.krate() } + pub fn trait_item(&self, id: TraitItemId) -> &'ast TraitItem { + self.read(id.node_id); + + // NB: intentionally bypass `self.forest.krate()` so that we + // do not trigger a read of the whole krate here + self.forest.krate.trait_item(id) + } + pub fn impl_item(&self, id: ImplItemId) -> &'ast ImplItem { self.read(id.node_id); @@ -1045,9 +1060,9 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String { } Some(NodeTraitItem(ti)) => { let kind = match ti.node { - ConstTraitItem(..) => "assoc constant", - MethodTraitItem(..) => "trait method", - TypeTraitItem(..) => "assoc type", + TraitItemKind::Const(..) => "assoc constant", + TraitItemKind::Method(..) => "trait method", + TraitItemKind::Type(..) => "assoc type", }; format!("{} {} in {}{}", kind, ti.name, path_str(), id_str) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index d135762ae82..db65d34e3d9 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -22,7 +22,6 @@ pub use self::Item_::*; pub use self::Mutability::*; pub use self::PrimTy::*; pub use self::Stmt_::*; -pub use self::TraitItem_::*; pub use self::Ty_::*; pub use self::TyParamBound::*; pub use self::UnOp::*; @@ -41,7 +40,7 @@ use syntax::abi::Abi; use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, AsmDialect}; use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem}; use syntax::ptr::P; -use syntax::symbol::{Symbol, keywords}; +use syntax::symbol::Symbol; use syntax::tokenstream::TokenTree; use syntax::util::ThinVec; @@ -431,6 +430,7 @@ pub struct Crate { // slightly different results. pub items: BTreeMap<NodeId, Item>, + pub trait_items: BTreeMap<TraitItemId, TraitItem>, pub impl_items: BTreeMap<ImplItemId, ImplItem>, pub exprs: FnvHashMap<ExprId, Expr>, } @@ -440,6 +440,10 @@ impl Crate { &self.items[&id] } + pub fn trait_item(&self, id: TraitItemId) -> &TraitItem { + &self.trait_items[&id] + } + pub fn impl_item(&self, id: ImplItemId) -> &ImplItem { &self.impl_items[&id] } @@ -459,6 +463,10 @@ impl Crate { visitor.visit_item(item); } + for (_, trait_item) in &self.trait_items { + visitor.visit_trait_item(trait_item); + } + for (_, impl_item) in &self.impl_items { visitor.visit_impl_item(impl_item); } @@ -1070,6 +1078,14 @@ pub struct MethodSig { pub generics: Generics, } +// The bodies for items are stored "out of line", in a separate +// hashmap in the `Crate`. Here we just record the node-id of the item +// so it can fetched later. +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct TraitItemId { + pub node_id: NodeId, +} + /// Represents an item declaration within a trait declaration, /// possibly including a default implementation. A trait item is /// either required (meaning it doesn't have an implementation, just a @@ -1079,21 +1095,21 @@ pub struct TraitItem { pub id: NodeId, pub name: Name, pub attrs: HirVec<Attribute>, - pub node: TraitItem_, + pub node: TraitItemKind, pub span: Span, } /// Represents a trait method or associated constant or type #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum TraitItem_ { +pub enum TraitItemKind { /// An associated constant with an optional value (otherwise `impl`s /// must contain a value) - ConstTraitItem(P<Ty>, Option<P<Expr>>), + Const(P<Ty>, Option<P<Expr>>), /// A method with an optional body - MethodTraitItem(MethodSig, Option<ExprId>), + Method(MethodSig, Option<ExprId>), /// An associated type with (possibly empty) bounds and optional concrete /// type - TypeTraitItem(TyParamBounds, Option<P<Ty>>), + Type(TyParamBounds, Option<P<Ty>>), } // The bodies for items are stored "out of line", in a separate @@ -1234,16 +1250,6 @@ pub struct Arg { pub id: NodeId, } -impl Arg { - fn is_self(&self) -> bool { - if let PatKind::Binding(_, _, name, _) = self.pat.node { - name.node == keywords::SelfValue.name() - } else { - false - } - } -} - /// Represents the header (not the body) of a function declaration #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct FnDecl { @@ -1252,12 +1258,6 @@ pub struct FnDecl { pub variadic: bool, } -impl FnDecl { - pub fn has_self(&self) -> bool { - self.inputs.get(0).map(Arg::is_self).unwrap_or(false) - } -} - #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum Unsafety { Unsafe, @@ -1548,7 +1548,7 @@ pub enum Item_ { /// A union definition, e.g. `union Foo<A, B> {x: A, y: B}` ItemUnion(VariantData, Generics), /// Represents a Trait Declaration - ItemTrait(Unsafety, Generics, TyParamBounds, HirVec<TraitItem>), + ItemTrait(Unsafety, Generics, TyParamBounds, HirVec<TraitItemRef>), // Default trait implementations /// @@ -1584,6 +1584,21 @@ impl Item_ { } } +/// A reference from an trait 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 TraitItemRef { + pub id: TraitItemId, + pub name: Name, + pub kind: AssociatedItemKind, + pub span: Span, + pub defaultness: Defaultness, +} + /// 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 diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index eaed62e4dce..745ab4e6372 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -858,7 +858,7 @@ impl<'a> State<'a> { word(&mut self.s, " ")?; self.bopen()?; for trait_item in trait_items { - self.print_trait_item(trait_item)?; + self.print_trait_item_ref(trait_item)?; } self.bclose(item.span)?; } @@ -1008,19 +1008,29 @@ impl<'a> State<'a> { vis) } + pub fn print_trait_item_ref(&mut self, item_ref: &hir::TraitItemRef) -> io::Result<()> { + if let Some(krate) = self.krate { + // skip nested items if krate context was not provided + let item = &krate.trait_item(item_ref.id); + self.print_trait_item(item) + } else { + Ok(()) + } + } + pub fn print_trait_item(&mut self, ti: &hir::TraitItem) -> io::Result<()> { self.ann.pre(self, NodeSubItem(ti.id))?; self.hardbreak_if_not_bol()?; self.maybe_print_comment(ti.span.lo)?; self.print_outer_attributes(&ti.attrs)?; match ti.node { - hir::ConstTraitItem(ref ty, ref default) => { + hir::TraitItemKind::Const(ref ty, ref default) => { self.print_associated_const(ti.name, &ty, default.as_ref().map(|expr| &**expr), &hir::Inherited)?; } - hir::MethodTraitItem(ref sig, ref body) => { + hir::TraitItemKind::Method(ref sig, ref body) => { if body.is_some() { self.head("")?; } @@ -1034,7 +1044,7 @@ impl<'a> State<'a> { word(&mut self.s, ";")?; } } - hir::TypeTraitItem(ref bounds, ref default) => { + hir::TraitItemKind::Type(ref bounds, ref default) => { self.print_associated_type(ti.name, Some(bounds), default.as_ref().map(|ty| &**ty))?; diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs index 9d48fbca53e..026f4b187e2 100644 --- a/src/librustc/infer/error_reporting.rs +++ b/src/librustc/infer/error_reporting.rs @@ -1079,7 +1079,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { }, ast_map::NodeTraitItem(item) => { match item.node { - hir::MethodTraitItem(ref sig, Some(_)) => { + hir::TraitItemKind::Method(ref sig, Some(_)) => { Some((&sig.decl, &sig.generics, sig.unsafety, diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index d0003693eef..7d570596386 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -183,9 +183,9 @@ impl<'a> InlinedItemRef<'a> { _tcx: TyCtxt) -> InlinedItemRef<'a> { let (body, args) = match item.node { - hir::ConstTraitItem(_, Some(ref body)) => + hir::TraitItemKind::Const(_, Some(ref body)) => (&**body, Vec::new()), - hir::ConstTraitItem(_, None) => { + hir::TraitItemKind::Const(_, None) => { bug!("InlinedItemRef::from_trait_item called for const without body") }, _ => bug!("InlinedItemRef::from_trait_item wrong kind") diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 1c5dd97b74b..2206336164a 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -328,11 +328,12 @@ impl<'v, 'k> ItemLikeVisitor<'v> for LifeSeeder<'k> { self.worklist.extend(enum_def.variants.iter() .map(|variant| variant.node.data.id())); } - hir::ItemTrait(.., ref trait_items) => { - for trait_item in trait_items { + hir::ItemTrait(.., ref trait_item_refs) => { + for trait_item_ref in trait_item_refs { + let trait_item = self.krate.trait_item(trait_item_ref.id); match trait_item.node { - hir::ConstTraitItem(_, Some(_)) | - hir::MethodTraitItem(_, Some(_)) => { + hir::TraitItemKind::Const(_, Some(_)) | + hir::TraitItemKind::Method(_, Some(_)) => { if has_allow_dead_code_or_lang_attr(&trait_item.attrs) { self.worklist.push(trait_item.id); } @@ -354,6 +355,10 @@ impl<'v, 'k> ItemLikeVisitor<'v> for LifeSeeder<'k> { } } + fn visit_trait_item(&mut self, _item: &hir::TraitItem) { + // ignore: we are handling this in `visit_item` above + } + fn visit_impl_item(&mut self, _item: &hir::ImplItem) { // ignore: we are handling this in `visit_item` above } @@ -567,15 +572,15 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> { // Overwrite so that we don't warn the trait item itself. fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) { match trait_item.node { - hir::ConstTraitItem(_, Some(ref body)) => { + hir::TraitItemKind::Const(_, Some(ref body)) => { intravisit::walk_expr(self, body) } - hir::MethodTraitItem(_, Some(body_id)) => { + hir::TraitItemKind::Method(_, Some(body_id)) => { self.visit_body(body_id) } - hir::ConstTraitItem(_, None) | - hir::MethodTraitItem(_, None) | - hir::TypeTraitItem(..) => {} + hir::TraitItemKind::Const(_, None) | + hir::TraitItemKind::Method(_, None) | + hir::TraitItemKind::Type(..) => {} } } } diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index e927843a984..f2e46d4cbc9 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -17,7 +17,7 @@ use syntax::ast::NodeId; use syntax::attr; use syntax::entry::EntryPointType; use syntax_pos::Span; -use hir::{Item, ItemFn, ImplItem}; +use hir::{Item, ItemFn, ImplItem, TraitItem}; use hir::itemlikevisit::ItemLikeVisitor; struct EntryContext<'a, 'tcx: 'a> { @@ -47,6 +47,9 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> { find_item(item, self, at_root); } + fn visit_trait_item(&mut self, _trait_item: &'tcx TraitItem) { + // entry fn is never a trait item + } fn visit_impl_item(&mut self, _impl_item: &'tcx ImplItem) { // entry fn is never an impl item diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index 2357549c82e..1c31e1800ee 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -132,7 +132,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ItemVisitor<'a, 'tcx> { } fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem) { - if let hir::ConstTraitItem(_, Some(ref expr)) = item.node { + if let hir::TraitItemKind::Const(_, Some(ref expr)) = item.node { self.visit_const(item.id, expr); } else { intravisit::walk_trait_item(self, item); diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 029a1d66add..4cae5b370eb 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -140,6 +140,10 @@ impl<'a, 'v, 'tcx> ItemLikeVisitor<'v> for LanguageItemCollector<'a, 'tcx> { } } + fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) { + // at present, lang items are always items, not trait items + } + fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) { // at present, lang items are always items, not impl items } diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 2c4710f1e45..25f70d04819 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -166,9 +166,9 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { } Some(ast_map::NodeTraitItem(trait_method)) => { match trait_method.node { - hir::ConstTraitItem(_, ref default) => default.is_some(), - hir::MethodTraitItem(_, ref body) => body.is_some(), - hir::TypeTraitItem(..) => false, + hir::TraitItemKind::Const(_, ref default) => default.is_some(), + hir::TraitItemKind::Method(_, ref body) => body.is_some(), + hir::TraitItemKind::Type(..) => false, } } Some(ast_map::NodeImplItem(impl_item)) => { @@ -274,17 +274,17 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { } ast_map::NodeTraitItem(trait_method) => { match trait_method.node { - hir::ConstTraitItem(_, None) | - hir::MethodTraitItem(_, None) => { + hir::TraitItemKind::Const(_, None) | + hir::TraitItemKind::Method(_, None) => { // Keep going, nothing to get exported } - hir::ConstTraitItem(_, Some(ref body)) => { + hir::TraitItemKind::Const(_, Some(ref body)) => { self.visit_expr(body); } - hir::MethodTraitItem(_, Some(body_id)) => { + hir::TraitItemKind::Method(_, Some(body_id)) => { self.visit_body(body_id); } - hir::TypeTraitItem(..) => {} + hir::TraitItemKind::Type(..) => {} } } ast_map::NodeImplItem(impl_item) => { @@ -358,6 +358,8 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, } } + fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {} + fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) { // processed in visit_item above } diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index c5b03a4a32a..443770e61b6 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -266,7 +266,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // methods in an impl can reuse label names. let saved = replace(&mut self.labels_in_fn, vec![]); - if let hir::MethodTraitItem(ref sig, None) = trait_item.node { + if let hir::TraitItemKind::Method(ref sig, None) = trait_item.node { self.visit_early_late( trait_item.id, &sig.decl, &sig.generics, diff --git a/src/librustc/mir/transform.rs b/src/librustc/mir/transform.rs index 3576ae662a0..3c5a91f4ff0 100644 --- a/src/librustc/mir/transform.rs +++ b/src/librustc/mir/transform.rs @@ -48,7 +48,7 @@ impl<'a, 'tcx> MirSource { match tcx.map.get(id) { map::NodeItem(&Item { node: ItemConst(..), .. }) | - map::NodeTraitItem(&TraitItem { node: ConstTraitItem(..), .. }) | + map::NodeTraitItem(&TraitItem { node: TraitItemKind::Const(..), .. }) | map::NodeImplItem(&ImplItem { node: ImplItemKind::Const(..), .. }) => { MirSource::Const(id) } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 180141d674a..67137470098 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1212,7 +1212,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { } Some(ast_map::NodeTraitItem(trait_item)) => { match trait_item.node { - hir::TypeTraitItem(..) | hir::ConstTraitItem(..) => { + hir::TraitItemKind::Type(..) | hir::TraitItemKind::Const(..) => { // associated types don't have their own entry (for some reason), // so for now just grab environment for the trait let trait_id = tcx.map.get_parent(id); @@ -1221,7 +1221,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { trait_def_id, tcx.region_maps.item_extent(id)) } - hir::MethodTraitItem(_, ref body) => { + hir::TraitItemKind::Method(_, ref body) => { // Use call-site for extent (unless this is a // trait method with no default; then fallback // to the method id). @@ -2100,10 +2100,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } - hir::ItemTrait(.., ref trait_items) => { - for trait_item in trait_items { + hir::ItemTrait(.., ref trait_item_refs) => { + for trait_item_ref in trait_item_refs { let assoc_item = - self.associated_item_from_trait_item_ref(parent_def_id, trait_item); + self.associated_item_from_trait_item_ref(parent_def_id, trait_item_ref); self.associated_items.borrow_mut().insert(assoc_item.def_id, assoc_item); } } @@ -2121,28 +2121,22 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { fn associated_item_from_trait_item_ref(self, parent_def_id: DefId, - trait_item: &hir::TraitItem) + trait_item_ref: &hir::TraitItemRef) -> AssociatedItem { - let def_id = self.map.local_def_id(trait_item.id); - - let (kind, has_self, has_value) = match trait_item.node { - hir::MethodTraitItem(ref sig, ref body) => { - (AssociatedKind::Method, sig.decl.has_self(), - body.is_some()) - } - hir::ConstTraitItem(_, ref value) => { - (AssociatedKind::Const, false, value.is_some()) - } - hir::TypeTraitItem(_, ref ty) => { - (AssociatedKind::Type, false, ty.is_some()) + let def_id = self.map.local_def_id(trait_item_ref.id.node_id); + let (kind, has_self) = match trait_item_ref.kind { + hir::AssociatedItemKind::Const => (ty::AssociatedKind::Const, false), + hir::AssociatedItemKind::Method { has_self } => { + (ty::AssociatedKind::Method, has_self) } + hir::AssociatedItemKind::Type => (ty::AssociatedKind::Type, false), }; AssociatedItem { - name: trait_item.name, + name: trait_item_ref.name, kind: kind, - vis: Visibility::from_hir(&hir::Inherited, trait_item.id, self), - defaultness: hir::Defaultness::Default { has_value: has_value }, + vis: Visibility::from_hir(&hir::Inherited, trait_item_ref.id.node_id, self), + defaultness: trait_item_ref.defaultness, def_id: def_id, container: TraitContainer(parent_def_id), method_has_self_argument: has_self @@ -2187,11 +2181,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let id = self.map.as_local_node_id(def_id).unwrap(); let item = self.map.expect_item(id); let vec: Vec<_> = match item.node { - hir::ItemTrait(.., ref trait_items) => { - trait_items.iter() - .map(|trait_item| trait_item.id) - .map(|id| self.map.local_def_id(id)) - .collect() + hir::ItemTrait(.., ref trait_item_refs) => { + trait_item_refs.iter() + .map(|trait_item_ref| trait_item_ref.id) + .map(|id| self.map.local_def_id(id.node_id)) + .collect() } hir::ItemImpl(.., ref impl_item_refs) => { impl_item_refs.iter() |
