diff options
| author | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-07-11 20:00:07 +0000 |
|---|---|---|
| committer | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-07-11 22:25:08 +0000 |
| commit | 060b5c5ef273a6b74ccbd10c1d4a1debfa27d9de (patch) | |
| tree | 63c0862d64c7c01fe52a02099e816f644e11aa02 /src/libsyntax/util | |
| parent | 752d4419a060e007548cf56f85ff864a13589567 (diff) | |
| download | rust-060b5c5ef273a6b74ccbd10c1d4a1debfa27d9de.tar.gz rust-060b5c5ef273a6b74ccbd10c1d4a1debfa27d9de.zip | |
Factor the `RefCell` out of the `Interner`.
Diffstat (limited to 'src/libsyntax/util')
| -rw-r--r-- | src/libsyntax/util/interner.rs | 94 |
1 files changed, 34 insertions, 60 deletions
diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index 2dd69c76958..6bb409715aa 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -15,7 +15,6 @@ use ast::Name; use std::borrow::Borrow; -use std::cell::RefCell; use std::collections::HashMap; use std::rc::Rc; @@ -28,85 +27,60 @@ impl Borrow<str> for RcStr { } } +#[derive(Default)] pub struct Interner { - map: RefCell<HashMap<RcStr, Name>>, - vect: RefCell<Vec<Rc<String>> >, + names: HashMap<RcStr, Name>, + strings: Vec<Rc<String>>, } /// When traits can extend traits, we should extend index<Name,T> to get [] impl Interner { pub fn new() -> Self { - Interner { - map: RefCell::new(HashMap::new()), - vect: RefCell::new(Vec::new()), - } + Interner::default() } pub fn prefill(init: &[&str]) -> Self { - let rv = Interner::new(); - for &v in init { rv.intern(v); } - rv - } - - pub fn intern<T: Borrow<str> + Into<String>>(&self, val: T) -> Name { - let mut map = self.map.borrow_mut(); - if let Some(&idx) = map.get(val.borrow()) { - return idx; + let mut this = Interner::new(); + for &string in init { + this.intern(string); } - - let new_idx = Name(self.len() as u32); - let val = Rc::new(val.into()); - map.insert(RcStr(val.clone()), new_idx); - self.vect.borrow_mut().push(val); - new_idx + this } - pub fn gensym(&self, val: &str) -> Name { - let new_idx = Name(self.len() as u32); - // leave out of .map to avoid colliding - self.vect.borrow_mut().push(Rc::new(val.to_owned())); - new_idx - } - - // I want these gensyms to share name pointers - // with existing entries. This would be automatic, - // except that the existing gensym creates its - // own managed ptr using to_managed. I think that - // adding this utility function is the most - // lightweight way to get what I want, though not - // necessarily the cleanest. - - /// Create a gensym with the same name as an existing - /// entry. - pub fn gensym_copy(&self, idx : Name) -> Name { - let new_idx = Name(self.len() as u32); - // leave out of map to avoid colliding - let mut vect = self.vect.borrow_mut(); - let existing = (*vect)[idx.0 as usize].clone(); - vect.push(existing); - new_idx - } + pub fn intern<T: Borrow<str> + Into<String>>(&mut self, string: T) -> Name { + if let Some(&name) = self.names.get(string.borrow()) { + return name; + } - pub fn get(&self, idx: Name) -> Rc<String> { - (*self.vect.borrow())[idx.0 as usize].clone() + let name = Name(self.strings.len() as u32); + let string = Rc::new(string.into()); + self.strings.push(string.clone()); + self.names.insert(RcStr(string), name); + name } - pub fn len(&self) -> usize { - self.vect.borrow().len() + pub fn gensym(&mut self, string: &str) -> Name { + let gensym = Name(self.strings.len() as u32); + // leave out of `names` to avoid colliding + self.strings.push(Rc::new(string.to_owned())); + gensym } - pub fn find(&self, val: &str) -> Option<Name> { - self.map.borrow().get(val).cloned() + /// Create a gensym with the same name as an existing entry. + pub fn gensym_copy(&mut self, name: Name) -> Name { + let gensym = Name(self.strings.len() as u32); + // leave out of `names` to avoid colliding + let string = self.strings[name.0 as usize].clone(); + self.strings.push(string); + gensym } - pub fn clear(&self) { - *self.map.borrow_mut() = HashMap::new(); - *self.vect.borrow_mut() = Vec::new(); + pub fn get(&self, name: Name) -> Rc<String> { + self.strings[name.0 as usize].clone() } - pub fn reset(&self, other: Interner) { - *self.map.borrow_mut() = other.map.into_inner(); - *self.vect.borrow_mut() = other.vect.into_inner(); + pub fn find(&self, string: &str) -> Option<Name> { + self.names.get(string).cloned() } } @@ -117,7 +91,7 @@ mod tests { #[test] fn interner_tests() { - let i : Interner = Interner::new(); + let mut i: Interner = Interner::new(); // first one is zero: assert_eq!(i.intern("dog"), Name(0)); // re-use gets the same entry: |
