about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/hir/map/collector.rs3
-rw-r--r--src/librustc/hir/map/mod.rs239
-rw-r--r--src/librustc/hir/pat_util.rs10
-rw-r--r--src/librustc/infer/error_reporting.rs10
-rw-r--r--src/librustc/middle/cstore.rs5
-rw-r--r--src/librustc/ty/item_path.rs5
-rw-r--r--src/librustc/ty/mod.rs33
-rw-r--r--src/librustc_driver/pretty.rs19
-rw-r--r--src/librustc_lint/builtin.rs5
-rw-r--r--src/librustc_metadata/astencode.rs17
-rw-r--r--src/librustc_metadata/common.rs9
-rw-r--r--src/librustc_metadata/csearch.rs16
-rw-r--r--src/librustc_metadata/decoder.rs26
-rw-r--r--src/librustc_metadata/encoder.rs101
-rw-r--r--src/librustc_mir/graphviz.rs2
-rw-r--r--src/librustc_mir/pretty.rs2
-rw-r--r--src/librustc_save_analysis/dump_visitor.rs8
-rw-r--r--src/librustc_save_analysis/lib.rs12
-rw-r--r--src/librustc_trans/base.rs11
-rw-r--r--src/librustc_trans/debuginfo/namespace.rs140
-rw-r--r--src/librustc_trans/debuginfo/type_names.rs34
-rw-r--r--src/librustdoc/clean/inline.rs8
-rw-r--r--src/test/run-make/pretty-print-path-suffix/foo_method.pp2
23 files changed, 192 insertions, 525 deletions
diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs
index b1a084ac799..94fa393ae3d 100644
--- a/src/librustc/hir/map/collector.rs
+++ b/src/librustc/hir/map/collector.rs
@@ -14,6 +14,7 @@ use super::MapEntry::*;
 use hir::*;
 use hir::intravisit::Visitor;
 use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex};
+use middle::cstore::InlinedItem;
 use std::iter::repeat;
 use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID};
 use syntax::codemap::Span;
@@ -46,7 +47,7 @@ impl<'ast> NodeCollector<'ast> {
     }
 
     pub fn extend(krate: &'ast Crate,
-                  parent: &'ast InlinedParent,
+                  parent: &'ast InlinedItem,
                   parent_node: NodeId,
                   parent_def_path: DefPath,
                   parent_def_id: DefId,
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 4096606b001..e1b7afda58b 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 pub use self::Node::*;
-pub use self::PathElem::*;
 use self::MapEntry::*;
 use self::collector::NodeCollector;
 pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData,
@@ -25,7 +24,6 @@ use syntax::abi::Abi;
 use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID};
 use syntax::attr::ThinAttributesExt;
 use syntax::codemap::{Span, Spanned};
-use syntax::parse::token;
 
 use hir::*;
 use hir::fold::Folder;
@@ -33,85 +31,13 @@ use hir::print as pprust;
 
 use arena::TypedArena;
 use std::cell::RefCell;
-use std::fmt;
 use std::io;
-use std::iter;
 use std::mem;
-use std::slice;
 
 pub mod blocks;
 mod collector;
 pub mod definitions;
 
-#[derive(Clone, Copy, PartialEq, Debug)]
-pub enum PathElem {
-    PathMod(Name),
-    PathName(Name)
-}
-
-impl PathElem {
-    pub fn name(&self) -> Name {
-        match *self {
-            PathMod(name) | PathName(name) => name
-        }
-    }
-}
-
-impl fmt::Display for PathElem {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{}", self.name())
-    }
-}
-
-#[derive(Clone)]
-pub struct LinkedPathNode<'a> {
-    node: PathElem,
-    next: LinkedPath<'a>,
-}
-
-#[derive(Copy, Clone)]
-pub struct LinkedPath<'a>(Option<&'a LinkedPathNode<'a>>);
-
-impl<'a> LinkedPath<'a> {
-    pub fn empty() -> LinkedPath<'a> {
-        LinkedPath(None)
-    }
-
-    pub fn from(node: &'a LinkedPathNode) -> LinkedPath<'a> {
-        LinkedPath(Some(node))
-    }
-}
-
-impl<'a> Iterator for LinkedPath<'a> {
-    type Item = PathElem;
-
-    fn next(&mut self) -> Option<PathElem> {
-        match self.0 {
-            Some(node) => {
-                *self = node.next;
-                Some(node.node)
-            }
-            None => None
-        }
-    }
-}
-
-/// The type of the iterator used by with_path.
-pub type PathElems<'a, 'b> = iter::Chain<iter::Cloned<slice::Iter<'a, PathElem>>, LinkedPath<'b>>;
-
-pub fn path_to_string<PI: Iterator<Item=PathElem>>(path: PI) -> String {
-    let itr = token::get_ident_interner();
-
-    path.fold(String::new(), |mut s, e| {
-        let e = itr.get(e.name());
-        if !s.is_empty() {
-            s.push_str("::");
-        }
-        s.push_str(&e[..]);
-        s
-    })
-}
-
 #[derive(Copy, Clone, Debug)]
 pub enum Node<'ast> {
     NodeItem(&'ast Item),
@@ -156,7 +82,7 @@ pub enum MapEntry<'ast> {
 
     /// Roots for node trees.
     RootCrate,
-    RootInlinedParent(&'ast InlinedParent)
+    RootInlinedParent(&'ast InlinedItem)
 }
 
 impl<'ast> Clone for MapEntry<'ast> {
@@ -165,12 +91,6 @@ impl<'ast> Clone for MapEntry<'ast> {
     }
 }
 
-#[derive(Debug)]
-pub struct InlinedParent {
-    path: Vec<PathElem>,
-    ii: InlinedItem
-}
-
 impl<'ast> MapEntry<'ast> {
     fn from_node(p: NodeId, node: Node<'ast>) -> MapEntry<'ast> {
         match node {
@@ -233,7 +153,7 @@ impl<'ast> MapEntry<'ast> {
 pub struct Forest {
     krate: Crate,
     pub dep_graph: DepGraph,
-    inlined_items: TypedArena<InlinedParent>
+    inlined_items: TypedArena<InlinedItem>
 }
 
 impl Forest {
@@ -351,8 +271,10 @@ impl<'ast> Map<'ast> {
         self.definitions.borrow().def_key(def_id.index)
     }
 
-    pub fn def_path_from_id(&self, id: NodeId) -> DefPath {
-        self.def_path(self.local_def_id(id))
+    pub fn def_path_from_id(&self, id: NodeId) -> Option<DefPath> {
+        self.opt_local_def_id(id).map(|def_id| {
+            self.def_path(def_id)
+        })
     }
 
     pub fn def_path(&self, def_id: DefId) -> DefPath {
@@ -551,8 +473,8 @@ impl<'ast> Map<'ast> {
     pub fn get_parent_did(&self, id: NodeId) -> DefId {
         let parent = self.get_parent(id);
         match self.find_entry(parent) {
-            Some(RootInlinedParent(&InlinedParent {ii: II::TraitItem(did, _), ..})) => did,
-            Some(RootInlinedParent(&InlinedParent {ii: II::ImplItem(did, _), ..})) => did,
+            Some(RootInlinedParent(&II::TraitItem(did, _))) |
+            Some(RootInlinedParent(&II::ImplItem(did, _))) => did,
             _ => self.local_def_id(parent)
         }
     }
@@ -634,80 +556,21 @@ impl<'ast> Map<'ast> {
         }
     }
 
-    /// returns the name associated with the given NodeId's AST
-    pub fn get_path_elem(&self, id: NodeId) -> PathElem {
-        let node = self.get(id);
-        match node {
-            NodeItem(item) => {
-                match item.node {
-                    ItemMod(_) | ItemForeignMod(_) => {
-                        PathMod(item.name)
-                    }
-                    _ => PathName(item.name)
-                }
-            }
-            NodeForeignItem(i) => PathName(i.name),
-            NodeImplItem(ii) => PathName(ii.name),
-            NodeTraitItem(ti) => PathName(ti.name),
-            NodeVariant(v) => PathName(v.node.name),
-            NodeLifetime(lt) => PathName(lt.name),
-            NodeTyParam(tp) => PathName(tp.name),
+    /// Returns the name associated with the given NodeId's AST.
+    pub fn name(&self, id: NodeId) -> Name {
+        match self.get(id) {
+            NodeItem(i) => i.name,
+            NodeForeignItem(i) => i.name,
+            NodeImplItem(ii) => ii.name,
+            NodeTraitItem(ti) => ti.name,
+            NodeVariant(v) => v.node.name,
+            NodeLifetime(lt) => lt.name,
+            NodeTyParam(tp) => tp.name,
             NodeLocal(&Pat { node: PatKind::Ident(_,l,_), .. }) => {
-                PathName(l.node.name)
+                l.node.name
             },
-            _ => bug!("no path elem for {:?}", node)
-        }
-    }
-
-    pub fn with_path<T, F>(&self, id: NodeId, f: F) -> T where
-        F: FnOnce(PathElems) -> T,
-    {
-        self.with_path_next(id, LinkedPath::empty(), f)
-    }
-
-    pub fn path_to_string(&self, id: NodeId) -> String {
-        self.with_path(id, |path| path_to_string(path))
-    }
-
-    fn path_to_str_with_name(&self, id: NodeId, name: Name) -> String {
-        self.with_path(id, |path| {
-            path_to_string(path.chain(Some(PathName(name))))
-        })
-    }
-
-    fn with_path_next<T, F>(&self, id: NodeId, next: LinkedPath, f: F) -> T where
-        F: FnOnce(PathElems) -> T,
-    {
-        // This function reveals the name of the item and hence is a
-        // kind of read. This is inefficient, since it walks ancestors
-        // and we are walking them anyhow, but whatever.
-        self.read(id);
-
-        let parent = self.get_parent(id);
-        let parent = match self.find_entry(id) {
-            Some(EntryForeignItem(..)) => {
-                // Anonymous extern items go in the parent scope.
-                self.get_parent(parent)
-            }
-            // But tuple struct ctors don't have names, so use the path of its
-            // parent, the struct item. Similarly with closure expressions.
-            Some(EntryStructCtor(..)) | Some(EntryExpr(..)) => {
-                return self.with_path_next(parent, next, f);
-            }
-            _ => parent
-        };
-        if parent == id {
-            match self.find_entry(id) {
-                Some(RootInlinedParent(data)) => {
-                    f(data.path.iter().cloned().chain(next))
-                }
-                _ => f([].iter().cloned().chain(next))
-            }
-        } else {
-            self.with_path_next(parent, LinkedPath::from(&LinkedPathNode {
-                node: self.get_path_elem(id),
-                next: next
-            }), f)
+            NodeStructCtor(_) => self.name(self.get_parent(id)),
+            _ => bug!("no name for {}", self.node_to_string(id))
         }
     }
 
@@ -958,7 +821,6 @@ pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> {
 /// Used for items loaded from external crate that are being inlined into this
 /// crate.
 pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
-                                          parent_path: Vec<PathElem>,
                                           parent_def_path: DefPath,
                                           parent_def_id: DefId,
                                           ii: InlinedItem,
@@ -978,27 +840,24 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
         II::Foreign(i) => II::Foreign(i.map(|i| fld.fold_foreign_item(i)))
     };
 
-    let ii_parent = map.forest.inlined_items.alloc(InlinedParent {
-        path: parent_path,
-        ii: ii
-    });
+    let ii = map.forest.inlined_items.alloc(ii);
 
     let ii_parent_id = fld.new_id(DUMMY_NODE_ID);
     let mut collector =
         NodeCollector::extend(
             map.krate(),
-            ii_parent,
+            ii,
             ii_parent_id,
             parent_def_path,
             parent_def_id,
             mem::replace(&mut *map.map.borrow_mut(), vec![]),
             mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new()));
-    ii_parent.ii.visit(&mut collector);
+    ii.visit(&mut collector);
 
     *map.map.borrow_mut() = collector.map;
     *map.definitions.borrow_mut() = collector.definitions;
 
-    &ii_parent.ii
+    ii
 }
 
 pub trait NodePrinter {
@@ -1032,9 +891,24 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
     let id_str = format!(" (id={})", id);
     let id_str = if include_id { &id_str[..] } else { "" };
 
+    let path_str = || {
+        // This functionality is used for debugging, try to use TyCtxt to get
+        // the user-friendly path, otherwise fall back to stringifying DefPath.
+        ::ty::tls::with_opt(|tcx| {
+            if let Some(tcx) = tcx {
+                tcx.node_path_str(id)
+            } else if let Some(path) = map.def_path_from_id(id) {
+                path.data.into_iter().map(|elem| {
+                    elem.data.to_string()
+                }).collect::<Vec<_>>().join("::")
+            } else {
+                String::from("<missing path>")
+            }
+        })
+    };
+
     match map.find(id) {
         Some(NodeItem(item)) => {
-            let path_str = map.path_to_str_with_name(id, item.name);
             let item_str = match item.node {
                 ItemExternCrate(..) => "extern crate",
                 ItemUse(..) => "use",
@@ -1050,30 +924,21 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
                 ItemImpl(..) => "impl",
                 ItemDefaultImpl(..) => "default impl",
             };
-            format!("{} {}{}", item_str, path_str, id_str)
+            format!("{} {}{}", item_str, path_str(), id_str)
         }
-        Some(NodeForeignItem(item)) => {
-            let path_str = map.path_to_str_with_name(id, item.name);
-            format!("foreign item {}{}", path_str, id_str)
+        Some(NodeForeignItem(_)) => {
+            format!("foreign item {}{}", path_str(), id_str)
         }
         Some(NodeImplItem(ii)) => {
             match ii.node {
                 ImplItemKind::Const(..) => {
-                    format!("assoc const {} in {}{}",
-                            ii.name,
-                            map.path_to_string(id),
-                            id_str)
+                    format!("assoc const {} in {}{}", ii.name, path_str(), id_str)
                 }
                 ImplItemKind::Method(..) => {
-                    format!("method {} in {}{}",
-                            ii.name,
-                            map.path_to_string(id), id_str)
+                    format!("method {} in {}{}", ii.name, path_str(), id_str)
                 }
                 ImplItemKind::Type(_) => {
-                    format!("assoc type {} in {}{}",
-                            ii.name,
-                            map.path_to_string(id),
-                            id_str)
+                    format!("assoc type {} in {}{}", ii.name, path_str(), id_str)
                 }
             }
         }
@@ -1084,16 +949,12 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
                 TypeTraitItem(..) => "assoc type",
             };
 
-            format!("{} {} in {}{}",
-                    kind,
-                    ti.name,
-                    map.path_to_string(id),
-                    id_str)
+            format!("{} {} in {}{}", kind, ti.name, path_str(), id_str)
         }
         Some(NodeVariant(ref variant)) => {
             format!("variant {} in {}{}",
                     variant.node.name,
-                    map.path_to_string(id), id_str)
+                    path_str(), id_str)
         }
         Some(NodeExpr(ref expr)) => {
             format!("expr {}{}", pprust::expr_to_string(&expr), id_str)
@@ -1111,7 +972,7 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
             format!("block {}{}", pprust::block_to_string(&block), id_str)
         }
         Some(NodeStructCtor(_)) => {
-            format!("struct_ctor {}{}", map.path_to_string(id), id_str)
+            format!("struct_ctor {}{}", path_str(), id_str)
         }
         Some(NodeLifetime(ref l)) => {
             format!("lifetime {}{}",
diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs
index 5eb4d53ea6a..6cc5a29062f 100644
--- a/src/librustc/hir/pat_util.rs
+++ b/src/librustc/hir/pat_util.rs
@@ -210,14 +210,8 @@ pub fn simple_name<'a>(pat: &'a hir::Pat) -> Option<ast::Name> {
 }
 
 pub fn def_to_path(tcx: &TyCtxt, id: DefId) -> hir::Path {
-    tcx.with_path(id, |path| hir::Path {
-        global: false,
-        segments: path.last().map(|elem| hir::PathSegment {
-            identifier: hir::Ident::from_name(elem.name()),
-            parameters: hir::PathParameters::none(),
-        }).into_iter().collect(),
-        span: DUMMY_SP,
-    })
+    let name = tcx.item_name(id);
+    hir::Path::from_ident(DUMMY_SP, hir::Ident::from_name(name))
 }
 
 /// Return variants that are necessary to exist for the pattern to match.
diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs
index 5a0d9ec1332..a7553f4eb1f 100644
--- a/src/librustc/infer/error_reporting.rs
+++ b/src/librustc/infer/error_reporting.rs
@@ -587,13 +587,9 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
             // Only external crates, if either is from a local
             // module we could have false positives
             if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate {
-                let exp_path = self.tcx.with_path(did1,
-                                                  |p| p.map(|x| x.to_string())
-                                                       .collect::<Vec<_>>());
-                let found_path = self.tcx.with_path(did2,
-                                                    |p| p.map(|x| x.to_string())
-                                                         .collect::<Vec<_>>());
-                // We compare strings because PathMod and PathName can be different
+                let exp_path = self.tcx.item_path_str(did1);
+                let found_path = self.tcx.item_path_str(did2);
+                // We compare strings because DefPath can be different
                 // for imported and non-imported crates
                 if exp_path == found_path {
                     let crate_name = self.tcx.sess.cstore.crate_name(did1.krate);
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index 027792b7439..1f6328187a5 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -166,9 +166,7 @@ pub trait CrateStore<'tcx> : Any {
     fn repr_attrs(&self, def: DefId) -> Vec<attr::ReprAttr>;
     fn item_type(&self, tcx: &TyCtxt<'tcx>, def: DefId)
                  -> ty::TypeScheme<'tcx>;
-    fn relative_item_path(&self, def: DefId) -> Vec<hir_map::PathElem>;
     fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>>;
-    fn extern_item_path(&self, def: DefId) -> Vec<hir_map::PathElem>;
     fn item_name(&self, def: DefId) -> ast::Name;
     fn item_predicates(&self, tcx: &TyCtxt<'tcx>, def: DefId)
                        -> ty::GenericPredicates<'tcx>;
@@ -345,12 +343,9 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
     fn repr_attrs(&self, def: DefId) -> Vec<attr::ReprAttr> { bug!("repr_attrs") }
     fn item_type(&self, tcx: &TyCtxt<'tcx>, def: DefId)
                  -> ty::TypeScheme<'tcx> { bug!("item_type") }
-    fn relative_item_path(&self, def: DefId)
-                          -> Vec<hir_map::PathElem> { bug!("relative_item_path") }
     fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>> {
         bug!("visible_parent_map")
     }
-    fn extern_item_path(&self, def: DefId) -> Vec<hir_map::PathElem> { bug!("extern_item_path") }
     fn item_name(&self, def: DefId) -> ast::Name { bug!("item_name") }
     fn item_predicates(&self, tcx: &TyCtxt<'tcx>, def: DefId)
                        -> ty::GenericPredicates<'tcx> { bug!("item_predicates") }
diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs
index 4d88b697416..5c1e19aee7b 100644
--- a/src/librustc/ty/item_path.rs
+++ b/src/librustc/ty/item_path.rs
@@ -24,6 +24,11 @@ impl<'tcx> TyCtxt<'tcx> {
         buffer.into_string()
     }
 
+    /// Returns a string identifying this local node-id.
+    pub fn node_path_str(&self, id: ast::NodeId) -> String {
+        self.item_path_str(self.map.local_def_id(id))
+    }
+
     /// Returns a string identifying this def-id. This string is
     /// suitable for user output. It always begins with a crate identifier.
     pub fn absolute_item_path_str(&self, def_id: DefId) -> String {
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 4ff859f5a94..444fea0918f 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -20,7 +20,6 @@ pub use self::fold::TypeFoldable;
 
 use dep_graph::{self, DepNode};
 use hir::map as ast_map;
-use hir::map::LinkedPath;
 use middle;
 use middle::cstore::{self, CrateStore, LOCAL_CRATE};
 use hir::def::{self, Def, ExportMap};
@@ -2231,39 +2230,9 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    pub fn with_path<T, F>(&self, id: DefId, f: F) -> T where
-        F: FnOnce(ast_map::PathElems) -> T,
-    {
-        if let Some(id) = self.map.as_local_node_id(id) {
-            self.map.with_path(id, f)
-        } else {
-            let mut path: Vec<_>;
-            if let Some(extern_crate) = self.sess.cstore.extern_crate(id.krate) {
-                if !extern_crate.direct {
-                    // this comes from some crate that we don't have a direct
-                    // path to; we'll settle for just prepending the name of
-                    // the crate.
-                    path = self.sess.cstore.extern_item_path(id)
-                } else {
-                    // start with the path to the extern crate, then
-                    // add the relative path to the actual item
-                    fn collector(elems: ast_map::PathElems) -> Vec<ast_map::PathElem> {
-                        elems.collect()
-                    }
-                    path = self.with_path(extern_crate.def_id, collector);
-                    path.extend(self.sess.cstore.relative_item_path(id));
-                }
-            } else {
-                // if this was injected, just make a path with name of crate
-                path = self.sess.cstore.extern_item_path(id);
-            }
-            f(path.iter().cloned().chain(LinkedPath::empty()))
-        }
-    }
-
     pub fn item_name(&self, id: DefId) -> ast::Name {
         if let Some(id) = self.map.as_local_node_id(id) {
-            self.map.get_path_elem(id).name()
+            self.map.name(id)
         } else {
             self.sess.cstore.item_name(id)
         }
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index cda5595c102..cde5ba19859 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -256,6 +256,15 @@ trait HirPrinterSupport<'ast>: pprust_hir::PpAnn {
     /// (Rust does not yet support upcasting from a trait object to
     /// an object for one of its super-traits.)
     fn pp_ann<'a>(&'a self) -> &'a pprust_hir::PpAnn;
+
+    /// Computes an user-readable representation of a path, if possible.
+    fn node_path(&self, id: ast::NodeId) -> Option<String> {
+        self.ast_map().and_then(|map| map.def_path_from_id(id)).map(|path| {
+            path.data.into_iter().map(|elem| {
+                elem.data.to_string()
+            }).collect::<Vec<_>>().join("::")
+        })
+    }
 }
 
 struct NoAnn<'ast> {
@@ -452,6 +461,10 @@ impl<'b, 'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'b, 'tcx> {
     fn pp_ann<'a>(&'a self) -> &'a pprust_hir::PpAnn {
         self
     }
+
+    fn node_path(&self, id: ast::NodeId) -> Option<String> {
+        Some(self.tcx.node_path_str(id))
+    }
 }
 
 impl<'a, 'tcx> pprust_hir::PpAnn for TypedAnnotation<'a, 'tcx> {
@@ -794,7 +807,7 @@ pub fn pretty_print_input(sess: Session,
                                        |annotation, (out,uii), _| {
                 debug!("pretty printing source code {:?}", s);
                 let sess = annotation.sess();
-                let ast_map = annotation.ast_map().expect("--pretty missing ast_map");
+                let ast_map = annotation.ast_map().expect("--unpretty missing HIR map");
                 let mut pp_state =
                     pprust_hir::State::new_from_input(sess.codemap(),
                                                       sess.diagnostic(),
@@ -808,7 +821,9 @@ pub fn pretty_print_input(sess: Session,
                     let node = ast_map.get(node_id);
                     pp_state.print_node(&node)?;
                     pp::space(&mut pp_state.s)?;
-                    pp_state.synth_comment(ast_map.path_to_string(node_id))?;
+                    let path = annotation.node_path(node_id)
+                                         .expect("--unpretty missing node paths");
+                    pp_state.synth_comment(path)?;
                     pp::hardbreak(&mut pp_state.s)?;
                 }
                 pp::eof(&mut pp_state.s)
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index fe10ca87b75..5e3a47701eb 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -1087,10 +1087,7 @@ impl LateLintPass for MutableTransmutes {
                 ty::TyFnDef(_, _, ref bfty) if bfty.abi == RustIntrinsic => (),
                 _ => return false
             }
-            cx.tcx.with_path(def_id, |path| match path.last() {
-                Some(ref last) => last.name().as_str() == "transmute",
-                _ => false
-            })
+            cx.tcx.item_name(def_id).as_str() == "transmute"
         }
     }
 }
diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs
index 3becc93f8a4..6fd9f27f0fb 100644
--- a/src/librustc_metadata/astencode.rs
+++ b/src/librustc_metadata/astencode.rs
@@ -85,7 +85,7 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext,
         InlinedItemRef::ImplItem(_, ii) => ii.id,
     };
     debug!("> Encoding inlined item: {} ({:?})",
-           ecx.tcx.map.path_to_string(id),
+           ecx.tcx.node_path_str(id),
            rbml_w.writer.seek(SeekFrom::Current(0)));
 
     // Folding could be avoided with a smarter encoder.
@@ -99,7 +99,7 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext,
     rbml_w.end_tag();
 
     debug!("< Encoded inlined fn: {} ({:?})",
-           ecx.tcx.map.path_to_string(id),
+           ecx.tcx.node_path_str(id),
            rbml_w.writer.seek(SeekFrom::Current(0)));
 }
 
@@ -124,20 +124,12 @@ impl<'a, 'b, 'c, 'tcx> ast_map::FoldOps for &'a DecodeContext<'b, 'c, 'tcx> {
 /// ast-map.
 pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
                                  tcx: &TyCtxt<'tcx>,
-                                 parent_path: Vec<ast_map::PathElem>,
                                  parent_def_path: ast_map::DefPath,
                                  parent_did: DefId,
                                  ast_doc: rbml::Doc,
                                  orig_did: DefId)
                                  -> &'tcx InlinedItem {
-    let mut path_as_str = None;
-    debug!("> Decoding inlined fn: {:?}::?",
-    {
-        // Do an Option dance to use the path after it is moved below.
-        let s = ast_map::path_to_string(parent_path.iter().cloned());
-        path_as_str = Some(s);
-        path_as_str.as_ref().map(|x| &x[..])
-    });
+    debug!("> Decoding inlined fn: {:?}", tcx.item_path_str(orig_did));
     let mut ast_dsr = reader::Decoder::new(ast_doc);
     let from_id_range = Decodable::decode(&mut ast_dsr).unwrap();
     let to_id_range = reserve_id_range(&tcx.sess, from_id_range);
@@ -149,7 +141,6 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
         last_filemap_index: Cell::new(0)
     };
     let ii = ast_map::map_decoded_item(&dcx.tcx.map,
-                                       parent_path,
                                        parent_def_path,
                                        parent_did,
                                        decode_ast(ast_doc),
@@ -162,7 +153,7 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
     };
     debug!("Fn named: {}", name);
     debug!("< Decoded inlined fn: {}::{}",
-            path_as_str.unwrap(),
+            tcx.item_path_str(parent_did),
             name);
     region::resolve_inlined_item(&tcx.sess, &tcx.region_maps, ii);
     decode_side_tables(dcx, ast_doc);
diff --git a/src/librustc_metadata/common.rs b/src/librustc_metadata/common.rs
index 22a5289f02b..ea4e2575420 100644
--- a/src/librustc_metadata/common.rs
+++ b/src/librustc_metadata/common.rs
@@ -86,13 +86,10 @@ pub const tag_item_trait_ref: usize = 0x3b;
 // discriminator value for variants
 pub const tag_disr_val: usize = 0x3c;
 
-// used to encode ast_map::PathElem
-pub const tag_path: usize = 0x3d;
-pub const tag_path_len: usize = 0x3e;
-pub const tag_path_elem_mod: usize = 0x3f;
-pub const tag_path_elem_name: usize = 0x40;
-pub const tag_item_field: usize = 0x41;
+// GAP 0x3d, 0x3e, 0x3f, 0x40
 
+pub const tag_item_field: usize = 0x41;
+// GAP 0x42
 pub const tag_item_variances: usize = 0x43;
 /*
   trait items contain tag_item_trait_item elements,
diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs
index bb691cebccd..0b90ad5b4e2 100644
--- a/src/librustc_metadata/csearch.rs
+++ b/src/librustc_metadata/csearch.rs
@@ -128,22 +128,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
         decoder::get_method_arg_names(&cdata, did.index)
     }
 
-    fn relative_item_path(&self, def: DefId) -> Vec<hir_map::PathElem> {
-        let cdata = self.get_crate_data(def.krate);
-        decoder::get_item_path(&cdata, def.index)
-    }
-
-    fn extern_item_path(&self, def: DefId) -> Vec<hir_map::PathElem> {
-        let cdata = self.get_crate_data(def.krate);
-        let path = decoder::get_item_path(&cdata, def.index);
-
-        let mut r = Vec::with_capacity(path.len() + 1);
-        let crate_name = hir_map::PathMod(token::intern(&cdata.name));
-        r.push(crate_name);
-        r.extend_from_slice(&path);
-        r
-    }
-
     fn item_name(&self, def: DefId) -> ast::Name {
         let cdata = self.get_crate_data(def.krate);
         decoder::get_item_name(&self.intr, &cdata, def.index)
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index e6f538255ac..6b53edbbff1 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -255,22 +255,6 @@ fn item_trait_ref<'tcx>(doc: rbml::Doc, tcx: &TyCtxt<'tcx>, cdata: Cmd)
     doc_trait_ref(tp, tcx, cdata)
 }
 
-fn item_path(item_doc: rbml::Doc) -> Vec<hir_map::PathElem> {
-    let path_doc = reader::get_doc(item_doc, tag_path);
-    reader::docs(path_doc).filter_map(|(tag, elt_doc)| {
-        if tag == tag_path_elem_mod {
-            let s = elt_doc.as_str_slice();
-            Some(hir_map::PathMod(token::intern(s)))
-        } else if tag == tag_path_elem_name {
-            let s = elt_doc.as_str_slice();
-            Some(hir_map::PathName(token::intern(s)))
-        } else {
-            // ignore tag_path_len element
-            None
-        }
-    }).collect()
-}
-
 fn item_name(intr: &IdentInterner, item: rbml::Doc) -> ast::Name {
     let name = reader::get_doc(item, tag_paths_data_name);
     let string = name.as_str_slice();
@@ -786,10 +770,6 @@ pub fn each_top_level_item_of_crate<F, G>(intr: Rc<IdentInterner>,
                                 callback)
 }
 
-pub fn get_item_path(cdata: Cmd, id: DefIndex) -> Vec<hir_map::PathElem> {
-    item_path(cdata.lookup_item(id))
-}
-
 pub fn get_item_name(intr: &IdentInterner, cdata: Cmd, id: DefIndex) -> ast::Name {
     item_name(intr, cdata.lookup_item(id))
 }
@@ -803,14 +783,11 @@ pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &TyCtxt<'tcx>, id: DefIndex)
         krate: cdata.cnum,
         index: def_key(cdata, id).parent.unwrap()
     };
-    let mut parent_path = item_path(item_doc);
-    parent_path.pop();
     let mut parent_def_path = def_path(cdata, id);
     parent_def_path.data.pop();
     if let Some(ast_doc) = reader::maybe_get_doc(item_doc, tag_ast as usize) {
         let ii = decode_inlined_item(cdata,
                                      tcx,
-                                     parent_path,
                                      parent_def_path,
                                      parent_def_id,
                                      ast_doc,
@@ -823,15 +800,12 @@ pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &TyCtxt<'tcx>, id: DefIndex)
             krate: cdata.cnum,
             index: def_key(cdata, parent_def_id.index).parent.unwrap()
         };
-        let mut grandparent_path = parent_path;
-        grandparent_path.pop();
         let mut grandparent_def_path = parent_def_path;
         grandparent_def_path.data.pop();
         let parent_doc = cdata.lookup_item(parent_did.index);
         if let Some(ast_doc) = reader::maybe_get_doc(parent_doc, tag_ast as usize) {
             let ii = decode_inlined_item(cdata,
                                          tcx,
-                                         grandparent_path,
                                          grandparent_def_path,
                                          grandparent_def_id,
                                          ast_doc,
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 83ffd8afbeb..d45650159e3 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -31,8 +31,6 @@ use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::util::IntTypeExt;
 
 use rustc::hir::svh::Svh;
-use rustc::hir::map::{LinkedPath, PathElem, PathElems};
-use rustc::hir::map as ast_map;
 use rustc::mir::mir_map::MirMap;
 use rustc::session::config;
 use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet};
@@ -300,26 +298,11 @@ fn encode_enum_variant_info<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
         }
         encode_bounds_and_type_for_item(rbml_w, ecx, index, variant_node_id);
 
-        ecx.tcx.map.with_path(variant_node_id, |path| encode_path(rbml_w, path));
         rbml_w.end_tag();
         disr_val = disr_val.wrap_incr();
     }
 }
 
-fn encode_path<PI: Iterator<Item=PathElem>>(rbml_w: &mut Encoder, path: PI) {
-    let path = path.collect::<Vec<_>>();
-    rbml_w.start_tag(tag_path);
-    rbml_w.wr_tagged_u32(tag_path_len, path.len() as u32);
-    for pe in &path {
-        let tag = match *pe {
-            ast_map::PathMod(_) => tag_path_elem_mod,
-            ast_map::PathName(_) => tag_path_elem_name
-        };
-        rbml_w.wr_tagged_str(tag, &pe.name().as_str());
-    }
-    rbml_w.end_tag();
-}
-
 /// Iterates through "auxiliary node IDs", which are node IDs that describe
 /// top-level items that are sub-items of the given item. Specifically:
 ///
@@ -371,7 +354,6 @@ fn encode_info_for_mod(ecx: &EncodeContext,
                        md: &hir::Mod,
                        attrs: &[ast::Attribute],
                        id: NodeId,
-                       path: PathElems,
                        name: Name,
                        vis: hir::Visibility) {
     rbml_w.start_tag(tag_items_data_item);
@@ -393,7 +375,6 @@ fn encode_info_for_mod(ecx: &EncodeContext,
         });
     }
 
-    encode_path(rbml_w, path.clone());
     encode_visibility(rbml_w, vis);
 
     let stab = stability::lookup_stability(ecx.tcx, ecx.tcx.map.local_def_id(id));
@@ -521,7 +502,6 @@ fn encode_info_for_struct_ctor<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
     });
     encode_bounds_and_type_for_item(rbml_w, ecx, index, ctor_id);
     encode_name(rbml_w, name);
-    ecx.tcx.map.with_path(ctor_id, |path| encode_path(rbml_w, path));
     encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(struct_id));
 
     if ecx.item_symbols.borrow().contains_key(&ctor_id) {
@@ -637,7 +617,6 @@ fn encode_info_for_associated_const<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                                               rbml_w: &mut Encoder,
                                               index: &mut CrateIndex<'tcx>,
                                               associated_const: &ty::AssociatedConst,
-                                              impl_path: PathElems,
                                               parent_id: NodeId,
                                               impl_item_opt: Option<&hir::ImplItem>) {
     debug!("encode_info_for_associated_const({:?},{:?})",
@@ -663,9 +642,6 @@ fn encode_info_for_associated_const<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
     encode_stability(rbml_w, stab);
     encode_deprecation(rbml_w, depr);
 
-    let elem = ast_map::PathName(associated_const.name);
-    encode_path(rbml_w, impl_path.chain(Some(elem)));
-
     if let Some(ii) = impl_item_opt {
         encode_attributes(rbml_w, &ii.attrs);
         encode_defaultness(rbml_w, ii.defaultness);
@@ -683,7 +659,6 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                                     rbml_w: &mut Encoder,
                                     index: &mut CrateIndex<'tcx>,
                                     m: &ty::Method<'tcx>,
-                                    impl_path: PathElems,
                                     is_default_impl: bool,
                                     parent_id: NodeId,
                                     impl_item_opt: Option<&hir::ImplItem>) {
@@ -705,8 +680,6 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
     let m_node_id = ecx.local_id(m.def_id);
     encode_bounds_and_type_for_item(rbml_w, ecx, index, m_node_id);
 
-    let elem = ast_map::PathName(m.name);
-    encode_path(rbml_w, impl_path.chain(Some(elem)));
     if let Some(impl_item) = impl_item_opt {
         if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node {
             encode_attributes(rbml_w, &impl_item.attrs);
@@ -738,7 +711,6 @@ fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                                              rbml_w: &mut Encoder,
                                              index: &mut CrateIndex<'tcx>,
                                              associated_type: &ty::AssociatedType<'tcx>,
-                                             impl_path: PathElems,
                                              parent_id: NodeId,
                                              impl_item_opt: Option<&hir::ImplItem>) {
     debug!("encode_info_for_associated_type({:?},{:?})",
@@ -760,9 +732,6 @@ fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
     encode_stability(rbml_w, stab);
     encode_deprecation(rbml_w, depr);
 
-    let elem = ast_map::PathName(associated_type.name);
-    encode_path(rbml_w, impl_path.chain(Some(elem)));
-
     if let Some(ii) = impl_item_opt {
         encode_attributes(rbml_w, &ii.attrs);
         encode_defaultness(rbml_w, ii.defaultness);
@@ -886,14 +855,13 @@ fn encode_xrefs<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
 fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                                   rbml_w: &mut Encoder,
                                   item: &hir::Item,
-                                  index: &mut CrateIndex<'tcx>,
-                                  path: PathElems,
-                                  vis: hir::Visibility) {
+                                  index: &mut CrateIndex<'tcx>) {
     let tcx = ecx.tcx;
 
     debug!("encoding info for item at {}",
            tcx.sess.codemap().span_to_string(item.span));
 
+    let vis = item.vis;
     let def_id = ecx.tcx.map.local_def_id(item.id);
     let stab = stability::lookup_stability(tcx, ecx.tcx.map.local_def_id(item.id));
     let depr = stability::lookup_deprecation(tcx, ecx.tcx.map.local_def_id(item.id));
@@ -911,7 +879,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
         encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id);
         encode_symbol(ecx, rbml_w, item.id);
         encode_name(rbml_w, item.name);
-        encode_path(rbml_w, path);
         encode_visibility(rbml_w, vis);
         encode_stability(rbml_w, stab);
         encode_deprecation(rbml_w, depr);
@@ -925,7 +892,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
         encode_family(rbml_w, 'C');
         encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id);
         encode_name(rbml_w, item.name);
-        encode_path(rbml_w, path);
         encode_attributes(rbml_w, &item.attrs);
         encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item));
         encode_mir(ecx, rbml_w, item.id);
@@ -942,7 +908,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
         let tps_len = generics.ty_params.len();
         encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id);
         encode_name(rbml_w, item.name);
-        encode_path(rbml_w, path);
         encode_attributes(rbml_w, &item.attrs);
         let needs_inline = tps_len > 0 || attr::requests_inline(&item.attrs);
         if needs_inline || constness == hir::Constness::Const {
@@ -966,7 +931,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                             m,
                             &item.attrs,
                             item.id,
-                            path,
                             item.name,
                             item.vis);
       }
@@ -976,7 +940,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
         encode_def_id_and_key(ecx, rbml_w, def_id);
         encode_family(rbml_w, 'n');
         encode_name(rbml_w, item.name);
-        encode_path(rbml_w, path);
 
         // Encode all the items in this module.
         for foreign_item in &fm.items {
@@ -995,7 +958,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
         encode_family(rbml_w, 'y');
         encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id);
         encode_name(rbml_w, item.name);
-        encode_path(rbml_w, path);
         encode_visibility(rbml_w, vis);
         encode_stability(rbml_w, stab);
         encode_deprecation(rbml_w, depr);
@@ -1017,7 +979,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
         }
         encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item));
         encode_mir(ecx, rbml_w, item.id);
-        encode_path(rbml_w, path);
 
         // Encode inherent implementations for this enumeration.
         encode_inherent_implementations(ecx, rbml_w, def_id);
@@ -1053,7 +1014,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
         encode_item_variances(rbml_w, ecx, item.id);
         encode_name(rbml_w, item.name);
         encode_attributes(rbml_w, &item.attrs);
-        encode_path(rbml_w, path.clone());
         encode_stability(rbml_w, stab);
         encode_deprecation(rbml_w, depr);
         encode_visibility(rbml_w, vis);
@@ -1156,7 +1116,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                 });
             encode_parent_impl(rbml_w, parent);
         }
-        encode_path(rbml_w, path.clone());
         encode_stability(rbml_w, stab);
         encode_deprecation(rbml_w, depr);
         rbml_w.end_tag();
@@ -1179,7 +1138,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                                                      rbml_w,
                                                      index,
                                                      &associated_const,
-                                                     path.clone(),
                                                      item.id,
                                                      ast_item)
                 }
@@ -1188,7 +1146,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                                            rbml_w,
                                            index,
                                            &method_type,
-                                           path.clone(),
                                            false,
                                            item.id,
                                            ast_item)
@@ -1198,7 +1155,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                                                     rbml_w,
                                                     index,
                                                     &associated_type,
-                                                    path.clone(),
                                                     item.id,
                                                     ast_item)
                 }
@@ -1250,7 +1206,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
             rbml_w.wr_tagged_u64(tag_mod_child,
                                  def_to_u64(method_def_id.def_id()));
         }
-        encode_path(rbml_w, path.clone());
 
         // Encode inherent implementations for this trait.
         encode_inherent_implementations(ecx, rbml_w, def_id);
@@ -1281,10 +1236,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                     encode_def_id_and_key(ecx, rbml_w, associated_const.def_id);
                     encode_visibility(rbml_w, associated_const.vis);
 
-                    let elem = ast_map::PathName(associated_const.name);
-                    encode_path(rbml_w,
-                                path.clone().chain(Some(elem)));
-
                     encode_family(rbml_w, 'C');
 
                     encode_bounds_and_type_for_item(rbml_w, ecx, index,
@@ -1297,10 +1248,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
 
                     encode_method_ty_fields(ecx, rbml_w, index, &method_ty);
 
-                    let elem = ast_map::PathName(method_ty.name);
-                    encode_path(rbml_w,
-                                path.clone().chain(Some(elem)));
-
                     match method_ty.explicit_self {
                         ty::ExplicitSelfCategory::Static => {
                             encode_family(rbml_w,
@@ -1320,11 +1267,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                 ty::TypeTraitItem(associated_type) => {
                     encode_name(rbml_w, associated_type.name);
                     encode_def_id_and_key(ecx, rbml_w, associated_type.def_id);
-
-                    let elem = ast_map::PathName(associated_type.name);
-                    encode_path(rbml_w,
-                                path.clone().chain(Some(elem)));
-
                     encode_item_sort(rbml_w, 't');
                     encode_family(rbml_w, 'y');
 
@@ -1386,10 +1328,10 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
 fn encode_info_for_foreign_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                                           rbml_w: &mut Encoder,
                                           nitem: &hir::ForeignItem,
-                                          index: &mut CrateIndex<'tcx>,
-                                          path: PathElems,
-                                          abi: Abi) {
+                                          index: &mut CrateIndex<'tcx>) {
+    debug!("writing foreign item {}", ecx.tcx.node_path_str(nitem.id));
     let def_id = ecx.tcx.map.local_def_id(nitem.id);
+    let abi = ecx.tcx.map.get_foreign_abi(nitem.id);
 
     index.record(def_id, rbml_w);
     rbml_w.start_tag(tag_items_data_item);
@@ -1429,7 +1371,6 @@ fn encode_info_for_foreign_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
         encode_name(rbml_w, nitem.name);
       }
     }
-    encode_path(rbml_w, path);
     rbml_w.end_tag();
 }
 
@@ -1454,8 +1395,6 @@ fn my_visit_expr(expr: &hir::Expr,
             ecx.tcx.closure_kind(def_id).encode(rbml_w).unwrap();
             rbml_w.end_tag();
 
-            ecx.tcx.map.with_path(expr.id, |path| encode_path(rbml_w, path));
-
             assert!(ecx.mir_map.map.contains_key(&expr.id));
             encode_mir(ecx, rbml_w, expr.id);
 
@@ -1465,31 +1404,6 @@ fn my_visit_expr(expr: &hir::Expr,
     }
 }
 
-fn my_visit_item<'a, 'tcx>(i: &hir::Item,
-                           rbml_w: &mut Encoder,
-                           ecx: &EncodeContext<'a, 'tcx>,
-                           index: &mut CrateIndex<'tcx>) {
-    ecx.tcx.map.with_path(i.id, |path| {
-        encode_info_for_item(ecx, rbml_w, i, index, path, i.vis);
-    });
-}
-
-fn my_visit_foreign_item<'a, 'tcx>(ni: &hir::ForeignItem,
-                                   rbml_w: &mut Encoder,
-                                   ecx: &EncodeContext<'a, 'tcx>,
-                                   index: &mut CrateIndex<'tcx>) {
-    debug!("writing foreign item {}::{}",
-            ecx.tcx.map.path_to_string(ni.id),
-            ni.name);
-
-    let abi = ecx.tcx.map.get_foreign_abi(ni.id);
-    ecx.tcx.map.with_path(ni.id, |path| {
-        encode_info_for_foreign_item(ecx, rbml_w,
-                                     ni, index,
-                                     path, abi);
-    });
-}
-
 struct EncodeVisitor<'a, 'b:'a, 'c:'a, 'tcx:'c> {
     rbml_w_for_visit_item: &'a mut Encoder<'b>,
     ecx: &'a EncodeContext<'c,'tcx>,
@@ -1503,11 +1417,11 @@ impl<'a, 'b, 'c, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'c, 'tcx> {
     }
     fn visit_item(&mut self, i: &'tcx hir::Item) {
         intravisit::walk_item(self, i);
-        my_visit_item(i, self.rbml_w_for_visit_item, self.ecx, self.index);
+        encode_info_for_item(self.ecx, self.rbml_w_for_visit_item, i, self.index);
     }
     fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem) {
         intravisit::walk_foreign_item(self, ni);
-        my_visit_foreign_item(ni, self.rbml_w_for_visit_item, self.ecx, self.index);
+        encode_info_for_foreign_item(self.ecx, self.rbml_w_for_visit_item, ni, self.index);
     }
 }
 
@@ -1528,7 +1442,6 @@ fn encode_info_for_items<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                         &krate.module,
                         &[],
                         CRATE_NODE_ID,
-                        [].iter().cloned().chain(LinkedPath::empty()),
                         syntax::parse::token::intern(&ecx.link_meta.crate_name),
                         hir::Public);
 
diff --git a/src/librustc_mir/graphviz.rs b/src/librustc_mir/graphviz.rs
index 959b1fdef52..069bd7826bc 100644
--- a/src/librustc_mir/graphviz.rs
+++ b/src/librustc_mir/graphviz.rs
@@ -118,7 +118,7 @@ fn write_edges<W: Write>(source: BasicBlock, mir: &Mir, w: &mut W) -> io::Result
 /// all the variables and temporaries.
 fn write_graph_label<W: Write>(tcx: &ty::TyCtxt, nid: NodeId, mir: &Mir, w: &mut W)
 -> io::Result<()> {
-    write!(w, "    label=<fn {}(", dot::escape_html(&tcx.map.path_to_string(nid)))?;
+    write!(w, "    label=<fn {}(", dot::escape_html(&tcx.node_path_str(nid)))?;
 
     // fn argument types.
     for (i, arg) in mir.arg_decls.iter().enumerate() {
diff --git a/src/librustc_mir/pretty.rs b/src/librustc_mir/pretty.rs
index 2c50697c37f..d0c66b340d9 100644
--- a/src/librustc_mir/pretty.rs
+++ b/src/librustc_mir/pretty.rs
@@ -216,7 +216,7 @@ fn write_scope_tree(tcx: &TyCtxt,
 /// local variables (both user-defined bindings and compiler temporaries).
 fn write_mir_intro(tcx: &TyCtxt, nid: NodeId, mir: &Mir, w: &mut Write)
                    -> io::Result<()> {
-    write!(w, "fn {}(", tcx.map.path_to_string(nid))?;
+    write!(w, "fn {}(", tcx.node_path_str(nid))?;
 
     // fn argument types.
     for (i, arg) in mir.arg_decls.iter().enumerate() {
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index c724091a2ec..da0e8ba78cf 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -519,7 +519,7 @@ where D: Dump
                      span: Span,
                      typ: &ast::Ty,
                      expr: &ast::Expr) {
-        let qualname = format!("::{}", self.tcx.map.path_to_string(id));
+        let qualname = format!("::{}", self.tcx.node_path_str(id));
 
         let sub_span = self.span.sub_span_after_keyword(span, keywords::Const);
 
@@ -544,7 +544,7 @@ where D: Dump
                       item: &ast::Item,
                       def: &ast::VariantData,
                       ty_params: &ast::Generics) {
-        let qualname = format!("::{}", self.tcx.map.path_to_string(item.id));
+        let qualname = format!("::{}", self.tcx.node_path_str(item.id));
 
         let val = self.span.snippet(item.span);
         let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Struct);
@@ -677,7 +677,7 @@ where D: Dump
                      generics: &ast::Generics,
                      trait_refs: &ast::TyParamBounds,
                      methods: &[ast::TraitItem]) {
-        let qualname = format!("::{}", self.tcx.map.path_to_string(item.id));
+        let qualname = format!("::{}", self.tcx.node_path_str(item.id));
         let val = self.span.snippet(item.span);
         let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Trait);
         if !self.span.filter_generated(sub_span, item.span) {
@@ -1108,7 +1108,7 @@ impl<'l, 'tcx, 'v, D: Dump + 'l> Visitor<'v> for DumpVisitor<'l, 'tcx, D> {
                 self.nest(item.id, |v| visit::walk_mod(v, m));
             }
             Ty(ref ty, ref ty_params) => {
-                let qualname = format!("::{}", self.tcx.map.path_to_string(item.id));
+                let qualname = format!("::{}", self.tcx.node_path_str(item.id));
                 let value = ty_to_string(&ty);
                 let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Type);
                 if !self.span.filter_generated(sub_span, item.span) {
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 98c0be1c93c..da4c8770b7e 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -116,7 +116,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
     pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
         match item.node {
             ast::ItemKind::Fn(..) => {
-                let name = self.tcx.map.path_to_string(item.id);
+                let name = self.tcx.node_path_str(item.id);
                 let qualname = format!("::{}", name);
                 let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Fn);
                 filter!(self.span_utils, sub_span, item.span, None);
@@ -130,7 +130,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                 }))
             }
             ast::ItemKind::Static(ref typ, mt, ref expr) => {
-                let qualname = format!("::{}", self.tcx.map.path_to_string(item.id));
+                let qualname = format!("::{}", self.tcx.node_path_str(item.id));
 
                 // If the variable is immutable, save the initialising expression.
                 let (value, keyword) = match mt {
@@ -153,7 +153,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                 }))
             }
             ast::ItemKind::Const(ref typ, ref expr) => {
-                let qualname = format!("::{}", self.tcx.map.path_to_string(item.id));
+                let qualname = format!("::{}", self.tcx.node_path_str(item.id));
                 let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Const);
                 filter!(self.span_utils, sub_span, item.span, None);
                 Some(Data::VariableData(VariableData {
@@ -167,7 +167,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                 }))
             }
             ast::ItemKind::Mod(ref m) => {
-                let qualname = format!("::{}", self.tcx.map.path_to_string(item.id));
+                let qualname = format!("::{}", self.tcx.node_path_str(item.id));
 
                 let cm = self.tcx.sess.codemap();
                 let filename = cm.span_to_filename(m.inner);
@@ -184,7 +184,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                 }))
             }
             ast::ItemKind::Enum(..) => {
-                let enum_name = format!("::{}", self.tcx.map.path_to_string(item.id));
+                let enum_name = format!("::{}", self.tcx.node_path_str(item.id));
                 let val = self.span_utils.snippet(item.span);
                 let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Enum);
                 filter!(self.span_utils, sub_span, item.span, None);
@@ -246,7 +246,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                           scope: NodeId) -> Option<VariableData> {
         match field.node.kind {
             ast::NamedField(ident, _) => {
-                let qualname = format!("::{}::{}", self.tcx.map.path_to_string(scope), ident);
+                let qualname = format!("::{}::{}", self.tcx.node_path_str(scope), ident);
                 let typ = self.tcx.node_types().get(&field.node.id).unwrap().to_string();
                 let sub_span = self.span_utils.sub_span_before_token(field.span, token::Colon);
                 filter!(self.span_utils, sub_span, field.span, None);
diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs
index 4f1585eeaca..c8ed4e629e4 100644
--- a/src/librustc_trans/base.rs
+++ b/src/librustc_trans/base.rs
@@ -1351,7 +1351,7 @@ fn build_cfg(tcx: &TyCtxt, id: ast::NodeId) -> (ast::NodeId, Option<cfg::CFG>) {
         None if id == ast::DUMMY_NODE_ID => return (ast::DUMMY_NODE_ID, None),
 
         _ => bug!("unexpected variant in has_nested_returns: {}",
-                  tcx.map.path_to_string(id)),
+                  tcx.node_path_str(id)),
     };
 
     (blk.id, Some(cfg::CFG::new(tcx, blk)))
@@ -1412,9 +1412,7 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
         let local_id = def_id.and_then(|id| ccx.tcx().map.as_local_node_id(id));
 
         debug!("FunctionContext::new(path={}, def_id={:?}, param_substs={:?})",
-            inlined_id.map_or(String::new(), |id| {
-                ccx.tcx().map.path_to_string(id).to_string()
-            }),
+            inlined_id.map_or(String::new(), |id| ccx.tcx().node_path_str(id)),
             def_id,
             param_substs);
 
@@ -1906,7 +1904,7 @@ pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                           llfndecl: ValueRef,
                           param_substs: &'tcx Substs<'tcx>,
                           id: ast::NodeId) {
-    let _s = StatRecorder::new(ccx, ccx.tcx().map.path_to_string(id).to_string());
+    let _s = StatRecorder::new(ccx, ccx.tcx().node_path_str(id));
     debug!("trans_fn(param_substs={:?})", param_substs);
     let _icx = push_ctxt("trans_fn");
     let fn_ty = ccx.tcx().node_id_to_type(id);
@@ -2446,8 +2444,7 @@ pub fn exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         _ => {
             if attr::contains_name(attrs, "no_mangle") {
                 // Don't mangle
-                let path = ccx.tcx().map.def_path_from_id(id);
-                path.data.last().unwrap().data.to_string()
+                ccx.tcx().map.name(id).as_str().to_string()
             } else {
                 match weak_lang_items::link_name(attrs) {
                     Some(name) => name.to_string(),
diff --git a/src/librustc_trans/debuginfo/namespace.rs b/src/librustc_trans/debuginfo/namespace.rs
index c1487f56956..5272a4fbbb7 100644
--- a/src/librustc_trans/debuginfo/namespace.rs
+++ b/src/librustc_trans/debuginfo/namespace.rs
@@ -19,6 +19,7 @@ use rustc::hir::map as hir_map;
 use common::CrateContext;
 
 use std::ffi::CString;
+use std::iter::once;
 use std::ptr;
 use std::rc::{Rc, Weak};
 use syntax::ast;
@@ -51,85 +52,76 @@ impl NamespaceTreeNode {
     }
 }
 
-pub fn crate_root_namespace<'a>(cx: &'a CrateContext) -> &'a str {
-    &cx.link_meta().crate_name
-}
-
 pub fn namespace_for_item(cx: &CrateContext, def_id: DefId) -> Rc<NamespaceTreeNode> {
-    cx.tcx().with_path(def_id, |path| {
-        // prepend crate name if not already present
-        let krate = if def_id.is_local() {
-            let crate_namespace_name = token::intern(crate_root_namespace(cx));
-            Some(hir_map::PathMod(crate_namespace_name))
-        } else {
-            None
+    // prepend crate name.
+    // This shouldn't need a roundtrip through InternedString.
+    let krate = token::intern(&cx.tcx().crate_name(def_id.krate));
+    let krate = hir_map::DefPathData::TypeNs(krate);
+    let path = cx.tcx().def_path(def_id).data;
+    let mut path = once(krate).chain(path.into_iter().map(|e| e.data)).peekable();
+
+    let mut current_key = Vec::new();
+    let mut parent_node: Option<Rc<NamespaceTreeNode>> = None;
+
+    // Create/Lookup namespace for each element of the path.
+    loop {
+        // Emulate a for loop so we can use peek below.
+        let path_element = match path.next() {
+            Some(e) => e,
+            None => break
         };
-        let mut path = krate.into_iter().chain(path).peekable();
-
-        let mut current_key = Vec::new();
-        let mut parent_node: Option<Rc<NamespaceTreeNode>> = None;
-
-        // Create/Lookup namespace for each element of the path.
-        loop {
-            // Emulate a for loop so we can use peek below.
-            let path_element = match path.next() {
-                Some(e) => e,
-                None => break
-            };
-            // Ignore the name of the item (the last path element).
-            if path.peek().is_none() {
-                break;
-            }
-
-            let name = path_element.name();
-            current_key.push(name);
-
-            let existing_node = debug_context(cx).namespace_map.borrow()
-                                                 .get(&current_key).cloned();
-            let current_node = match existing_node {
-                Some(existing_node) => existing_node,
-                None => {
-                    // create and insert
-                    let parent_scope = match parent_node {
-                        Some(ref node) => node.scope,
-                        None => ptr::null_mut()
-                    };
-                    let namespace_name = name.as_str();
-                    let namespace_name = CString::new(namespace_name.as_bytes()).unwrap();
-                    let scope = unsafe {
-                        llvm::LLVMDIBuilderCreateNameSpace(
-                            DIB(cx),
-                            parent_scope,
-                            namespace_name.as_ptr(),
-                            // cannot reconstruct file ...
-                            ptr::null_mut(),
-                            // ... or line information, but that's not so important.
-                            0)
-                    };
-
-                    let node = Rc::new(NamespaceTreeNode {
-                        name: name,
-                        scope: scope,
-                        parent: parent_node.map(|parent| Rc::downgrade(&parent)),
-                    });
-
-                    debug_context(cx).namespace_map.borrow_mut()
-                                     .insert(current_key.clone(), node.clone());
-
-                    node
-                }
-            };
-
-            parent_node = Some(current_node);
+        // Ignore the name of the item (the last path element).
+        if path.peek().is_none() {
+            break;
         }
 
-        match parent_node {
-            Some(node) => node,
+        // This shouldn't need a roundtrip through InternedString.
+        let namespace_name = path_element.as_interned_str();
+        let name = token::intern(&namespace_name);
+        current_key.push(name);
+
+        let existing_node = debug_context(cx).namespace_map.borrow()
+                                             .get(&current_key).cloned();
+        let current_node = match existing_node {
+            Some(existing_node) => existing_node,
             None => {
-                bug!("debuginfo::namespace_for_item(): \
-                      path too short for {:?}",
-                     def_id);
+                // create and insert
+                let parent_scope = match parent_node {
+                    Some(ref node) => node.scope,
+                    None => ptr::null_mut()
+                };
+                let namespace_name = CString::new(namespace_name.as_bytes()).unwrap();
+                let scope = unsafe {
+                    llvm::LLVMDIBuilderCreateNameSpace(
+                        DIB(cx),
+                        parent_scope,
+                        namespace_name.as_ptr(),
+                        // cannot reconstruct file ...
+                        ptr::null_mut(),
+                        // ... or line information, but that's not so important.
+                        0)
+                };
+
+                let node = Rc::new(NamespaceTreeNode {
+                    name: name,
+                    scope: scope,
+                    parent: parent_node.map(|parent| Rc::downgrade(&parent)),
+                });
+
+                debug_context(cx).namespace_map.borrow_mut()
+                                 .insert(current_key.clone(), node.clone());
+
+                node
             }
+        };
+
+        parent_node = Some(current_node);
+    }
+
+    match parent_node {
+        Some(node) => node,
+        None => {
+            bug!("debuginfo::namespace_for_item: path too short for {:?}", def_id);
         }
-    })
+    }
 }
diff --git a/src/librustc_trans/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs
index 0169734ad3b..6fdd6a2c1d1 100644
--- a/src/librustc_trans/debuginfo/type_names.rs
+++ b/src/librustc_trans/debuginfo/type_names.rs
@@ -10,8 +10,6 @@
 
 // Type Names for Debug Info.
 
-use super::namespace::crate_root_namespace;
-
 use common::CrateContext;
 use rustc::hir::def_id::DefId;
 use rustc::infer;
@@ -163,31 +161,15 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                       def_id: DefId,
                       qualified: bool,
                       output: &mut String) {
-        cx.tcx().with_path(def_id, |path| {
-            if qualified {
-                if def_id.is_local() {
-                    output.push_str(crate_root_namespace(cx));
-                    output.push_str("::");
-                }
-
-                let mut path_element_count = 0;
-                for path_element in path {
-                    output.push_str(&path_element.name().as_str());
-                    output.push_str("::");
-                    path_element_count += 1;
-                }
-
-                if path_element_count == 0 {
-                    bug!("debuginfo: Encountered empty item path!");
-                }
-
-                output.pop();
-                output.pop();
-            } else {
-                let name = path.last().expect("debuginfo: Empty item path?").name();
-                output.push_str(&name.as_str());
+        if qualified {
+            output.push_str(&cx.tcx().crate_name(def_id.krate));
+            for path_element in cx.tcx().def_path(def_id).data {
+                output.push_str("::");
+                output.push_str(&path_element.data.as_interned_str());
             }
-        });
+        } else {
+            output.push_str(&cx.tcx().item_name(def_id).as_str());
+        }
     }
 
     // Pushes the type parameters in the given `Substs` to the output string.
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 70997a1a6ee..8c65eb8dbd3 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -11,6 +11,7 @@
 //! Support for inlining external documentation into the current AST.
 
 use std::collections::HashSet;
+use std::iter::once;
 
 use syntax::ast;
 use syntax::attr::AttrMetaMethods;
@@ -140,8 +141,11 @@ pub fn load_attrs(cx: &DocContext, tcx: &TyCtxt,
 /// source links back to the original item.
 pub fn record_extern_fqn(cx: &DocContext, did: DefId, kind: clean::TypeKind) {
     if let Some(tcx) = cx.tcx_opt() {
-        let fqn = tcx.sess.cstore.extern_item_path(did);
-        let fqn = fqn.into_iter().map(|i| i.to_string()).collect();
+        let crate_name = tcx.sess.cstore.crate_name(did.krate).to_string();
+        let relative = tcx.def_path(did).data.into_iter().map(|elem| {
+            elem.data.to_string()
+        });
+        let fqn = once(crate_name).chain(relative).collect();
         cx.external_paths.borrow_mut().as_mut().unwrap().insert(did, (fqn, kind));
     }
 }
diff --git a/src/test/run-make/pretty-print-path-suffix/foo_method.pp b/src/test/run-make/pretty-print-path-suffix/foo_method.pp
index 4879fbfe6d3..696e0544fdc 100644
--- a/src/test/run-make/pretty-print-path-suffix/foo_method.pp
+++ b/src/test/run-make/pretty-print-path-suffix/foo_method.pp
@@ -13,4 +13,4 @@
 
 
 fn foo_method(&self) -> &'static str { return "i am very similar to foo."; }
-/* nest::S::foo_method */
+/* nest::{{impl}}::foo_method */