about summary refs log tree commit diff
path: root/src/libsyntax/util
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-07-11 20:00:07 +0000
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-07-11 22:25:08 +0000
commit060b5c5ef273a6b74ccbd10c1d4a1debfa27d9de (patch)
tree63c0862d64c7c01fe52a02099e816f644e11aa02 /src/libsyntax/util
parent752d4419a060e007548cf56f85ff864a13589567 (diff)
downloadrust-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.rs94
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: