about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-11-19 05:55:28 +0000
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-11-21 09:00:56 +0000
commitcc74068642d288534df0d6c2a454663920c5e97d (patch)
treef4e7aceb006421c4733f8ed8c40a5e734b4af0f6 /src/libsyntax
parent36c8f6b0d3f38904459f40496af36d36e9cc0fac (diff)
Remove `Rc` from the interner.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/lib.rs1
-rw-r--r--src/libsyntax/symbol.rs39
2 files changed, 22 insertions, 18 deletions
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 15b93a4864b..5a1b0d4005e 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -27,6 +27,7 @@
 #![feature(associated_consts)]
 #![feature(const_fn)]
 #![feature(libc)]
+#![feature(optin_builtin_traits)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
 #![feature(str_escape)]
diff --git a/src/libsyntax/symbol.rs b/src/libsyntax/symbol.rs
index f7217b9535f..fe9a176179c 100644
--- a/src/libsyntax/symbol.rs
+++ b/src/libsyntax/symbol.rs
@@ -16,12 +16,14 @@ use serialize::{Decodable, Decoder, Encodable, Encoder};
 use std::cell::RefCell;
 use std::collections::HashMap;
 use std::fmt;
-use std::rc::Rc;
 
 /// A symbol is an interned or gensymed string.
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub struct Symbol(u32);
 
+// The interner in thread-local, so `Symbol` shouldn't move between threads.
+impl !Send for Symbol { }
+
 impl Symbol {
     /// Maps a string to its interned representation.
     pub fn intern(string: &str) -> Self {
@@ -34,7 +36,11 @@ impl Symbol {
     }
 
     pub fn as_str(self) -> InternedString {
-        with_interner(|interner| InternedString { string: interner.get(self) })
+        with_interner(|interner| unsafe {
+            InternedString {
+                string: ::std::mem::transmute::<&str, &str>(interner.get(self))
+            }
+        })
     }
 
     pub fn as_u32(self) -> u32 {
@@ -74,8 +80,8 @@ impl<'a> PartialEq<&'a str> for Symbol {
 
 #[derive(Default)]
 pub struct Interner {
-    names: HashMap<Rc<str>, Symbol>,
-    strings: Vec<Rc<str>>,
+    names: HashMap<Box<str>, Symbol>,
+    strings: Vec<Box<str>>,
 }
 
 impl Interner {
@@ -97,7 +103,7 @@ impl Interner {
         }
 
         let name = Symbol(self.strings.len() as u32);
-        let string = Rc::__from_str(string);
+        let string = string.to_string().into_boxed_str();
         self.strings.push(string.clone());
         self.names.insert(string, name);
         name
@@ -106,12 +112,12 @@ impl Interner {
     fn gensym(&mut self, string: &str) -> Symbol {
         let gensym = Symbol(self.strings.len() as u32);
         // leave out of `names` to avoid colliding
-        self.strings.push(Rc::__from_str(string));
+        self.strings.push(string.to_string().into_boxed_str());
         gensym
     }
 
-    pub fn get(&self, name: Symbol) -> Rc<str> {
-        self.strings[name.0 as usize].clone()
+    pub fn get(&self, name: Symbol) -> &str {
+        &self.strings[name.0 as usize]
     }
 }
 
@@ -225,11 +231,6 @@ fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
     INTERNER.with(|interner| f(&mut *interner.borrow_mut()))
 }
 
-/// Reset the ident interner to its initial state.
-pub fn reset_interner() {
-    with_interner(|interner| *interner = Interner::fresh());
-}
-
 /// Represents a string stored in the thread-local interner. Because the
 /// interner lives for the life of the thread, this can be safely treated as an
 /// immortal string, as long as it never crosses between threads.
@@ -241,23 +242,25 @@ pub fn reset_interner() {
 /// somehow.
 #[derive(Clone, PartialEq, Hash, PartialOrd, Eq, Ord)]
 pub struct InternedString {
-    string: Rc<str>,
+    string: &'static str,
 }
 
+impl !Send for InternedString { }
+
 impl ::std::ops::Deref for InternedString {
     type Target = str;
-    fn deref(&self) -> &str { &self.string }
+    fn deref(&self) -> &str { self.string }
 }
 
 impl fmt::Debug for InternedString {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Debug::fmt(&self.string, f)
+        fmt::Debug::fmt(self.string, f)
     }
 }
 
 impl fmt::Display for InternedString {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Display::fmt(&self.string, f)
+        fmt::Display::fmt(self.string, f)
     }
 }
 
@@ -269,7 +272,7 @@ impl Decodable for InternedString {
 
 impl Encodable for InternedString {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        s.emit_str(&self.string)
+        s.emit_str(self.string)
     }
 }