about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-05-18 00:27:49 -0700
committerbors <bors@rust-lang.org>2016-05-18 00:27:49 -0700
commit310d8996f40fceaa8d294577276cfb1b080c8bc9 (patch)
tree42009bb563e6ab18b8ed13450fee15fd7ee09da5 /src
parent75e23e1b032d87300392a4f3835bde8d5d873823 (diff)
parent02a1eef6e4eb4bcc214e0e00ddc62406c8990e2d (diff)
downloadrust-310d8996f40fceaa8d294577276cfb1b080c8bc9.tar.gz
rust-310d8996f40fceaa8d294577276cfb1b080c8bc9.zip
Auto merge of #33654 - petrochenkov:hirident, r=nrc
Remove hir::Ident

Now when name resolution is done on AST, `hir::Ident` is no longer necessary.
See https://github.com/rust-lang/rust/pull/30145 for more details.

r? @nrc
Diffstat (limited to 'src')
-rw-r--r--src/librustc/cfg/construct.rs4
-rw-r--r--src/librustc/hir/fold.rs30
-rw-r--r--src/librustc/hir/intravisit.rs31
-rw-r--r--src/librustc/hir/lowering.rs89
-rw-r--r--src/librustc/hir/map/def_collector.rs4
-rw-r--r--src/librustc/hir/map/mod.rs4
-rw-r--r--src/librustc/hir/mod.rs91
-rw-r--r--src/librustc/hir/pat_util.rs18
-rw-r--r--src/librustc/hir/print.rs36
-rw-r--r--src/librustc/infer/error_reporting.rs2
-rw-r--r--src/librustc/middle/liveness.rs4
-rw-r--r--src/librustc/middle/resolve_lifetime.rs2
-rw-r--r--src/librustc/ty/mod.rs2
-rw-r--r--src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs2
-rw-r--r--src/librustc_const_eval/check_match.rs8
-rw-r--r--src/librustc_incremental/calculate_svh.rs6
-rw-r--r--src/librustc_lint/bad_style.rs4
-rw-r--r--src/librustc_lint/builtin.rs2
-rw-r--r--src/librustc_metadata/encoder.rs2
-rw-r--r--src/librustc_mir/build/mod.rs4
-rw-r--r--src/librustc_mir/hair/cx/pattern.rs4
-rw-r--r--src/librustc_resolve/lib.rs6
-rw-r--r--src/librustc_trans/_match.rs8
-rw-r--r--src/librustc_trans/debuginfo/create_scope_map.rs6
-rw-r--r--src/librustc_trans/debuginfo/metadata.rs2
-rw-r--r--src/librustc_trans/expr.rs4
-rw-r--r--src/librustc_typeck/astconv.rs6
-rw-r--r--src/librustc_typeck/check/_match.rs4
-rw-r--r--src/librustc_typeck/check/method/suggest.rs2
-rw-r--r--src/librustc_typeck/check/mod.rs2
-rw-r--r--src/librustdoc/clean/mod.rs6
-rw-r--r--src/libsyntax/ast.rs4
32 files changed, 160 insertions, 239 deletions
diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs
index 64c51c94328..76699f13959 100644
--- a/src/librustc/cfg/construct.rs
+++ b/src/librustc/cfg/construct.rs
@@ -285,7 +285,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
             }
 
             hir::ExprBreak(label) => {
-                let loop_scope = self.find_scope(expr, label.map(|l| l.node.name));
+                let loop_scope = self.find_scope(expr, label.map(|l| l.node));
                 let b = self.add_ast_node(expr.id, &[pred]);
                 self.add_exiting_edge(expr, b,
                                       loop_scope, loop_scope.break_index);
@@ -293,7 +293,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
             }
 
             hir::ExprAgain(label) => {
-                let loop_scope = self.find_scope(expr, label.map(|l| l.node.name));
+                let loop_scope = self.find_scope(expr, label.map(|l| l.node));
                 let a = self.add_ast_node(expr.id, &[pred]);
                 self.add_exiting_edge(expr, a,
                                       loop_scope, loop_scope.continue_index);
diff --git a/src/librustc/hir/fold.rs b/src/librustc/hir/fold.rs
index 740d72f4c3e..a91d16f25a2 100644
--- a/src/librustc/hir/fold.rs
+++ b/src/librustc/hir/fold.rs
@@ -126,10 +126,6 @@ pub trait Folder : Sized {
         noop_fold_name(n, self)
     }
 
-    fn fold_ident(&mut self, i: Ident) -> Ident {
-        noop_fold_ident(i, self)
-    }
-
     fn fold_usize(&mut self, i: usize) -> usize {
         noop_fold_usize(i, self)
     }
@@ -407,10 +403,6 @@ pub fn noop_fold_name<T: Folder>(n: Name, _: &mut T) -> Name {
     n
 }
 
-pub fn noop_fold_ident<T: Folder>(i: Ident, _: &mut T) -> Ident {
-    i
-}
-
 pub fn noop_fold_usize<T: Folder>(i: usize, _: &mut T) -> usize {
     i
 }
@@ -418,9 +410,9 @@ pub fn noop_fold_usize<T: Folder>(i: usize, _: &mut T) -> usize {
 pub fn noop_fold_path<T: Folder>(Path { global, segments, span }: Path, fld: &mut T) -> Path {
     Path {
         global: global,
-        segments: segments.move_map(|PathSegment { identifier, parameters }| {
+        segments: segments.move_map(|PathSegment { name, parameters }| {
             PathSegment {
-                identifier: fld.fold_ident(identifier),
+                name: fld.fold_name(name),
                 parameters: fld.fold_path_parameters(parameters),
             }
         }),
@@ -926,7 +918,7 @@ pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> {
                     PatKind::Ident(binding_mode,
                              Spanned {
                                  span: folder.new_span(pth1.span),
-                                 node: folder.fold_ident(pth1.node),
+                                 node: folder.fold_name(pth1.node),
                              },
                              sub.map(|x| folder.fold_pat(x)))
                 }
@@ -1014,14 +1006,14 @@ pub fn noop_fold_expr<T: Folder>(Expr { id, node, span, attrs }: Expr, folder: &
                        folder.fold_block(tr),
                        fl.map(|x| folder.fold_expr(x)))
             }
-            ExprWhile(cond, body, opt_ident) => {
+            ExprWhile(cond, body, opt_name) => {
                 ExprWhile(folder.fold_expr(cond),
                           folder.fold_block(body),
-                          opt_ident.map(|i| folder.fold_ident(i)))
+                          opt_name.map(|i| folder.fold_name(i)))
             }
-            ExprLoop(body, opt_ident) => {
+            ExprLoop(body, opt_name) => {
                 ExprLoop(folder.fold_block(body),
-                         opt_ident.map(|i| folder.fold_ident(i)))
+                         opt_name.map(|i| folder.fold_name(i)))
             }
             ExprMatch(expr, arms, source) => {
                 ExprMatch(folder.fold_expr(expr),
@@ -1061,11 +1053,11 @@ pub fn noop_fold_expr<T: Folder>(Expr { id, node, span, attrs }: Expr, folder: &
                 });
                 ExprPath(qself, folder.fold_path(path))
             }
-            ExprBreak(opt_ident) => ExprBreak(opt_ident.map(|label| {
-                respan(folder.new_span(label.span), folder.fold_ident(label.node))
+            ExprBreak(opt_name) => ExprBreak(opt_name.map(|label| {
+                respan(folder.new_span(label.span), folder.fold_name(label.node))
             })),
-            ExprAgain(opt_ident) => ExprAgain(opt_ident.map(|label| {
-                respan(folder.new_span(label.span), folder.fold_ident(label.node))
+            ExprAgain(opt_name) => ExprAgain(opt_name.map(|label| {
+                respan(folder.new_span(label.span), folder.fold_name(label.node))
             })),
             ExprRet(e) => ExprRet(e.map(|x| folder.fold_expr(x))),
             ExprInlineAsm(asm, outputs, inputs) => {
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index b387ced4822..2e9e433b830 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -97,9 +97,6 @@ pub trait Visitor<'v> : Sized {
     fn visit_name(&mut self, _span: Span, _name: Name) {
         // Nothing to do.
     }
-    fn visit_ident(&mut self, span: Span, ident: Ident) {
-        walk_ident(self, span, ident);
-    }
     fn visit_mod(&mut self, m: &'v Mod, _s: Span, _n: NodeId) {
         walk_mod(self, m)
     }
@@ -211,16 +208,6 @@ pub fn walk_opt_name<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, opt_name:
     }
 }
 
-pub fn walk_opt_ident<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, opt_ident: Option<Ident>) {
-    for ident in opt_ident {
-        visitor.visit_ident(span, ident);
-    }
-}
-
-pub fn walk_ident<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, ident: Ident) {
-    visitor.visit_name(span, ident.name);
-}
-
 /// Walks the contents of a crate. See also `Crate::visit_all_items`.
 pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate) {
     visitor.visit_mod(&krate.module, krate.span, CRATE_NODE_ID);
@@ -439,7 +426,7 @@ pub fn walk_path_list_item<'v, V: Visitor<'v>>(visitor: &mut V,
 pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V,
                                              path_span: Span,
                                              segment: &'v PathSegment) {
-    visitor.visit_ident(path_span, segment.identifier);
+    visitor.visit_name(path_span, segment.name);
     visitor.visit_path_parameters(path_span, &segment.parameters);
 }
 
@@ -495,7 +482,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
             visitor.visit_pat(subpattern)
         }
         PatKind::Ident(_, ref pth1, ref optional_subpattern) => {
-            visitor.visit_ident(pth1.span, pth1.node);
+            visitor.visit_name(pth1.span, pth1.node);
             walk_list!(visitor, visit_pat, optional_subpattern);
         }
         PatKind::Lit(ref expression) => visitor.visit_expr(expression),
@@ -750,14 +737,14 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
             visitor.visit_block(if_block);
             walk_list!(visitor, visit_expr, optional_else);
         }
-        ExprWhile(ref subexpression, ref block, opt_ident) => {
+        ExprWhile(ref subexpression, ref block, opt_name) => {
             visitor.visit_expr(subexpression);
             visitor.visit_block(block);
-            walk_opt_ident(visitor, expression.span, opt_ident)
+            walk_opt_name(visitor, expression.span, opt_name)
         }
-        ExprLoop(ref block, opt_ident) => {
+        ExprLoop(ref block, opt_name) => {
             visitor.visit_block(block);
-            walk_opt_ident(visitor, expression.span, opt_ident)
+            walk_opt_name(visitor, expression.span, opt_name)
         }
         ExprMatch(ref subexpression, ref arms, _) => {
             visitor.visit_expr(subexpression);
@@ -796,9 +783,9 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
             }
             visitor.visit_path(path, expression.id)
         }
-        ExprBreak(ref opt_sp_ident) | ExprAgain(ref opt_sp_ident) => {
-            for sp_ident in opt_sp_ident {
-                visitor.visit_ident(sp_ident.span, sp_ident.node);
+        ExprBreak(ref opt_sp_name) | ExprAgain(ref opt_sp_name) => {
+            for sp_name in opt_sp_name {
+                visitor.visit_name(sp_name.span, sp_name.node);
             }
         }
         ExprRet(ref optional_expression) => {
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 0c3c190064b..67ea7951de7 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -44,7 +44,7 @@ use hir;
 use hir::map::Definitions;
 use hir::map::definitions::DefPathData;
 use hir::def_id::{DefIndex, DefId};
-use hir::def::Def;
+use hir::def::{Def, PathResolution};
 
 use std::collections::BTreeMap;
 use std::iter;
@@ -53,7 +53,7 @@ use syntax::attr::{ThinAttributes, ThinAttributesExt};
 use syntax::ext::mtwt;
 use syntax::ptr::P;
 use syntax::codemap::{respan, Spanned, Span};
-use syntax::parse::token;
+use syntax::parse::token::{self, keywords};
 use syntax::std_inject;
 use syntax::visit::{self, Visitor};
 
@@ -72,6 +72,9 @@ pub trait Resolver {
     // Resolve a global hir path generated by the lowerer when expanding `for`, `if let`, etc.
     fn resolve_generated_global_path(&mut self, path: &hir::Path, is_value: bool) -> Def;
 
+    // Obtain the resolution for a node id
+    fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution>;
+
     // Record the resolution of a path or binding generated by the lowerer when expanding.
     fn record_resolution(&mut self, id: NodeId, def: Def);
 
@@ -85,6 +88,9 @@ impl Resolver for DummyResolver {
     fn resolve_generated_global_path(&mut self, _path: &hir::Path, _is_value: bool) -> Def {
         Def::Err
     }
+    fn get_resolution(&mut self, _id: NodeId) -> Option<PathResolution> {
+        None
+    }
     fn record_resolution(&mut self, _id: NodeId, _def: Def) {}
     fn definitions(&mut self) -> Option<&mut Definitions> {
         None
@@ -150,8 +156,8 @@ impl<'a> LoweringContext<'a> {
         self.id_assigner.next_node_id()
     }
 
-    fn str_to_ident(&self, s: &'static str) -> hir::Ident {
-        hir::Ident::from_name(token::gensym(s))
+    fn str_to_ident(&self, s: &'static str) -> Name {
+        token::gensym(s)
     }
 
     fn with_parent_def<T, F>(&mut self, parent_id: NodeId, f: F) -> T
@@ -169,10 +175,11 @@ impl<'a> LoweringContext<'a> {
         result
     }
 
-    fn lower_ident(&mut self, ident: Ident) -> hir::Ident {
-        hir::Ident {
-            name: mtwt::resolve(ident),
-            unhygienic_name: ident.name,
+    fn lower_ident(&mut self, ident: Ident) -> Name {
+        if ident.name != keywords::Invalid.name() {
+            mtwt::resolve(ident)
+        } else {
+            ident.name
         }
     }
 
@@ -318,21 +325,17 @@ impl<'a> LoweringContext<'a> {
         }
     }
 
-    // Path segments are usually unhygienic, hygienic path segments can occur only in
-    // identifier-like paths originating from `ExprPath`.
-    // Make life simpler for rustc_resolve by renaming only such segments.
-    fn lower_path_full(&mut self, p: &Path, maybe_hygienic: bool) -> hir::Path {
-        let maybe_hygienic = maybe_hygienic && !p.global && p.segments.len() == 1;
+    fn lower_path_full(&mut self, p: &Path, rename: bool) -> hir::Path {
         hir::Path {
             global: p.global,
             segments: p.segments
                        .iter()
                        .map(|&PathSegment { identifier, ref parameters }| {
                            hir::PathSegment {
-                               identifier: if maybe_hygienic {
+                               name: if rename {
                                    self.lower_ident(identifier)
                                } else {
-                                   hir::Ident::from_name(identifier.name)
+                                   identifier.name
                                },
                                parameters: self.lower_path_parameters(parameters),
                            }
@@ -849,9 +852,14 @@ impl<'a> LoweringContext<'a> {
                 PatKind::Wild => hir::PatKind::Wild,
                 PatKind::Ident(ref binding_mode, pth1, ref sub) => {
                     self.with_parent_def(p.id, |this| {
+                        let name = match this.resolver.get_resolution(p.id).map(|d| d.full_def()) {
+                            // Only pattern bindings are renamed
+                            None | Some(Def::Local(..)) => this.lower_ident(pth1.node),
+                            _ => pth1.node.name,
+                        };
                         hir::PatKind::Ident(this.lower_binding_mode(binding_mode),
-                                      respan(pth1.span, this.lower_ident(pth1.node)),
-                                      sub.as_ref().map(|x| this.lower_pat(x)))
+                                            respan(pth1.span, name),
+                                            sub.as_ref().map(|x| this.lower_pat(x)))
                     })
                 }
                 PatKind::Lit(ref e) => hir::PatKind::Lit(self.lower_expr(e)),
@@ -1215,7 +1223,16 @@ impl<'a> LoweringContext<'a> {
                             position: position,
                         }
                     });
-                    hir::ExprPath(hir_qself, self.lower_path_full(path, qself.is_none()))
+                    let rename = if path.segments.len() == 1 {
+                        // Only local variables are renamed
+                        match self.resolver.get_resolution(e.id).map(|d| d.full_def()) {
+                            Some(Def::Local(..)) | Some(Def::Upvar(..)) => true,
+                            _ => false,
+                        }
+                    } else {
+                        false
+                    };
+                    hir::ExprPath(hir_qself, self.lower_path_full(path, rename))
                 }
                 ExprKind::Break(opt_ident) => hir::ExprBreak(opt_ident.map(|sp_ident| {
                     respan(sp_ident.span, self.lower_ident(sp_ident.node))
@@ -1692,7 +1709,7 @@ impl<'a> LoweringContext<'a> {
         self.expr(span, hir::ExprCall(e, args), attrs)
     }
 
-    fn expr_ident(&mut self, span: Span, id: hir::Ident, attrs: ThinAttributes, binding: NodeId)
+    fn expr_ident(&mut self, span: Span, id: Name, attrs: ThinAttributes, binding: NodeId)
                   -> P<hir::Expr> {
         let expr_path = hir::ExprPath(None, self.path_ident(span, id));
         let expr = self.expr(span, expr_path, attrs);
@@ -1760,7 +1777,7 @@ impl<'a> LoweringContext<'a> {
     fn stmt_let(&mut self,
                 sp: Span,
                 mutbl: bool,
-                ident: hir::Ident,
+                ident: Name,
                 ex: P<hir::Expr>,
                 attrs: ThinAttributes)
                 -> (hir::Stmt, NodeId) {
@@ -1834,16 +1851,16 @@ impl<'a> LoweringContext<'a> {
         pat
     }
 
-    fn pat_ident(&mut self, span: Span, ident: hir::Ident) -> P<hir::Pat> {
-        self.pat_ident_binding_mode(span, ident, hir::BindByValue(hir::MutImmutable))
+    fn pat_ident(&mut self, span: Span, name: Name) -> P<hir::Pat> {
+        self.pat_ident_binding_mode(span, name, hir::BindByValue(hir::MutImmutable))
     }
 
-    fn pat_ident_binding_mode(&mut self, span: Span, ident: hir::Ident, bm: hir::BindingMode)
+    fn pat_ident_binding_mode(&mut self, span: Span, name: Name, bm: hir::BindingMode)
                               -> P<hir::Pat> {
         let pat_ident = hir::PatKind::Ident(bm,
                                             Spanned {
                                                 span: span,
-                                                node: ident,
+                                                node: name,
                                             },
                                             None);
 
@@ -1851,7 +1868,7 @@ impl<'a> LoweringContext<'a> {
 
         let parent_def = self.parent_def;
         let def = self.resolver.definitions().map(|defs| {
-            let def_path_data = DefPathData::Binding(ident.name);
+            let def_path_data = DefPathData::Binding(name);
             let def_index = defs.create_def_with_parent(parent_def, pat.id, def_path_data);
             Def::Local(DefId::local(def_index), pat.id)
         }).unwrap_or(Def::Err);
@@ -1872,36 +1889,36 @@ impl<'a> LoweringContext<'a> {
         })
     }
 
-    fn path_ident(&mut self, span: Span, id: hir::Ident) -> hir::Path {
+    fn path_ident(&mut self, span: Span, id: Name) -> hir::Path {
         self.path(span, vec![id])
     }
 
-    fn path(&mut self, span: Span, strs: Vec<hir::Ident>) -> hir::Path {
+    fn path(&mut self, span: Span, strs: Vec<Name>) -> hir::Path {
         self.path_all(span, false, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new())
     }
 
-    fn path_global(&mut self, span: Span, strs: Vec<hir::Ident>) -> hir::Path {
+    fn path_global(&mut self, span: Span, strs: Vec<Name>) -> hir::Path {
         self.path_all(span, true, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new())
     }
 
     fn path_all(&mut self,
                 sp: Span,
                 global: bool,
-                mut idents: Vec<hir::Ident>,
+                mut names: Vec<Name>,
                 lifetimes: hir::HirVec<hir::Lifetime>,
                 types: hir::HirVec<P<hir::Ty>>,
                 bindings: hir::HirVec<hir::TypeBinding>)
                 -> hir::Path {
-        let last_identifier = idents.pop().unwrap();
-        let mut segments: Vec<hir::PathSegment> = idents.into_iter().map(|ident| {
+        let last_identifier = names.pop().unwrap();
+        let mut segments: Vec<hir::PathSegment> = names.into_iter().map(|name| {
             hir::PathSegment {
-                identifier: ident,
+                name: name,
                 parameters: hir::PathParameters::none(),
            }
         }).collect();
 
         segments.push(hir::PathSegment {
-            identifier: last_identifier,
+            name: last_identifier,
             parameters: hir::AngleBracketedParameters(hir::AngleBracketedParameterData {
                 lifetimes: lifetimes,
                 types: types,
@@ -1915,12 +1932,12 @@ impl<'a> LoweringContext<'a> {
         }
     }
 
-    fn std_path(&mut self, components: &[&str]) -> Vec<hir::Ident> {
+    fn std_path(&mut self, components: &[&str]) -> Vec<Name> {
         let mut v = Vec::new();
         if let Some(s) = self.crate_root {
-            v.push(hir::Ident::from_name(token::intern(s)));
+            v.push(token::intern(s));
         }
-        v.extend(components.iter().map(|s| hir::Ident::from_name(token::intern(s))));
+        v.extend(components.iter().map(|s| token::intern(s)));
         return v;
     }
 
diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs
index 640ef48493a..e783d84dc1b 100644
--- a/src/librustc/hir/map/def_collector.rs
+++ b/src/librustc/hir/map/def_collector.rs
@@ -396,8 +396,8 @@ impl<'ast> intravisit::Visitor<'ast> for DefCollector<'ast> {
     fn visit_pat(&mut self, pat: &'ast hir::Pat) {
         let parent_def = self.parent_def;
 
-        if let hir::PatKind::Ident(_, id, _) = pat.node {
-            let def = self.create_def(pat.id, DefPathData::Binding(id.node.name));
+        if let hir::PatKind::Ident(_, name, _) = pat.node {
+            let def = self.create_def(pat.id, DefPathData::Binding(name.node));
             self.parent_def = Some(def);
         }
 
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index f0eb580cfd5..c0bbccad5f2 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -562,9 +562,7 @@ impl<'ast> Map<'ast> {
             NodeVariant(v) => v.node.name,
             NodeLifetime(lt) => lt.name,
             NodeTyParam(tp) => tp.name,
-            NodeLocal(&Pat { node: PatKind::Ident(_,l,_), .. }) => {
-                l.node.name
-            },
+            NodeLocal(&Pat { node: PatKind::Ident(_,l,_), .. }) => l.node,
             NodeStructCtor(_) => self.name(self.get_parent(id)),
             _ => bug!("no name for {}", self.node_to_string(id))
         }
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index eb38458a3ac..39a6ec9f3af 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -46,8 +46,6 @@ use syntax::ptr::P;
 
 use std::collections::BTreeMap;
 use std::fmt;
-use std::hash::{Hash, Hasher};
-use serialize::{Encodable, Decodable, Encoder, Decoder};
 
 /// HIR doesn't commit to a concrete storage type and have its own alias for a vector.
 /// It can be `Vec`, `P<[T]>` or potentially `Box<[T]>`, or some other container with similar
@@ -76,63 +74,6 @@ pub mod pat_util;
 pub mod print;
 pub mod svh;
 
-/// Identifier in HIR
-#[derive(Clone, Copy, Eq)]
-pub struct Ident {
-    /// Hygienic name (renamed), should be used by default
-    pub name: Name,
-    /// Unhygienic name (original, not renamed), needed in few places in name resolution
-    pub unhygienic_name: Name,
-}
-
-impl Ident {
-    /// Creates a HIR identifier with both `name` and `unhygienic_name` initialized with
-    /// the argument. Hygiene properties of the created identifier depend entirely on this
-    /// argument. If the argument is a plain interned string `intern("iter")`, then the result
-    /// is unhygienic and can interfere with other entities named "iter". If the argument is
-    /// a "fresh" name created with `gensym("iter")`, then the result is hygienic and can't
-    /// interfere with other entities having the same string as a name.
-    pub fn from_name(name: Name) -> Ident {
-        Ident { name: name, unhygienic_name: name }
-    }
-}
-
-impl PartialEq for Ident {
-    fn eq(&self, other: &Ident) -> bool {
-        self.name == other.name
-    }
-}
-
-impl Hash for Ident {
-    fn hash<H: Hasher>(&self, state: &mut H) {
-        self.name.hash(state)
-    }
-}
-
-impl fmt::Debug for Ident {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Debug::fmt(&self.name, f)
-    }
-}
-
-impl fmt::Display for Ident {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Display::fmt(&self.name, f)
-    }
-}
-
-impl Encodable for Ident {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        self.name.encode(s)
-    }
-}
-
-impl Decodable for Ident {
-    fn decode<D: Decoder>(d: &mut D) -> Result<Ident, D::Error> {
-        Ok(Ident::from_name(Name::decode(d)?))
-    }
-}
-
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
 pub struct Lifetime {
     pub id: NodeId,
@@ -184,12 +125,12 @@ impl fmt::Display for Path {
 impl Path {
     /// Convert a span and an identifier to the corresponding
     /// 1-segment path.
-    pub fn from_ident(s: Span, ident: Ident) -> Path {
+    pub fn from_name(s: Span, name: Name) -> Path {
         Path {
             span: s,
             global: false,
             segments: hir_vec![PathSegment {
-                identifier: ident,
+                name: name,
                 parameters: PathParameters::none()
             }],
         }
@@ -201,15 +142,7 @@ impl Path {
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct PathSegment {
     /// The identifier portion of this path segment.
-    ///
-    /// Hygiene properties of this identifier are worth noting.
-    /// Most path segments are not hygienic and they are not renamed during
-    /// lowering from AST to HIR (see comments to `fn lower_path`). However segments from
-    /// unqualified paths with one segment originating from `ExprPath` (local-variable-like paths)
-    /// can be hygienic, so they are renamed. You should not normally care about this peculiarity
-    /// and just use `identifier.name` unless you modify identifier resolution code
-    /// (`fn resolve_identifier` and other functions called by it in `rustc_resolve`).
-    pub identifier: Ident,
+    pub name: Name,
 
     /// Type/lifetime parameters attached to this path. They come in
     /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
@@ -600,7 +533,7 @@ pub enum PatKind {
     /// which it is. The resolver determines this, and
     /// records this pattern's `NodeId` in an auxiliary
     /// set (of "PatIdents that refer to unit patterns or constants").
-    Ident(BindingMode, Spanned<Ident>, Option<P<Pat>>),
+    Ident(BindingMode, Spanned<Name>, Option<P<Pat>>),
 
     /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
     /// The `bool` is `true` in the presence of a `..`.
@@ -940,11 +873,11 @@ pub enum Expr_ {
     /// A while loop, with an optional label
     ///
     /// `'label: while expr { block }`
-    ExprWhile(P<Expr>, P<Block>, Option<Ident>),
+    ExprWhile(P<Expr>, P<Block>, Option<Name>),
     /// Conditionless loop (can be exited with break, continue, or return)
     ///
     /// `'label: loop { block }`
-    ExprLoop(P<Block>, Option<Ident>),
+    ExprLoop(P<Block>, Option<Name>),
     /// A `match` block, with a source that indicates whether or not it is
     /// the result of a desugaring, and if so, which kind.
     ExprMatch(P<Expr>, HirVec<Arm>, MatchSource),
@@ -980,9 +913,9 @@ pub enum Expr_ {
     /// A referencing operation (`&a` or `&mut a`)
     ExprAddrOf(Mutability, P<Expr>),
     /// A `break`, with an optional label to break
-    ExprBreak(Option<Spanned<Ident>>),
+    ExprBreak(Option<Spanned<Name>>),
     /// A `continue`, with an optional label
-    ExprAgain(Option<Spanned<Ident>>),
+    ExprAgain(Option<Spanned<Name>>),
     /// A `return`, with an optional value to be returned
     ExprRet(Option<P<Expr>>),
 
@@ -1209,8 +1142,8 @@ pub type ExplicitSelf = Spanned<SelfKind>;
 
 impl Arg {
     pub fn to_self(&self) -> Option<ExplicitSelf> {
-        if let PatKind::Ident(BindByValue(mutbl), ident, _) = self.pat.node {
-            if ident.node.unhygienic_name == keywords::SelfValue.name() {
+        if let PatKind::Ident(BindByValue(mutbl), name, _) = self.pat.node {
+            if name.node.unhygienize() == keywords::SelfValue.name() {
                 return match self.ty.node {
                     TyInfer => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
                     TyRptr(lt, MutTy{ref ty, mutbl}) if ty.node == TyInfer => {
@@ -1225,8 +1158,8 @@ impl Arg {
     }
 
     pub fn is_self(&self) -> bool {
-        if let PatKind::Ident(_, ident, _) = self.pat.node {
-            ident.node.unhygienic_name == keywords::SelfValue.name()
+        if let PatKind::Ident(_, name, _) = self.pat.node {
+            name.node.unhygienize() == keywords::SelfValue.name()
         } else {
             false
         }
diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs
index 6bbd6a207ee..15f2310607f 100644
--- a/src/librustc/hir/pat_util.rs
+++ b/src/librustc/hir/pat_util.rs
@@ -117,19 +117,6 @@ pub fn pat_bindings<I>(dm: &RefCell<DefMap>, pat: &hir::Pat, mut it: I) where
     pat.walk(|p| {
         match p.node {
           PatKind::Ident(binding_mode, ref pth, _) if pat_is_binding(&dm.borrow(), p) => {
-            it(binding_mode, p.id, p.span, &respan(pth.span, pth.node.name));
-          }
-          _ => {}
-        }
-        true
-    });
-}
-pub fn pat_bindings_ident<I>(dm: &RefCell<DefMap>, pat: &hir::Pat, mut it: I) where
-    I: FnMut(hir::BindingMode, ast::NodeId, Span, &Spanned<hir::Ident>),
-{
-    pat.walk(|p| {
-        match p.node {
-          PatKind::Ident(binding_mode, ref pth, _) if pat_is_binding(&dm.borrow(), p) => {
             it(binding_mode, p.id, p.span, &respan(pth.span, pth.node));
           }
           _ => {}
@@ -201,7 +188,7 @@ pub fn pat_contains_bindings_or_wild(dm: &DefMap, pat: &hir::Pat) -> bool {
 pub fn simple_name<'a>(pat: &'a hir::Pat) -> Option<ast::Name> {
     match pat.node {
         PatKind::Ident(hir::BindByValue(_), ref path1, None) => {
-            Some(path1.node.name)
+            Some(path1.node)
         }
         _ => {
             None
@@ -210,8 +197,7 @@ pub fn simple_name<'a>(pat: &'a hir::Pat) -> Option<ast::Name> {
 }
 
 pub fn def_to_path<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> hir::Path {
-    let name = tcx.item_name(id);
-    hir::Path::from_ident(DUMMY_SP, hir::Ident::from_name(name))
+    hir::Path::from_name(DUMMY_SP, tcx.item_name(id))
 }
 
 /// Return variants that are necessary to exist for the pattern to match.
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index c3617cb768d..4455c7da3ba 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -1351,9 +1351,9 @@ impl<'a> State<'a> {
             hir::ExprIf(ref test, ref blk, ref elseopt) => {
                 self.print_if(&test, &blk, elseopt.as_ref().map(|e| &**e))?;
             }
-            hir::ExprWhile(ref test, ref blk, opt_ident) => {
-                if let Some(ident) = opt_ident {
-                    self.print_name(ident.name)?;
+            hir::ExprWhile(ref test, ref blk, opt_name) => {
+                if let Some(name) = opt_name {
+                    self.print_name(name)?;
                     self.word_space(":")?;
                 }
                 self.head("while")?;
@@ -1361,9 +1361,9 @@ impl<'a> State<'a> {
                 space(&mut self.s)?;
                 self.print_block(&blk)?;
             }
-            hir::ExprLoop(ref blk, opt_ident) => {
-                if let Some(ident) = opt_ident {
-                    self.print_name(ident.name)?;
+            hir::ExprLoop(ref blk, opt_name) => {
+                if let Some(name) = opt_name {
+                    self.print_name(name)?;
                     self.word_space(":")?;
                 }
                 self.head("loop")?;
@@ -1455,19 +1455,19 @@ impl<'a> State<'a> {
             hir::ExprPath(Some(ref qself), ref path) => {
                 self.print_qpath(path, qself, true)?
             }
-            hir::ExprBreak(opt_ident) => {
+            hir::ExprBreak(opt_name) => {
                 word(&mut self.s, "break")?;
                 space(&mut self.s)?;
-                if let Some(ident) = opt_ident {
-                    self.print_name(ident.node.name)?;
+                if let Some(name) = opt_name {
+                    self.print_name(name.node)?;
                     space(&mut self.s)?;
                 }
             }
-            hir::ExprAgain(opt_ident) => {
+            hir::ExprAgain(opt_name) => {
                 word(&mut self.s, "continue")?;
                 space(&mut self.s)?;
-                if let Some(ident) = opt_ident {
-                    self.print_name(ident.node.name)?;
+                if let Some(name) = opt_name {
+                    self.print_name(name.node)?;
                     space(&mut self.s)?
                 }
             }
@@ -1615,7 +1615,7 @@ impl<'a> State<'a> {
                 word(&mut self.s, "::")?
             }
 
-            self.print_name(segment.identifier.name)?;
+            self.print_name(segment.name)?;
 
             self.print_path_parameters(&segment.parameters, colons_before_params)?;
         }
@@ -1639,7 +1639,7 @@ impl<'a> State<'a> {
         word(&mut self.s, ">")?;
         word(&mut self.s, "::")?;
         let item_segment = path.segments.last().unwrap();
-        self.print_name(item_segment.identifier.name)?;
+        self.print_name(item_segment.name)?;
         self.print_path_parameters(&item_segment.parameters, colons_before_params)
     }
 
@@ -1727,7 +1727,7 @@ impl<'a> State<'a> {
                         self.word_nbsp("mut")?;
                     }
                 }
-                self.print_name(path1.node.name)?;
+                self.print_name(path1.node)?;
                 match *sub {
                     Some(ref p) => {
                         word(&mut self.s, "@")?;
@@ -2095,7 +2095,7 @@ impl<'a> State<'a> {
             hir::ViewPathSimple(name, ref path) => {
                 self.print_path(path, false, 0)?;
 
-                if path.segments.last().unwrap().identifier.name != name {
+                if path.segments.last().unwrap().name != name {
                     space(&mut self.s)?;
                     self.word_space("as")?;
                     self.print_name(name)?;
@@ -2151,8 +2151,8 @@ impl<'a> State<'a> {
                 if let Some(eself) = input.to_self() {
                     self.print_explicit_self(&eself)?;
                 } else {
-                    let invalid = if let PatKind::Ident(_, ident, _) = input.pat.node {
-                        ident.node.name == keywords::Invalid.name()
+                    let invalid = if let PatKind::Ident(_, name, _) = input.pat.node {
+                        name.node == keywords::Invalid.name()
                     } else {
                         false
                     };
diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs
index 950b7f68ed8..45982793a70 100644
--- a/src/librustc/infer/error_reporting.rs
+++ b/src/librustc/infer/error_reporting.rs
@@ -1514,7 +1514,7 @@ impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> {
             }
         };
         let new_seg = hir::PathSegment {
-            identifier: last_seg.identifier,
+            name: last_seg.name,
             parameters: new_parameters
         };
         let mut new_segs = Vec::new();
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 473fd7d9be6..be8caeb436a 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -1050,7 +1050,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
 
           hir::ExprBreak(opt_label) => {
               // Find which label this break jumps to
-              let sc = self.find_loop_scope(opt_label.map(|l| l.node.name), expr.id, expr.span);
+              let sc = self.find_loop_scope(opt_label.map(|l| l.node), expr.id, expr.span);
 
               // Now that we know the label we're going to,
               // look it up in the break loop nodes table
@@ -1063,7 +1063,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
 
           hir::ExprAgain(opt_label) => {
               // Find which label this expr continues to
-              let sc = self.find_loop_scope(opt_label.map(|l| l.node.name), expr.id, expr.span);
+              let sc = self.find_loop_scope(opt_label.map(|l| l.node), expr.id, expr.span);
 
               // Now that we know the label we're going to,
               // look it up in the continue loop nodes table
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 932f2882b49..2200d72c883 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -433,7 +433,7 @@ fn extract_labels<'v, 'a>(ctxt: &mut LifetimeContext<'a>, b: &'v hir::Block) {
     fn expression_label(ex: &hir::Expr) -> Option<ast::Name> {
         match ex.node {
             hir::ExprWhile(_, _, Some(label)) |
-            hir::ExprLoop(_, Some(label)) => Some(label.unhygienic_name),
+            hir::ExprLoop(_, Some(label)) => Some(label.unhygienize()),
             _ => None,
         }
     }
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 114e81721ab..dfb4ec73924 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -2216,7 +2216,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         match self.map.find(id) {
             Some(ast_map::NodeLocal(pat)) => {
                 match pat.node {
-                    PatKind::Ident(_, ref path1, _) => path1.node.name.as_str(),
+                    PatKind::Ident(_, ref path1, _) => path1.node.as_str(),
                     _ => {
                         bug!("Variable id {} maps to {:?}, not local", id, pat);
                     },
diff --git a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
index c85d69fa8a6..83322215e30 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
@@ -100,7 +100,7 @@ pub fn gather_move_from_pat<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
     let pat_span_path_opt = match move_pat.node {
         PatKind::Ident(_, ref path1, _) => {
             Some(MoveSpanAndPath{span: move_pat.span,
-                                 name: path1.node.name})
+                                 name: path1.node})
         },
         _ => None,
     };
diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs
index 61d2408d5bf..2fb5d796589 100644
--- a/src/librustc_const_eval/check_match.rs
+++ b/src/librustc_const_eval/check_match.rs
@@ -240,24 +240,24 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &hir::Expr) {
 fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat) {
     pat.walk(|p| {
         match p.node {
-            PatKind::Ident(hir::BindByValue(hir::MutImmutable), ident, None) => {
+            PatKind::Ident(hir::BindByValue(hir::MutImmutable), name, None) => {
                 let pat_ty = cx.tcx.pat_ty(p);
                 if let ty::TyEnum(edef, _) = pat_ty.sty {
                     let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def());
                     if let Some(Def::Local(..)) = def {
                         if edef.variants.iter().any(|variant|
-                            variant.name == ident.node.unhygienic_name
+                            variant.name == name.node.unhygienize()
                                 && variant.kind() == VariantKind::Unit
                         ) {
                             let ty_path = cx.tcx.item_path_str(edef.did);
                             let mut err = struct_span_warn!(cx.tcx.sess, p.span, E0170,
                                 "pattern binding `{}` is named the same as one \
                                  of the variants of the type `{}`",
-                                ident.node, ty_path);
+                                name.node, ty_path);
                             help!(err,
                                 "if you meant to match on a variant, \
                                  consider making the path in the pattern qualified: `{}::{}`",
-                                ty_path, ident.node);
+                                ty_path, name.node);
                             err.emit();
                         }
                     }
diff --git a/src/librustc_incremental/calculate_svh.rs b/src/librustc_incremental/calculate_svh.rs
index e914c38963c..f134f3c3f10 100644
--- a/src/librustc_incremental/calculate_svh.rs
+++ b/src/librustc_incremental/calculate_svh.rs
@@ -244,7 +244,7 @@ mod svh_visitor {
             ExprType(..)             => SawExprType,
             ExprIf(..)               => SawExprIf,
             ExprWhile(..)            => SawExprWhile,
-            ExprLoop(_, id)          => SawExprLoop(id.map(|id| id.name.as_str())),
+            ExprLoop(_, id)          => SawExprLoop(id.map(|id| id.as_str())),
             ExprMatch(..)            => SawExprMatch,
             ExprClosure(..)          => SawExprClosure,
             ExprBlock(..)            => SawExprBlock,
@@ -255,8 +255,8 @@ mod svh_visitor {
             ExprIndex(..)            => SawExprIndex,
             ExprPath(ref qself, _)   => SawExprPath(qself.as_ref().map(|q| q.position)),
             ExprAddrOf(m, _)         => SawExprAddrOf(m),
-            ExprBreak(id)            => SawExprBreak(id.map(|id| id.node.name.as_str())),
-            ExprAgain(id)            => SawExprAgain(id.map(|id| id.node.name.as_str())),
+            ExprBreak(id)            => SawExprBreak(id.map(|id| id.node.as_str())),
+            ExprAgain(id)            => SawExprAgain(id.map(|id| id.node.as_str())),
             ExprRet(..)              => SawExprRet,
             ExprInlineAsm(ref a,_,_) => SawExprInlineAsm(a),
             ExprStruct(..)           => SawExprStruct,
diff --git a/src/librustc_lint/bad_style.rs b/src/librustc_lint/bad_style.rs
index f4fb226d352..27a6e433c73 100644
--- a/src/librustc_lint/bad_style.rs
+++ b/src/librustc_lint/bad_style.rs
@@ -277,7 +277,7 @@ impl LateLintPass for NonSnakeCase {
         if let &PatKind::Ident(_, ref path1, _) = &p.node {
             let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def());
             if let Some(Def::Local(..)) = def {
-                self.check_snake_case(cx, "variable", &path1.node.name.as_str(), Some(p.span));
+                self.check_snake_case(cx, "variable", &path1.node.as_str(), Some(p.span));
             }
         }
     }
@@ -363,7 +363,7 @@ impl LateLintPass for NonUpperCaseGlobals {
         match (&p.node, cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def())) {
             (&PatKind::Ident(_, ref path1, _), Some(Def::Const(..))) => {
                 NonUpperCaseGlobals::check_upper_case(cx, "constant in pattern",
-                                                      path1.node.name, p.span);
+                                                      path1.node, p.span);
             }
             _ => {}
         }
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index d1eba5b3f4a..49b59aea46e 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -172,7 +172,7 @@ impl LateLintPass for NonShorthandFieldPatterns {
             });
             for fieldpat in field_pats {
                 if let PatKind::Ident(_, ident, None) = fieldpat.node.pat.node {
-                    if ident.node.unhygienic_name == fieldpat.node.name {
+                    if ident.node.unhygienize() == fieldpat.node.name {
                         cx.span_lint(NON_SHORTHAND_FIELD_PATTERNS, fieldpat.span,
                                      &format!("the `{}:` in this pattern is redundant and can \
                                               be removed", ident.node))
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 020f12d753e..662942a5bdc 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -762,7 +762,7 @@ fn encode_method_argument_names(rbml_w: &mut Encoder,
     for arg in &decl.inputs {
         let tag = tag_method_argument_name;
         if let PatKind::Ident(_, ref path1, _) = arg.pat.node {
-            let name = path1.node.name.as_str();
+            let name = path1.node.as_str();
             rbml_w.wr_tagged_bytes(tag, name.as_bytes());
         } else {
             rbml_w.wr_tagged_bytes(tag, &[]);
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index 77499a0f96c..d75cf3b7587 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -222,7 +222,7 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
             };
             if let Some(hir::map::NodeLocal(pat)) = tcx.map.find(fv.def.var_id()) {
                 if let hir::PatKind::Ident(_, ref ident, _) = pat.node {
-                    decl.debug_name = ident.node.name;
+                    decl.debug_name = ident.node;
                 }
             }
             decl
@@ -335,7 +335,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             if let Some(pat) = pattern {
                 if let hir::PatKind::Ident(_, ref ident, _) = pat.node {
                     if pat_is_binding(&self.hir.tcx().def_map.borrow(), pat) {
-                        name = ident.node.name;
+                        name = ident.node;
                     }
                 }
             }
diff --git a/src/librustc_mir/hair/cx/pattern.rs b/src/librustc_mir/hair/cx/pattern.rs
index 9e08e7b62d3..0118b97dd7f 100644
--- a/src/librustc_mir/hair/cx/pattern.rs
+++ b/src/librustc_mir/hair/cx/pattern.rs
@@ -166,7 +166,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
             {
                 let id = match self.binding_map {
                     None => pat.id,
-                    Some(ref map) => map[&ident.node.name],
+                    Some(ref map) => map[&ident.node],
                 };
                 let var_ty = self.cx.tcx.node_id_to_type(pat.id);
                 let region = match var_ty.sty {
@@ -197,7 +197,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
                 PatternKind::Binding {
                     mutability: mutability,
                     mode: mode,
-                    name: ident.node.name,
+                    name: ident.node,
                     var: id,
                     ty: var_ty,
                     subpattern: self.to_opt_pattern(sub),
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 5b447a1690f..016dff5f005 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1102,6 +1102,10 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
         }
     }
 
+    fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution> {
+        self.def_map.get(&id).cloned()
+    }
+
     fn record_resolution(&mut self, id: NodeId, def: Def) {
         self.def_map.insert(id, PathResolution { base_def: def, depth: 0 });
     }
@@ -1123,7 +1127,7 @@ impl Named for ast::PathSegment {
 
 impl Named for hir::PathSegment {
     fn name(&self) -> Name {
-        self.identifier.name
+        self.name
     }
 }
 
diff --git a/src/librustc_trans/_match.rs b/src/librustc_trans/_match.rs
index 6df308d5e62..dbc277f2432 100644
--- a/src/librustc_trans/_match.rs
+++ b/src/librustc_trans/_match.rs
@@ -482,7 +482,7 @@ fn expand_nested_bindings<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         loop {
             pat = match pat.node {
                 PatKind::Ident(_, ref path, Some(ref inner)) => {
-                    bound_ptrs.push((path.node.name, val.val));
+                    bound_ptrs.push((path.node, val.val));
                     &inner
                 },
                 _ => break
@@ -520,7 +520,7 @@ fn enter_match<'a, 'b, 'p, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
             match this.node {
                 PatKind::Ident(_, ref path, None) => {
                     if pat_is_binding(&dm.borrow(), &this) {
-                        bound_ptrs.push((path.node.name, val.val));
+                        bound_ptrs.push((path.node, val.val));
                     }
                 }
                 PatKind::Vec(ref before, Some(ref slice), ref after) => {
@@ -528,7 +528,7 @@ fn enter_match<'a, 'b, 'p, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
                         let subslice_val = bind_subslice_pat(
                             bcx, this.id, val,
                             before.len(), after.len());
-                        bound_ptrs.push((path.node.name, subslice_val));
+                        bound_ptrs.push((path.node, subslice_val));
                     }
                 }
                 _ => {}
@@ -1802,7 +1802,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 // binding will live and place it into the appropriate
                 // map.
                 bcx = mk_binding_alloca(
-                    bcx, pat.id, path1.node.name, cleanup_scope, (),
+                    bcx, pat.id, path1.node, cleanup_scope, (),
                     "_match::bind_irrefutable_pat",
                     |(), bcx, Datum { val: llval, ty, kind: _ }| {
                         match pat_binding_mode {
diff --git a/src/librustc_trans/debuginfo/create_scope_map.rs b/src/librustc_trans/debuginfo/create_scope_map.rs
index 3a8974c2aca..ba592382d1a 100644
--- a/src/librustc_trans/debuginfo/create_scope_map.rs
+++ b/src/librustc_trans/debuginfo/create_scope_map.rs
@@ -51,9 +51,9 @@ pub fn create_scope_map(cx: &CrateContext,
     // Push argument identifiers onto the stack so arguments integrate nicely
     // with variable shadowing.
     for arg in args {
-        pat_util::pat_bindings_ident(def_map, &arg.pat, |_, node_id, _, path1| {
+        pat_util::pat_bindings(def_map, &arg.pat, |_, node_id, _, path1| {
             scope_stack.push(ScopeStackEntry { scope_metadata: fn_metadata,
-                                               name: Some(path1.node.unhygienic_name) });
+                                               name: Some(path1.node.unhygienize()) });
             scope_map.insert(node_id, fn_metadata);
         })
     }
@@ -248,7 +248,7 @@ fn walk_pattern(cx: &CrateContext,
             // scope stack and maybe introduce an artificial scope
             if pat_util::pat_is_binding(&def_map.borrow(), &pat) {
 
-                let name = path1.node.unhygienic_name;
+                let name = path1.node.unhygienize();
 
                 // LLVM does not properly generate 'DW_AT_start_scope' fields
                 // for variable DIEs. For this reason we have to introduce
diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs
index 7826693c827..ccb01789aa6 100644
--- a/src/librustc_trans/debuginfo/metadata.rs
+++ b/src/librustc_trans/debuginfo/metadata.rs
@@ -1946,7 +1946,7 @@ pub fn create_captured_var_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         Some(hir_map::NodeLocal(pat)) => {
             match pat.node {
                 PatKind::Ident(_, ref path1, _) => {
-                    path1.node.name
+                    path1.node
                 }
                 _ => {
                     span_bug!(span,
diff --git a/src/librustc_trans/expr.rs b/src/librustc_trans/expr.rs
index 186781547f9..36a593a546b 100644
--- a/src/librustc_trans/expr.rs
+++ b/src/librustc_trans/expr.rs
@@ -928,13 +928,13 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     match expr.node {
         hir::ExprBreak(label_opt) => {
-            controlflow::trans_break(bcx, expr, label_opt.map(|l| l.node.name))
+            controlflow::trans_break(bcx, expr, label_opt.map(|l| l.node))
         }
         hir::ExprType(ref e, _) => {
             trans_into(bcx, &e, Ignore)
         }
         hir::ExprAgain(label_opt) => {
-            controlflow::trans_cont(bcx, expr, label_opt.map(|l| l.node.name))
+            controlflow::trans_cont(bcx, expr, label_opt.map(|l| l.node))
         }
         hir::ExprRet(ref ex) => {
             // Check to see if the return expression itself is reachable.
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index ac86b7c8740..9944f453f0a 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1283,7 +1283,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
                                  -> (Ty<'tcx>, Def)
     {
         let tcx = self.tcx();
-        let assoc_name = item_segment.identifier.name;
+        let assoc_name = item_segment.name;
 
         debug!("associated_path_def_to_ty: {:?}::{}", ty, assoc_name);
 
@@ -1394,7 +1394,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
             self.report_ambiguous_associated_type(span,
                                                   "Type",
                                                   &path_str,
-                                                  &item_segment.identifier.name.as_str());
+                                                  &item_segment.name.as_str());
             return tcx.types.err;
         };
 
@@ -1409,7 +1409,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
 
         debug!("qpath_to_ty: trait_ref={:?}", trait_ref);
 
-        self.projected_ty(span, trait_ref, item_segment.identifier.name)
+        self.projected_ty(span, trait_ref, item_segment.name)
     }
 
     /// Convert a type supplied as value for a type argument from AST into our
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index d55ca803c64..10c8ea84bfd 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -200,7 +200,7 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> {
 
                 // if there are multiple arms, make sure they all agree on
                 // what the type of the binding `x` ought to be
-                if let Some(&canon_id) = self.map.get(&path.node.name) {
+                if let Some(&canon_id) = self.map.get(&path.node) {
                     if canon_id != pat.id {
                         let ct = self.local_ty(pat.span, canon_id);
                         self.demand_eqtype(pat.span, ct, typ);
@@ -212,7 +212,7 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> {
                 }
             }
             PatKind::Ident(_, ref path, _) => {
-                let path = hir::Path::from_ident(path.span, path.node);
+                let path = hir::Path::from_name(path.span, path.node);
                 self.check_pat_enum(pat, &path, Some(&[]), expected, false);
             }
             PatKind::TupleStruct(ref path, ref subpats) => {
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index be329ec11af..2cd60d20251 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -216,7 +216,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         }
                         else if let Expr_::ExprPath(_, path) = expr.node.clone() {
                             if let Some(segment) = path.segments.last() {
-                                report_function!(expr.span, segment.identifier.name);
+                                report_function!(expr.span, segment.name);
                             }
                         }
                     }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 1ee9d1032a6..3ea617d310b 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3870,7 +3870,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                                                  &ty_segments[..base_ty_end],
                                                                  &ty_segments[base_ty_end..]);
             let item_segment = path.segments.last().unwrap();
-            let item_name = item_segment.identifier.name;
+            let item_name = item_segment.name;
             let def = match self.resolve_ufcs(span, item_name, ty, node_id) {
                 Ok(def) => Some(def),
                 Err(error) => {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index ce83c4a258c..463702c11b7 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1626,7 +1626,7 @@ impl Clean<Type> for hir::Ty {
                     segments: segments.into(),
                 };
                 Type::QPath {
-                    name: p.segments.last().unwrap().identifier.name.clean(cx),
+                    name: p.segments.last().unwrap().name.clean(cx),
                     self_type: box qself.ty.clean(cx),
                     trait_: box resolve_type(cx, trait_path.clean(cx), self.id)
                 }
@@ -2064,7 +2064,7 @@ pub struct PathSegment {
 impl Clean<PathSegment> for hir::PathSegment {
     fn clean(&self, cx: &DocContext) -> PathSegment {
         PathSegment {
-            name: self.identifier.name.clean(cx),
+            name: self.name.clean(cx),
             params: self.parameters.clean(cx)
         }
     }
@@ -2073,7 +2073,7 @@ impl Clean<PathSegment> for hir::PathSegment {
 fn path_to_string(p: &hir::Path) -> String {
     let mut s = String::new();
     let mut first = true;
-    for i in p.segments.iter().map(|x| x.identifier.name.as_str()) {
+    for i in p.segments.iter().map(|x| x.name.as_str()) {
         if !first || p.global {
             s.push_str("::");
         } else {
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 0f3b9be3a7a..d9409d3bbd9 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -60,6 +60,10 @@ impl Name {
     pub fn as_str(self) -> token::InternedString {
         token::InternedString::new_from_name(self)
     }
+
+    pub fn unhygienize(self) -> Name {
+        token::intern(&self.as_str())
+    }
 }
 
 impl fmt::Debug for Name {