Skip to content

Commit

Permalink
lowering: Rename identifiers only when necessary
Browse files Browse the repository at this point in the history
Do not rename invalid identifiers, they stop being invalid after renaming
  • Loading branch information
petrochenkov committed May 16, 2016
1 parent aad347c commit 79b343d
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 12 deletions.
44 changes: 32 additions & 12 deletions src/librustc/hir/lowering.rs
Expand Up @@ -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;
Expand All @@ -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};

Expand All @@ -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);

Expand All @@ -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
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)),
Expand Down Expand Up @@ -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))
Expand Down
4 changes: 4 additions & 0 deletions src/librustc_resolve/lib.rs
Expand Up @@ -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 });
}
Expand Down

0 comments on commit 79b343d

Please sign in to comment.