Skip to content

Commit 79b343d

Browse files
committed
lowering: Rename identifiers only when necessary
Do not rename invalid identifiers, they stop being invalid after renaming
1 parent aad347c commit 79b343d

File tree

2 files changed

+36
-12
lines changed

2 files changed

+36
-12
lines changed

src/librustc/hir/lowering.rs

+32-12
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ use hir;
4444
use hir::map::Definitions;
4545
use hir::map::definitions::DefPathData;
4646
use hir::def_id::{DefIndex, DefId};
47-
use hir::def::Def;
47+
use hir::def::{Def, PathResolution};
4848

4949
use std::collections::BTreeMap;
5050
use std::iter;
@@ -53,7 +53,7 @@ use syntax::attr::{ThinAttributes, ThinAttributesExt};
5353
use syntax::ext::mtwt;
5454
use syntax::ptr::P;
5555
use syntax::codemap::{respan, Spanned, Span};
56-
use syntax::parse::token;
56+
use syntax::parse::token::{self, keywords};
5757
use syntax::std_inject;
5858
use syntax::visit::{self, Visitor};
5959

@@ -72,6 +72,9 @@ pub trait Resolver {
7272
// Resolve a global hir path generated by the lowerer when expanding `for`, `if let`, etc.
7373
fn resolve_generated_global_path(&mut self, path: &hir::Path, is_value: bool) -> Def;
7474

75+
// Obtain the resolution for a node id
76+
fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution>;
77+
7578
// Record the resolution of a path or binding generated by the lowerer when expanding.
7679
fn record_resolution(&mut self, id: NodeId, def: Def);
7780

@@ -85,6 +88,9 @@ impl Resolver for DummyResolver {
8588
fn resolve_generated_global_path(&mut self, _path: &hir::Path, _is_value: bool) -> Def {
8689
Def::Err
8790
}
91+
fn get_resolution(&mut self, _id: NodeId) -> Option<PathResolution> {
92+
None
93+
}
8894
fn record_resolution(&mut self, _id: NodeId, _def: Def) {}
8995
fn definitions(&mut self) -> Option<&mut Definitions> {
9096
None
@@ -170,7 +176,11 @@ impl<'a> LoweringContext<'a> {
170176
}
171177

172178
fn lower_ident(&mut self, ident: Ident) -> Name {
173-
mtwt::resolve(ident)
179+
if ident.name != keywords::Invalid.name() {
180+
mtwt::resolve(ident)
181+
} else {
182+
ident.name
183+
}
174184
}
175185

176186
fn lower_attrs(&mut self, attrs: &Vec<Attribute>) -> hir::HirVec<Attribute> {
@@ -315,18 +325,14 @@ impl<'a> LoweringContext<'a> {
315325
}
316326
}
317327

318-
// Path segments are usually unhygienic, hygienic path segments can occur only in
319-
// identifier-like paths originating from `ExprPath`.
320-
// Make life simpler for rustc_resolve by renaming only such segments.
321-
fn lower_path_full(&mut self, p: &Path, maybe_hygienic: bool) -> hir::Path {
322-
let maybe_hygienic = maybe_hygienic && !p.global && p.segments.len() == 1;
328+
fn lower_path_full(&mut self, p: &Path, rename: bool) -> hir::Path {
323329
hir::Path {
324330
global: p.global,
325331
segments: p.segments
326332
.iter()
327333
.map(|&PathSegment { identifier, ref parameters }| {
328334
hir::PathSegment {
329-
name: if maybe_hygienic {
335+
name: if rename {
330336
self.lower_ident(identifier)
331337
} else {
332338
identifier.name
@@ -846,9 +852,14 @@ impl<'a> LoweringContext<'a> {
846852
PatKind::Wild => hir::PatKind::Wild,
847853
PatKind::Ident(ref binding_mode, pth1, ref sub) => {
848854
self.with_parent_def(p.id, |this| {
855+
let name = match this.resolver.get_resolution(p.id).map(|d| d.full_def()) {
856+
// Only pattern bindings are renamed
857+
None | Some(Def::Local(..)) => this.lower_ident(pth1.node),
858+
_ => pth1.node.name,
859+
};
849860
hir::PatKind::Ident(this.lower_binding_mode(binding_mode),
850-
respan(pth1.span, this.lower_ident(pth1.node)),
851-
sub.as_ref().map(|x| this.lower_pat(x)))
861+
respan(pth1.span, name),
862+
sub.as_ref().map(|x| this.lower_pat(x)))
852863
})
853864
}
854865
PatKind::Lit(ref e) => hir::PatKind::Lit(self.lower_expr(e)),
@@ -1212,7 +1223,16 @@ impl<'a> LoweringContext<'a> {
12121223
position: position,
12131224
}
12141225
});
1215-
hir::ExprPath(hir_qself, self.lower_path_full(path, qself.is_none()))
1226+
let rename = if path.segments.len() == 1 {
1227+
// Only local variables are renamed
1228+
match self.resolver.get_resolution(e.id).map(|d| d.full_def()) {
1229+
Some(Def::Local(..)) | Some(Def::Upvar(..)) => true,
1230+
_ => false,
1231+
}
1232+
} else {
1233+
false
1234+
};
1235+
hir::ExprPath(hir_qself, self.lower_path_full(path, rename))
12161236
}
12171237
ExprKind::Break(opt_ident) => hir::ExprBreak(opt_ident.map(|sp_ident| {
12181238
respan(sp_ident.span, self.lower_ident(sp_ident.node))

src/librustc_resolve/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,10 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
11021102
}
11031103
}
11041104

1105+
fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution> {
1106+
self.def_map.get(&id).cloned()
1107+
}
1108+
11051109
fn record_resolution(&mut self, id: NodeId, def: Def) {
11061110
self.def_map.insert(id, PathResolution { base_def: def, depth: 0 });
11071111
}

0 commit comments

Comments
 (0)