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.