diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 877027a21a2..49611689fc4 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -571,7 +571,8 @@ impl<'a> LoweringContext<'a> { def_node_id, DefPathData::LifetimeDef(name.as_str()), DefIndexAddressSpace::High, - Mark::root() + Mark::root(), + span ); hir::GenericParam::Lifetime(hir::LifetimeDef { @@ -1003,7 +1004,8 @@ impl<'a> LoweringContext<'a> { def_node_id, DefPathData::ImplTrait, DefIndexAddressSpace::High, - Mark::root() + Mark::root(), + span ); let hir_bounds = self.lower_bounds(bounds, itctx); @@ -1150,7 +1152,8 @@ impl<'a> LoweringContext<'a> { def_node_id, DefPathData::LifetimeDef(name.name().as_str()), DefIndexAddressSpace::High, - Mark::root() + Mark::root(), + lifetime.span ); let def_lifetime = hir::Lifetime { id: def_node_id, diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index cdd63957478..3619a7fb0c6 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -18,6 +18,7 @@ use syntax::visit; use syntax::symbol::keywords; use syntax::symbol::Symbol; use syntax::parse::token::{self, Token}; +use syntax_pos::Span; use hir::map::{ITEM_LIKE_SPACE, REGULAR_SPACE}; @@ -57,12 +58,13 @@ impl<'a> DefCollector<'a> { fn create_def(&mut self, node_id: NodeId, data: DefPathData, - address_space: DefIndexAddressSpace) + address_space: DefIndexAddressSpace, + span: Span) -> DefIndex { let parent_def = self.parent_def.unwrap(); debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def); self.definitions - .create_def_with_parent(parent_def, node_id, data, address_space, self.expansion) + .create_def_with_parent(parent_def, node_id, data, address_space, self.expansion, span) } pub fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_def: DefIndex, f: F) { @@ -83,7 +85,7 @@ impl<'a> DefCollector<'a> { _ => {} } - self.create_def(expr.id, DefPathData::Initializer, REGULAR_SPACE); + self.create_def(expr.id, DefPathData::Initializer, REGULAR_SPACE, expr.span); } fn visit_macro_invoc(&mut self, id: NodeId, const_expr: bool) { @@ -122,7 +124,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { return visit::walk_item(self, i); } }; - let def = self.create_def(i.id, def_data, ITEM_LIKE_SPACE); + let def = self.create_def(i.id, def_data, ITEM_LIKE_SPACE, i.span); self.with_parent(def, |this| { match i.node { @@ -131,14 +133,16 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { let variant_def_index = this.create_def(v.node.data.id(), DefPathData::EnumVariant(v.node.name.name.as_str()), - REGULAR_SPACE); + REGULAR_SPACE, + v.span); this.with_parent(variant_def_index, |this| { for (index, field) in v.node.data.fields().iter().enumerate() { let name = field.ident.map(|ident| ident.name) .unwrap_or_else(|| Symbol::intern(&index.to_string())); this.create_def(field.id, DefPathData::Field(name.as_str()), - REGULAR_SPACE); + REGULAR_SPACE, + field.span); } if let Some(ref expr) = v.node.disr_expr { @@ -152,13 +156,17 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { if !struct_def.is_struct() { this.create_def(struct_def.id(), DefPathData::StructCtor, - REGULAR_SPACE); + REGULAR_SPACE, + i.span); } for (index, field) in struct_def.fields().iter().enumerate() { let name = field.ident.map(|ident| ident.name) .unwrap_or_else(|| Symbol::intern(&index.to_string())); - this.create_def(field.id, DefPathData::Field(name.as_str()), REGULAR_SPACE); + this.create_def(field.id, + DefPathData::Field(name.as_str()), + REGULAR_SPACE, + field.span); } } _ => {} @@ -168,14 +176,15 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { } fn visit_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId, _nested: bool) { - self.create_def(id, DefPathData::Misc, ITEM_LIKE_SPACE); + self.create_def(id, DefPathData::Misc, ITEM_LIKE_SPACE, use_tree.span); visit::walk_use_tree(self, use_tree, id); } fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) { let def = self.create_def(foreign_item.id, DefPathData::ValueNs(foreign_item.ident.name.as_str()), - REGULAR_SPACE); + REGULAR_SPACE, + foreign_item.span); self.with_parent(def, |this| { visit::walk_foreign_item(this, foreign_item); @@ -188,14 +197,16 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { self.create_def( lifetime_def.lifetime.id, DefPathData::LifetimeDef(lifetime_def.lifetime.ident.name.as_str()), - REGULAR_SPACE + REGULAR_SPACE, + lifetime_def.lifetime.span ); } GenericParam::Type(ref ty_param) => { self.create_def( ty_param.id, DefPathData::TypeParam(ty_param.ident.name.as_str()), - REGULAR_SPACE + REGULAR_SPACE, + ty_param.span ); } } @@ -211,7 +222,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { TraitItemKind::Macro(..) => return self.visit_macro_invoc(ti.id, false), }; - let def = self.create_def(ti.id, def_data, ITEM_LIKE_SPACE); + let def = self.create_def(ti.id, def_data, ITEM_LIKE_SPACE, ti.span); self.with_parent(def, |this| { if let TraitItemKind::Const(_, Some(ref expr)) = ti.node { this.visit_const_expr(expr); @@ -229,7 +240,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id, false), }; - let def = self.create_def(ii.id, def_data, ITEM_LIKE_SPACE); + let def = self.create_def(ii.id, def_data, ITEM_LIKE_SPACE, ii.span); self.with_parent(def, |this| { if let ImplItemKind::Const(_, ref expr) = ii.node { this.visit_const_expr(expr); @@ -255,7 +266,8 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { ExprKind::Closure(..) => { let def = self.create_def(expr.id, DefPathData::ClosureExpr, - REGULAR_SPACE); + REGULAR_SPACE, + expr.span); self.parent_def = Some(def); } _ => {} @@ -270,7 +282,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { TyKind::Mac(..) => return self.visit_macro_invoc(ty.id, false), TyKind::Array(_, ref length) => self.visit_const_expr(length), TyKind::ImplTrait(..) => { - self.create_def(ty.id, DefPathData::ImplTrait, REGULAR_SPACE); + self.create_def(ty.id, DefPathData::ImplTrait, REGULAR_SPACE, ty.span); } TyKind::Typeof(ref expr) => self.visit_const_expr(expr), _ => {} diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 61a58a60306..1a2840de447 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -28,6 +28,7 @@ use std::hash::Hash; use syntax::ast; use syntax::ext::hygiene::Mark; use syntax::symbol::{Symbol, InternedString}; +use syntax_pos::{Span, DUMMY_SP}; use util::nodemap::NodeMap; /// The DefPathTable maps DefIndexes to DefKeys and vice versa. @@ -159,6 +160,7 @@ pub struct Definitions { macro_def_scopes: FxHashMap<Mark, DefId>, expansions: FxHashMap<DefIndex, Mark>, next_disambiguator: FxHashMap<(DefIndex, DefPathData), u32>, + def_index_to_span: FxHashMap<DefIndex, Span>, } // Unfortunately we have to provide a manual impl of Clone because of the @@ -176,6 +178,7 @@ impl Clone for Definitions { macro_def_scopes: self.macro_def_scopes.clone(), expansions: self.expansions.clone(), next_disambiguator: self.next_disambiguator.clone(), + def_index_to_span: self.def_index_to_span.clone(), } } } @@ -410,6 +413,7 @@ impl Definitions { macro_def_scopes: FxHashMap(), expansions: FxHashMap(), next_disambiguator: FxHashMap(), + def_index_to_span: FxHashMap(), } } @@ -493,6 +497,22 @@ impl Definitions { self.node_to_hir_id[node_id] } + /// Retrieve the span of the given `DefId` if `DefId` is in the local crate, the span exists and + /// it's not DUMMY_SP + #[inline] + pub fn opt_span(&self, def_id: DefId) -> Option<Span> { + if def_id.krate == LOCAL_CRATE { + let span = self.def_index_to_span.get(&def_id.index).cloned().unwrap_or(DUMMY_SP); + if span != DUMMY_SP { + Some(span) + } else { + None + } + } else { + None + } + } + /// Add a definition with a parent definition. pub fn create_root_def(&mut self, crate_name: &str, @@ -530,7 +550,8 @@ impl Definitions { node_id: ast::NodeId, data: DefPathData, address_space: DefIndexAddressSpace, - expansion: Mark) + expansion: Mark, + span: Span) -> DefIndex { debug!("create_def_with_parent(parent={:?}, node_id={:?}, data={:?})", parent, node_id, data); @@ -583,6 +604,11 @@ impl Definitions { self.expansions.insert(index, expansion); } + // The span is added if it isn't DUMMY_SP + if span != DUMMY_SP { + self.def_index_to_span.insert(index, span); + } + index } @@ -692,7 +718,8 @@ macro_rules! define_global_metadata_kind { ast::DUMMY_NODE_ID, DefPathData::GlobalMetaData(instance.name().as_str()), GLOBAL_MD_ADDRESS_SPACE, - Mark::root() + Mark::root(), + DUMMY_SP ); // Make sure calling def_index does not crash.