diff options
| author | bors <bors@rust-lang.org> | 2018-05-12 18:45:00 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-05-12 18:45:00 +0000 |
| commit | ff2ac35db93a80b2de5daa4f280bf1503d62c164 (patch) | |
| tree | d267bc43ba84346d4592ed77f5d2a7084d299304 /src/libsyntax_pos | |
| parent | c0cea750a0a10a0ed5a101839e37968d87f8ef9d (diff) | |
| parent | da79ff3cc2265514483d2a5e1f4238c85baa70e9 (diff) | |
Auto merge of #50686 - Mark-Simulacrum:rollup, r=Mark-Simulacrum
Rollup of 13 pull requests Successful merges: - #50544 (Cleanup some dependencies) - #50545 (Made some functions in time module const) - #50550 (use fmt::Result where applicable) - #50558 (Remove all reference to DepGraph::work_products) - #50602 (Update canonicalize docs) - #50607 (Allocate Symbol strings from an arena) - #50613 (Migrate the toolstate update bot to rust-highfive) - #50624 (fs::write: Add example writing a &str) - #50634 (Do not silently truncate offsets for `read_at`/`write_at` on emscripten) - #50644 (AppVeyor: Read back trace from crash dump on failure.) - #50661 (Ignore non .rs files for tidy libcoretest) - #50663 (rustc: Allow an edition's feature on that edition) - #50667 (rustc: Only suggest deleting `extern crate` if it works) Failed merges:
Diffstat (limited to 'src/libsyntax_pos')
| -rw-r--r-- | src/libsyntax_pos/Cargo.toml | 1 | ||||
| -rw-r--r-- | src/libsyntax_pos/lib.rs | 1 | ||||
| -rw-r--r-- | src/libsyntax_pos/symbol.rs | 40 |
3 files changed, 34 insertions, 8 deletions
diff --git a/src/libsyntax_pos/Cargo.toml b/src/libsyntax_pos/Cargo.toml index b9637b1855e..a9147b394f7 100644 --- a/src/libsyntax_pos/Cargo.toml +++ b/src/libsyntax_pos/Cargo.toml @@ -11,5 +11,6 @@ crate-type = ["dylib"] [dependencies] serialize = { path = "../libserialize" } rustc_data_structures = { path = "../librustc_data_structures" } +arena = { path = "../libarena" } scoped-tls = { version = "0.1.1", features = ["nightly"] } unicode-width = "0.1.4" diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 8b4a3ea26a1..d30d3d78ca5 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -35,6 +35,7 @@ use std::path::PathBuf; use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::sync::{Lrc, Lock}; +extern crate arena; extern crate rustc_data_structures; #[macro_use] diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 4a8b1e8b1c1..b84ff5697a4 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -16,8 +16,10 @@ use hygiene::SyntaxContext; use {Span, DUMMY_SP, GLOBALS}; use rustc_data_structures::fx::FxHashMap; +use arena::DroplessArena; use serialize::{Decodable, Decoder, Encodable, Encoder}; use std::fmt; +use std::str; use std::cmp::{PartialEq, Ordering, PartialOrd, Ord}; use std::hash::{Hash, Hasher}; @@ -198,22 +200,35 @@ impl<T: ::std::ops::Deref<Target=str>> PartialEq<T> for Symbol { } } -#[derive(Default)] +// The &'static strs in this type actually point into the arena pub struct Interner { - names: FxHashMap<Box<str>, Symbol>, - strings: Vec<Box<str>>, + arena: DroplessArena, + names: FxHashMap<&'static str, Symbol>, + strings: Vec<&'static str>, gensyms: Vec<Symbol>, } impl Interner { pub fn new() -> Self { - Interner::default() + Interner { + arena: DroplessArena::new(), + names: Default::default(), + strings: Default::default(), + gensyms: Default::default(), + } } fn prefill(init: &[&str]) -> Self { let mut this = Interner::new(); for &string in init { - this.intern(string); + if string == "" { + // We can't allocate empty strings in the arena, so handle this here + let name = Symbol(this.strings.len() as u32); + this.names.insert("", name); + this.strings.push(""); + } else { + this.intern(string); + } } this } @@ -224,8 +239,17 @@ impl Interner { } let name = Symbol(self.strings.len() as u32); - let string = string.to_string().into_boxed_str(); - self.strings.push(string.clone()); + + // from_utf8_unchecked is safe since we just allocated a &str which is known to be utf8 + let string: &str = unsafe { + str::from_utf8_unchecked(self.arena.alloc_slice(string.as_bytes())) + }; + // It is safe to extend the arena allocation to 'static because we only access + // these while the arena is still alive + let string: &'static str = unsafe { + &*(string as *const str) + }; + self.strings.push(string); self.names.insert(string, name); name } @@ -254,7 +278,7 @@ impl Interner { pub fn get(&self, symbol: Symbol) -> &str { match self.strings.get(symbol.0 as usize) { - Some(ref string) => string, + Some(string) => string, None => self.get(self.gensyms[(!0 - symbol.0) as usize]), } } |
