Skip to content

Commit a15dfca

Browse files
committed
Instead of renaming, treat differently marked identifiers as unequal
1 parent ca92404 commit a15dfca

File tree

6 files changed

+37
-560
lines changed

6 files changed

+37
-560
lines changed

src/librustc_resolve/lib.rs

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ use rustc::ty::subst::{ParamSpace, FnSpace, TypeSpace};
5353
use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
5454
use rustc::util::nodemap::{NodeMap, NodeSet, FnvHashMap, FnvHashSet};
5555

56-
use syntax::ext::mtwt;
5756
use syntax::ast::{self, FloatTy};
5857
use syntax::ast::{CRATE_NODE_ID, Name, NodeId, CrateNum, IntTy, UintTy};
5958
use syntax::parse::token::{self, keywords};
@@ -462,7 +461,7 @@ struct BindingInfo {
462461
}
463462

464463
// Map from the name in a pattern to its binding mode.
465-
type BindingMap = HashMap<Name, BindingInfo>;
464+
type BindingMap = HashMap<ast::Ident, BindingInfo>;
466465

467466
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
468467
enum PatternSource {
@@ -668,7 +667,7 @@ enum ModulePrefixResult<'a> {
668667
/// One local scope.
669668
#[derive(Debug)]
670669
struct Rib<'a> {
671-
bindings: HashMap<Name, Def>,
670+
bindings: HashMap<ast::Ident, Def>,
672671
kind: RibKind<'a>,
673672
}
674673

@@ -1385,15 +1384,17 @@ impl<'a> Resolver<'a> {
13851384
/// Invariant: This must only be called during main resolution, not during
13861385
/// import resolution.
13871386
fn resolve_ident_in_lexical_scope(&mut self,
1388-
ident: ast::Ident,
1387+
mut ident: ast::Ident,
13891388
ns: Namespace,
13901389
record_used: bool)
13911390
-> Option<LexicalScopeBinding<'a>> {
1392-
let name = match ns { ValueNS => mtwt::resolve(ident), TypeNS => ident.name };
1391+
if ns == TypeNS {
1392+
ident = ast::Ident::with_empty_ctxt(ident.name);
1393+
}
13931394

13941395
// Walk backwards up the ribs in scope.
13951396
for i in (0 .. self.get_ribs(ns).len()).rev() {
1396-
if let Some(def) = self.get_ribs(ns)[i].bindings.get(&name).cloned() {
1397+
if let Some(def) = self.get_ribs(ns)[i].bindings.get(&ident).cloned() {
13971398
// The ident resolves to a type parameter or local variable.
13981399
return Some(LexicalScopeBinding::LocalDef(LocalDef {
13991400
ribs: Some((ns, i)),
@@ -1556,7 +1557,7 @@ impl<'a> Resolver<'a> {
15561557

15571558
/// Searches the current set of local scopes for labels.
15581559
/// Stops after meeting a closure.
1559-
fn search_label(&self, name: Name) -> Option<Def> {
1560+
fn search_label(&self, ident: ast::Ident) -> Option<Def> {
15601561
for rib in self.label_ribs.iter().rev() {
15611562
match rib.kind {
15621563
NormalRibKind => {
@@ -1567,7 +1568,7 @@ impl<'a> Resolver<'a> {
15671568
return None;
15681569
}
15691570
}
1570-
let result = rib.bindings.get(&name).cloned();
1571+
let result = rib.bindings.get(&ident).cloned();
15711572
if result.is_some() {
15721573
return result;
15731574
}
@@ -1716,7 +1717,7 @@ impl<'a> Resolver<'a> {
17161717
// plain insert (no renaming)
17171718
let def_id = self.definitions.local_def_id(type_parameter.id);
17181719
let def = Def::TyParam(space, index as u32, def_id, name);
1719-
function_type_rib.bindings.insert(name, def);
1720+
function_type_rib.bindings.insert(ast::Ident::with_empty_ctxt(name), def);
17201721
}
17211722
self.type_ribs.push(function_type_rib);
17221723
}
@@ -1887,7 +1888,7 @@ impl<'a> Resolver<'a> {
18871888
let mut self_type_rib = Rib::new(NormalRibKind);
18881889

18891890
// plain insert (no renaming, types are not currently hygienic....)
1890-
self_type_rib.bindings.insert(keywords::SelfType.name(), self_def);
1891+
self_type_rib.bindings.insert(keywords::SelfType.ident(), self_def);
18911892
self.type_ribs.push(self_type_rib);
18921893
f(self);
18931894
self.type_ribs.pop();
@@ -1998,7 +1999,7 @@ impl<'a> Resolver<'a> {
19981999
_ => false,
19992000
} {
20002001
let binding_info = BindingInfo { span: ident.span, binding_mode: binding_mode };
2001-
binding_map.insert(mtwt::resolve(ident.node), binding_info);
2002+
binding_map.insert(ident.node, binding_info);
20022003
}
20032004
}
20042005
true
@@ -2020,15 +2021,14 @@ impl<'a> Resolver<'a> {
20202021
for (&key, &binding_0) in &map_0 {
20212022
match map_i.get(&key) {
20222023
None => {
2023-
resolve_error(self,
2024-
p.span,
2025-
ResolutionError::VariableNotBoundInPattern(key, 1, i + 1));
2024+
let error = ResolutionError::VariableNotBoundInPattern(key.name, 1, i + 1);
2025+
resolve_error(self, p.span, error);
20262026
}
20272027
Some(binding_i) => {
20282028
if binding_0.binding_mode != binding_i.binding_mode {
20292029
resolve_error(self,
20302030
binding_i.span,
2031-
ResolutionError::VariableBoundWithDifferentMode(key,
2031+
ResolutionError::VariableBoundWithDifferentMode(key.name,
20322032
i + 1));
20332033
}
20342034
}
@@ -2039,7 +2039,7 @@ impl<'a> Resolver<'a> {
20392039
if !map_0.contains_key(&key) {
20402040
resolve_error(self,
20412041
binding.span,
2042-
ResolutionError::VariableNotBoundInPattern(key, i + 1, 1));
2042+
ResolutionError::VariableNotBoundInPattern(key.name, i + 1, 1));
20432043
}
20442044
}
20452045
}
@@ -2173,16 +2173,15 @@ impl<'a> Resolver<'a> {
21732173
pat_id: NodeId,
21742174
outer_pat_id: NodeId,
21752175
pat_src: PatternSource,
2176-
bindings: &mut HashMap<Name, NodeId>)
2176+
bindings: &mut HashMap<ast::Ident, NodeId>)
21772177
-> PathResolution {
21782178
// Add the binding to the local ribs, if it
21792179
// doesn't already exist in the bindings map. (We
21802180
// must not add it if it's in the bindings map
21812181
// because that breaks the assumptions later
21822182
// passes make about or-patterns.)
2183-
let renamed = mtwt::resolve(ident.node);
21842183
let mut def = Def::Local(self.definitions.local_def_id(pat_id), pat_id);
2185-
match bindings.get(&renamed).cloned() {
2184+
match bindings.get(&ident.node).cloned() {
21862185
Some(id) if id == outer_pat_id => {
21872186
// `Variant(a, a)`, error
21882187
resolve_error(
@@ -2204,7 +2203,7 @@ impl<'a> Resolver<'a> {
22042203
Some(..) if pat_src == PatternSource::Match => {
22052204
// `Variant1(a) | Variant2(a)`, ok
22062205
// Reuse definition from the first `a`.
2207-
def = self.value_ribs.last_mut().unwrap().bindings[&renamed];
2206+
def = self.value_ribs.last_mut().unwrap().bindings[&ident.node];
22082207
}
22092208
Some(..) => {
22102209
span_bug!(ident.span, "two bindings with the same name from \
@@ -2213,8 +2212,8 @@ impl<'a> Resolver<'a> {
22132212
None => {
22142213
// A completely fresh binding, add to the lists if it's valid.
22152214
if ident.node.name != keywords::Invalid.name() {
2216-
bindings.insert(renamed, outer_pat_id);
2217-
self.value_ribs.last_mut().unwrap().bindings.insert(renamed, def);
2215+
bindings.insert(ident.node, outer_pat_id);
2216+
self.value_ribs.last_mut().unwrap().bindings.insert(ident.node, def);
22182217
}
22192218
}
22202219
}
@@ -2275,7 +2274,7 @@ impl<'a> Resolver<'a> {
22752274
pat_src: PatternSource,
22762275
// Maps idents to the node ID for the
22772276
// outermost pattern that binds them.
2278-
bindings: &mut HashMap<Name, NodeId>) {
2277+
bindings: &mut HashMap<ast::Ident, NodeId>) {
22792278
// Visit all direct subpatterns of this pattern.
22802279
let outer_pat_id = pat.id;
22812280
pat.walk(&mut |pat| {
@@ -2748,7 +2747,7 @@ impl<'a> Resolver<'a> {
27482747
let names = self.value_ribs
27492748
.iter()
27502749
.rev()
2751-
.flat_map(|rib| rib.bindings.keys());
2750+
.flat_map(|rib| rib.bindings.keys().map(|ident| &ident.name));
27522751

27532752
if let Some(found) = find_best_match_for_name(names, name, None) {
27542753
if name != found {
@@ -2759,7 +2758,7 @@ impl<'a> Resolver<'a> {
27592758

27602759
fn resolve_labeled_block(&mut self, label: Option<ast::Ident>, id: NodeId, block: &Block) {
27612760
if let Some(label) = label {
2762-
let (label, def) = (mtwt::resolve(label), Def::Label(id));
2761+
let def = Def::Label(id);
27632762
self.with_label_rib(|this| {
27642763
this.label_ribs.last_mut().unwrap().bindings.insert(label, def);
27652764
this.visit_block(block);
@@ -2966,15 +2965,15 @@ impl<'a> Resolver<'a> {
29662965

29672966
{
29682967
let rib = this.label_ribs.last_mut().unwrap();
2969-
rib.bindings.insert(mtwt::resolve(label.node), def);
2968+
rib.bindings.insert(label.node, def);
29702969
}
29712970

29722971
visit::walk_expr(this, expr);
29732972
})
29742973
}
29752974

29762975
ExprKind::Break(Some(label)) | ExprKind::Continue(Some(label)) => {
2977-
match self.search_label(mtwt::resolve(label.node)) {
2976+
match self.search_label(label.node) {
29782977
None => {
29792978
self.record_def(expr.id, err_path_resolution());
29802979
resolve_error(self,

src/libsyntax/ast.rs

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ use tokenstream::{TokenTree};
2626

2727
use std::fmt;
2828
use std::rc::Rc;
29-
use std::hash::{Hash, Hasher};
3029
use serialize::{Encodable, Decodable, Encoder, Decoder};
3130

3231
/// A name is a part of an identifier, representing a string or gensym. It's
@@ -46,7 +45,7 @@ pub struct SyntaxContext(pub u32);
4645
/// An identifier contains a Name (index into the interner
4746
/// table) and a SyntaxContext to track renaming and
4847
/// macro expansion per Flatt et al., "Macros That Work Together"
49-
#[derive(Clone, Copy, Eq)]
48+
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
5049
pub struct Ident {
5150
pub name: Name,
5251
pub ctxt: SyntaxContext
@@ -93,40 +92,6 @@ impl Ident {
9392
}
9493
}
9594

96-
impl PartialEq for Ident {
97-
fn eq(&self, other: &Ident) -> bool {
98-
if self.ctxt != other.ctxt {
99-
// There's no one true way to compare Idents. They can be compared
100-
// non-hygienically `id1.name == id2.name`, hygienically
101-
// `mtwt::resolve(id1) == mtwt::resolve(id2)`, or even member-wise
102-
// `(id1.name, id1.ctxt) == (id2.name, id2.ctxt)` depending on the situation.
103-
// Ideally, PartialEq should not be implemented for Ident at all, but that
104-
// would be too impractical, because many larger structures (Token, in particular)
105-
// including Idents as their parts derive PartialEq and use it for non-hygienic
106-
// comparisons. That's why PartialEq is implemented and defaults to non-hygienic
107-
// comparison. Hash is implemented too and is consistent with PartialEq, i.e. only
108-
// the name of Ident is hashed. Still try to avoid comparing idents in your code
109-
// (especially as keys in hash maps), use one of the three methods listed above
110-
// explicitly.
111-
//
112-
// If you see this panic, then some idents from different contexts were compared
113-
// non-hygienically. It's likely a bug. Use one of the three comparison methods
114-
// listed above explicitly.
115-
116-
panic!("idents with different contexts are compared with operator `==`: \
117-
{:?}, {:?}.", self, other);
118-
}
119-
120-
self.name == other.name
121-
}
122-
}
123-
124-
impl Hash for Ident {
125-
fn hash<H: Hasher>(&self, state: &mut H) {
126-
self.name.hash(state)
127-
}
128-
}
129-
13095
impl fmt::Debug for Ident {
13196
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
13297
write!(f, "{}#{}", self.name, self.ctxt.0)

src/libsyntax/ext/base.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ use parse::token::{InternedString, intern, str_to_ident};
2626
use ptr::P;
2727
use util::small_vector::SmallVector;
2828
use util::lev_distance::find_best_match_for_name;
29-
use ext::mtwt;
3029
use fold::Folder;
3130

3231
use std::collections::{HashMap, HashSet};
@@ -483,15 +482,12 @@ pub type NamedSyntaxExtension = (Name, SyntaxExtension);
483482
pub struct BlockInfo {
484483
/// Should macros escape from this scope?
485484
pub macros_escape: bool,
486-
/// What are the pending renames?
487-
pub pending_renames: mtwt::RenameList,
488485
}
489486

490487
impl BlockInfo {
491488
pub fn new() -> BlockInfo {
492489
BlockInfo {
493490
macros_escape: false,
494-
pending_renames: Vec::new(),
495491
}
496492
}
497493
}

0 commit comments

Comments
 (0)