Skip to content

Commit 8c5b96f

Browse files
committed
Improve efficiency.
1 parent 50d00ad commit 8c5b96f

File tree

4 files changed

+50
-19
lines changed

4 files changed

+50
-19
lines changed

src/librustc/hir/map/definitions.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,9 @@ impl Definitions {
518518
assert_eq!(index.as_array_index(),
519519
self.def_index_to_node[address_space.index()].len());
520520
self.def_index_to_node[address_space.index()].push(node_id);
521-
self.expansions.insert(index, expansion);
521+
if expansion.is_modern() {
522+
self.expansions.insert(index, expansion);
523+
}
522524

523525
debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id);
524526
self.node_to_def_index.insert(node_id, index);
@@ -536,7 +538,7 @@ impl Definitions {
536538
}
537539

538540
pub fn expansion(&self, index: DefIndex) -> Mark {
539-
self.expansions[&index]
541+
self.expansions.get(&index).cloned().unwrap_or(Mark::root())
540542
}
541543

542544
pub fn macro_def_scope(&self, mark: Mark) -> DefId {

src/librustc/ich/impls_syntax.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ impl_stable_hash_for!(enum ::syntax::ast::FloatTy { F32, F64 });
130130
impl_stable_hash_for!(enum ::syntax::ast::Unsafety { Unsafe, Normal });
131131
impl_stable_hash_for!(enum ::syntax::ast::Constness { Const, NotConst });
132132
impl_stable_hash_for!(enum ::syntax::ast::Defaultness { Default, Final });
133-
impl_stable_hash_for!(struct ::syntax::ast::Lifetime { id, span, name });
133+
impl_stable_hash_for!(struct ::syntax::ast::Lifetime { id, span, ident });
134134
impl_stable_hash_for!(enum ::syntax::ast::StrStyle { Cooked, Raw(pounds) });
135135
impl_stable_hash_for!(enum ::syntax::ast::AttrStyle { Outer, Inner });
136136

src/libsyntax_pos/hygiene.rs

+13-6
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ impl Mark {
8585
})
8686
}
8787

88+
pub fn is_modern(self) -> bool {
89+
HygieneData::with(|data| data.marks[self.0 as usize].modern)
90+
}
91+
8892
pub fn set_modern(self) {
8993
HygieneData::with(|data| data.marks[self.0 as usize].modern = true)
9094
}
@@ -106,7 +110,7 @@ struct HygieneData {
106110
marks: Vec<MarkData>,
107111
syntax_contexts: Vec<SyntaxContextData>,
108112
markings: HashMap<(SyntaxContext, Mark), SyntaxContext>,
109-
idents: HashMap<Symbol, Ident>,
113+
gensym_to_ctxt: HashMap<Symbol, SyntaxContext>,
110114
}
111115

112116
impl HygieneData {
@@ -115,7 +119,7 @@ impl HygieneData {
115119
marks: vec![MarkData::default()],
116120
syntax_contexts: vec![SyntaxContextData::default()],
117121
markings: HashMap::new(),
118-
idents: HashMap::new(),
122+
gensym_to_ctxt: HashMap::new(),
119123
}
120124
}
121125

@@ -354,15 +358,18 @@ impl Decodable for SyntaxContext {
354358
impl Symbol {
355359
pub fn from_ident(ident: Ident) -> Symbol {
356360
HygieneData::with(|data| {
357-
let symbol = Symbol::gensym(&ident.name.as_str());
358-
data.idents.insert(symbol, ident);
359-
symbol
361+
let gensym = ident.name.gensymed();
362+
data.gensym_to_ctxt.insert(gensym, ident.ctxt);
363+
gensym
360364
})
361365
}
362366

363367
pub fn to_ident(self) -> Ident {
364368
HygieneData::with(|data| {
365-
data.idents.get(&self).cloned().unwrap_or(Ident::with_empty_ctxt(self))
369+
match data.gensym_to_ctxt.get(&self) {
370+
Some(&ctxt) => Ident { name: self.interned(), ctxt: ctxt },
371+
None => Ident::with_empty_ctxt(self),
372+
}
366373
})
367374
}
368375
}

src/libsyntax_pos/symbol.rs

+32-10
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,19 @@ impl Symbol {
7777
with_interner(|interner| interner.intern(string))
7878
}
7979

80+
pub fn interned(self) -> Self {
81+
with_interner(|interner| interner.interned(self))
82+
}
83+
8084
/// gensym's a new usize, using the current interner.
8185
pub fn gensym(string: &str) -> Self {
8286
with_interner(|interner| interner.gensym(string))
8387
}
8488

89+
pub fn gensymed(self) -> Self {
90+
with_interner(|interner| interner.gensymed(self))
91+
}
92+
8593
pub fn as_str(self) -> InternedString {
8694
with_interner(|interner| unsafe {
8795
InternedString {
@@ -129,6 +137,7 @@ impl<T: ::std::ops::Deref<Target=str>> PartialEq<T> for Symbol {
129137
pub struct Interner {
130138
names: HashMap<Box<str>, Symbol>,
131139
strings: Vec<Box<str>>,
140+
gensyms: Vec<Symbol>,
132141
}
133142

134143
impl Interner {
@@ -156,15 +165,29 @@ impl Interner {
156165
name
157166
}
158167

168+
pub fn interned(&self, symbol: Symbol) -> Symbol {
169+
if (symbol.0 as usize) < self.strings.len() {
170+
symbol
171+
} else {
172+
self.interned(self.gensyms[(!0 - symbol.0) as usize])
173+
}
174+
}
175+
159176
fn gensym(&mut self, string: &str) -> Symbol {
160-
let gensym = Symbol(self.strings.len() as u32);
161-
// leave out of `names` to avoid colliding
162-
self.strings.push(string.to_string().into_boxed_str());
163-
gensym
177+
let symbol = self.intern(string);
178+
self.gensymed(symbol)
164179
}
165180

166-
pub fn get(&self, name: Symbol) -> &str {
167-
&self.strings[name.0 as usize]
181+
fn gensymed(&mut self, symbol: Symbol) -> Symbol {
182+
self.gensyms.push(symbol);
183+
Symbol(!0 - self.gensyms.len() as u32 + 1)
184+
}
185+
186+
pub fn get(&self, symbol: Symbol) -> &str {
187+
match self.strings.get(symbol.0 as usize) {
188+
Some(ref string) => string,
189+
None => self.get(self.gensyms[(!0 - symbol.0) as usize]),
190+
}
168191
}
169192
}
170193

@@ -379,11 +402,10 @@ mod tests {
379402
assert_eq!(i.intern("cat"), Symbol(1));
380403
// dog is still at zero
381404
assert_eq!(i.intern("dog"), Symbol(0));
382-
// gensym gets 3
383-
assert_eq!(i.gensym("zebra"), Symbol(2));
405+
assert_eq!(i.gensym("zebra"), Symbol(4294967295));
384406
// gensym of same string gets new number :
385-
assert_eq!(i.gensym("zebra"), Symbol(3));
407+
assert_eq!(i.gensym("zebra"), Symbol(4294967294));
386408
// gensym of *existing* string gets new number:
387-
assert_eq!(i.gensym("dog"), Symbol(4));
409+
assert_eq!(i.gensym("dog"), Symbol(4294967293));
388410
}
389411
}

0 commit comments

Comments
 (0)