From 1eb6d0b485acc5f6e0d9f9b0946000bce12f5bfc Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Mon, 11 Jul 2016 08:00:48 +0000 Subject: [PATCH] Remove `Interner` and rename `StrInterner` to `Interner`. --- src/librustc_metadata/decoder.rs | 4 +- src/librustc_trans/debuginfo/metadata.rs | 6 +- src/libsyntax/parse/token.rs | 6 +- src/libsyntax/util/interner.rs | 149 ++--------------------- 4 files changed, 21 insertions(+), 144 deletions(-) diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 6d3699e9787..6dfd340a3fb 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -450,7 +450,7 @@ fn get_variant_fields<'tcx>(intr: &IdentInterner, struct_field_family_to_visibility(ff)) }).chain(reader::tagged_docs(doc, tag_item_unnamed_field).map(|f| { let ff = item_family(f); - let name = intr.intern(&index.to_string()); + let name = intr.intern(index.to_string()); index += 1; ty::FieldDefData::new(item_def_id(f, cdata), name, struct_field_family_to_visibility(ff)) @@ -1187,7 +1187,7 @@ pub fn get_struct_field_names(intr: &IdentInterner, cdata: Cmd, id: DefIndex) reader::tagged_docs(item, tag_item_field).map(|an_item| { item_name(intr, an_item) }).chain(reader::tagged_docs(item, tag_item_unnamed_field).map(|_| { - let name = intr.intern(&index.to_string()); + let name = intr.intern(index.to_string()); index += 1; name })).collect() diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index b84cc028d0c..46813d957dc 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -81,7 +81,7 @@ // UniqueTypeIds. pub struct TypeMap<'tcx> { // The UniqueTypeIds created so far - unique_id_interner: Interner>, + unique_id_interner: Interner, // A map from UniqueTypeId to debuginfo metadata for that type. This is a 1:1 mapping. unique_id_to_metadata: FnvHashMap, // A map from types to debuginfo metadata. This is a N:1 mapping. @@ -313,7 +313,7 @@ fn get_unique_type_id_of_type<'a>(&mut self, cx: &CrateContext<'a, 'tcx>, // Trim to size before storing permanently unique_type_id.shrink_to_fit(); - let key = self.unique_id_interner.intern(Rc::new(unique_type_id)); + let key = self.unique_id_interner.intern(unique_type_id); self.type_to_unique_id.insert(type_, UniqueTypeId(key)); return UniqueTypeId(key); @@ -383,7 +383,7 @@ fn get_unique_type_id_of_enum_variant<'a>(&mut self, let enum_variant_type_id = format!("{}::{}", &self.get_unique_type_id_as_string(enum_type_id), variant_name); - let interner_key = self.unique_id_interner.intern(Rc::new(enum_variant_type_id)); + let interner_key = self.unique_id_interner.intern(enum_variant_type_id); UniqueTypeId(interner_key) } } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 6ebd2ca6ec1..222cf65b78e 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -17,7 +17,7 @@ use ast::{self, BinOpKind}; use ext::mtwt; use ptr::P; -use util::interner::StrInterner; +use util::interner::Interner; use tokenstream; use serialize::{Decodable, Decoder, Encodable, Encoder}; @@ -396,7 +396,7 @@ impl Keyword { } fn mk_fresh_ident_interner() -> IdentInterner { - StrInterner::prefill(&[$($string,)*]) + Interner::prefill(&[$($string,)*]) } }} @@ -472,7 +472,7 @@ fn mk_fresh_ident_interner() -> IdentInterner { } // looks like we can get rid of this completely... -pub type IdentInterner = StrInterner; +pub type IdentInterner = Interner; // if an interner exists in TLS, return it. Otherwise, prepare a // fresh one. diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index 68dbd6272f4..2dd69c76958 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -17,122 +17,45 @@ use std::borrow::Borrow; use std::cell::RefCell; use std::collections::HashMap; -use std::hash::Hash; use std::rc::Rc; -pub struct Interner { - map: RefCell>, - vect: RefCell >, -} - -// when traits can extend traits, we should extend index to get [] -impl Interner { - pub fn new() -> Interner { - Interner { - map: RefCell::new(HashMap::new()), - vect: RefCell::new(Vec::new()), - } - } - - pub fn prefill(init: &[T]) -> Interner { - let rv = Interner::new(); - for v in init { - rv.intern((*v).clone()); - } - rv - } - - pub fn intern(&self, val: T) -> Name { - let mut map = self.map.borrow_mut(); - if let Some(&idx) = (*map).get(&val) { - return idx; - } - - let mut vect = self.vect.borrow_mut(); - let new_idx = Name((*vect).len() as u32); - (*map).insert(val.clone(), new_idx); - (*vect).push(val); - new_idx - } - - pub fn gensym(&self, val: T) -> Name { - let mut vect = self.vect.borrow_mut(); - let new_idx = Name((*vect).len() as u32); - // leave out of .map to avoid colliding - (*vect).push(val); - new_idx - } - - pub fn get(&self, idx: Name) -> T { - let vect = self.vect.borrow(); - (*vect)[idx.0 as usize].clone() - } - - pub fn len(&self) -> usize { - let vect = self.vect.borrow(); - (*vect).len() - } - - pub fn find(&self, val: &Q) -> Option - where T: Borrow, Q: Eq + Hash { - let map = self.map.borrow(); - match (*map).get(val) { - Some(v) => Some(*v), - None => None, - } - } - - pub fn clear(&self) { - *self.map.borrow_mut() = HashMap::new(); - *self.vect.borrow_mut() = Vec::new(); - } -} - -#[derive(Clone, PartialEq, Eq, Hash, Debug)] +#[derive(PartialEq, Eq, Hash)] struct RcStr(Rc); -impl RcStr { - fn new(string: &str) -> Self { - RcStr(Rc::new(string.to_owned())) - } -} - impl Borrow for RcStr { fn borrow(&self) -> &str { &self.0 } } -/// A StrInterner differs from Interner in that it accepts -/// &str rather than RcStr, resulting in less allocation. -pub struct StrInterner { +pub struct Interner { map: RefCell>, vect: RefCell> >, } /// When traits can extend traits, we should extend index to get [] -impl StrInterner { - pub fn new() -> StrInterner { - StrInterner { +impl Interner { + pub fn new() -> Self { + Interner { map: RefCell::new(HashMap::new()), vect: RefCell::new(Vec::new()), } } - pub fn prefill(init: &[&str]) -> StrInterner { - let rv = StrInterner::new(); + pub fn prefill(init: &[&str]) -> Self { + let rv = Interner::new(); for &v in init { rv.intern(v); } rv } - pub fn intern(&self, val: &str) -> Name { + pub fn intern + Into>(&self, val: T) -> Name { let mut map = self.map.borrow_mut(); - if let Some(&idx) = map.get(val) { + if let Some(&idx) = map.get(val.borrow()) { return idx; } let new_idx = Name(self.len() as u32); - let val = Rc::new(val.to_owned()); + let val = Rc::new(val.into()); map.insert(RcStr(val.clone()), new_idx); self.vect.borrow_mut().push(val); new_idx @@ -181,7 +104,7 @@ pub fn clear(&self) { *self.vect.borrow_mut() = Vec::new(); } - pub fn reset(&self, other: StrInterner) { + pub fn reset(&self, other: Interner) { *self.map.borrow_mut() = other.map.into_inner(); *self.vect.borrow_mut() = other.vect.into_inner(); } @@ -190,57 +113,11 @@ pub fn reset(&self, other: StrInterner) { #[cfg(test)] mod tests { use super::*; - use super::RcStr; use ast::Name; #[test] - #[should_panic] - fn i1 () { - let i : Interner = Interner::new(); - i.get(Name(13)); - } - - #[test] - fn interner_tests () { - let i : Interner = Interner::new(); - // first one is zero: - assert_eq!(i.intern(RcStr::new("dog")), Name(0)); - // re-use gets the same entry: - assert_eq!(i.intern(RcStr::new("dog")), Name(0)); - // different string gets a different #: - assert_eq!(i.intern(RcStr::new("cat")), Name(1)); - assert_eq!(i.intern(RcStr::new("cat")), Name(1)); - // dog is still at zero - assert_eq!(i.intern(RcStr::new("dog")), Name(0)); - // gensym gets 3 - assert_eq!(i.gensym(RcStr::new("zebra") ), Name(2)); - // gensym of same string gets new number : - assert_eq!(i.gensym (RcStr::new("zebra") ), Name(3)); - // gensym of *existing* string gets new number: - assert_eq!(i.gensym(RcStr::new("dog")), Name(4)); - assert_eq!(i.get(Name(0)), RcStr::new("dog")); - assert_eq!(i.get(Name(1)), RcStr::new("cat")); - assert_eq!(i.get(Name(2)), RcStr::new("zebra")); - assert_eq!(i.get(Name(3)), RcStr::new("zebra")); - assert_eq!(i.get(Name(4)), RcStr::new("dog")); - } - - #[test] - fn i3 () { - let i : Interner = Interner::prefill(&[ - RcStr::new("Alan"), - RcStr::new("Bob"), - RcStr::new("Carol") - ]); - assert_eq!(i.get(Name(0)), RcStr::new("Alan")); - assert_eq!(i.get(Name(1)), RcStr::new("Bob")); - assert_eq!(i.get(Name(2)), RcStr::new("Carol")); - assert_eq!(i.intern(RcStr::new("Bob")), Name(1)); - } - - #[test] - fn string_interner_tests() { - let i : StrInterner = StrInterner::new(); + fn interner_tests() { + let i : Interner = Interner::new(); // first one is zero: assert_eq!(i.intern("dog"), Name(0)); // re-use gets the same entry: -- GitLab