about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2016-03-06 15:54:44 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2016-05-16 22:25:08 +0300
commit79b343d87c64e786c79f640675beefa4064100ec (patch)
tree5ecabecc6b6588f4048e93a5cf660d183b2b4396
parentaad347c4f781bda18efb3f3cdbaa736e7e458e24 (diff)
downloadrust-79b343d87c64e786c79f640675beefa4064100ec.tar.gz
rust-79b343d87c64e786c79f640675beefa4064100ec.zip
lowering: Rename identifiers only when necessary
Do not rename invalid identifiers, they stop being invalid after renaming
-rw-r--r--src/librustc/hir/lowering.rs44
-rw-r--r--src/librustc_resolve/lib.rs4
2 files changed, 36 insertions, 12 deletions
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index f5cb611b95f..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
@@ -170,7 +176,11 @@ impl<'a> LoweringContext<'a> {
     }
 
     fn lower_ident(&mut self, ident: Ident) -> Name {
-        mtwt::resolve(ident)
+        if ident.name != keywords::Invalid.name() {
+            mtwt::resolve(ident)
+        } else {
+            ident.name
+        }
     }
 
     fn lower_attrs(&mut self, attrs: &Vec<Attribute>) -> hir::HirVec<Attribute> {
@@ -315,18 +325,14 @@ 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 {
-                               name: if maybe_hygienic {
+                               name: if rename {
                                    self.lower_ident(identifier)
                                } else {
                                    identifier.name
@@ -846,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)),
@@ -1212,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))
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 1d774eda71b..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 });
     }