use std::fmt::Write;
use std::path::Path;
use std::ptr;
-use std::rc::Rc;
use syntax::ast;
use syntax::symbol::{Interner, InternedString};
use syntax_pos::{self, Span};
unique_type_id: UniqueTypeId,
metadata: DIType) {
if self.unique_id_to_metadata.insert(unique_type_id, metadata).is_some() {
- let unique_type_id_str = self.get_unique_type_id_as_string(unique_type_id);
bug!("Type metadata for unique id '{}' is already in the TypeMap!",
- &unique_type_id_str[..]);
+ self.get_unique_type_id_as_string(unique_type_id));
}
}
// Get the string representation of a UniqueTypeId. This method will fail if
// the id is unknown.
- fn get_unique_type_id_as_string(&self, unique_type_id: UniqueTypeId) -> Rc<str> {
+ fn get_unique_type_id_as_string(&self, unique_type_id: UniqueTypeId) -> &str {
let UniqueTypeId(interner_key) = unique_type_id;
self.unique_id_interner.get(interner_key)
}
-> UniqueTypeId {
let enum_type_id = self.get_unique_type_id_of_type(cx, enum_type);
let enum_variant_type_id = format!("{}::{}",
- &self.get_unique_type_id_as_string(enum_type_id),
+ self.get_unique_type_id_as_string(enum_type_id),
variant_name);
let interner_key = self.unique_id_interner.intern(&enum_variant_type_id);
UniqueTypeId(interner_key)
let metadata_for_uid = match type_map.find_metadata_for_unique_id(unique_type_id) {
Some(metadata) => metadata,
None => {
- let unique_type_id_str =
- type_map.get_unique_type_id_as_string(unique_type_id);
span_bug!(usage_site_span,
"Expected type metadata for unique \
type id '{}' to already be in \
the debuginfo::TypeMap but it \
was not. (Ty = {})",
- &unique_type_id_str[..],
+ type_map.get_unique_type_id_as_string(unique_type_id),
t);
}
};
match type_map.find_metadata_for_type(t) {
Some(metadata) => {
if metadata != metadata_for_uid {
- let unique_type_id_str =
- type_map.get_unique_type_id_as_string(unique_type_id);
span_bug!(usage_site_span,
"Mismatch between Ty and \
UniqueTypeId maps in \
debuginfo::TypeMap. \
UniqueTypeId={}, Ty={}",
- &unique_type_id_str[..],
+ type_map.get_unique_type_id_as_string(unique_type_id),
t);
}
}
let enum_llvm_type = type_of::type_of(cx, enum_type);
let (enum_type_size, enum_type_align) = size_and_align_of(cx, enum_llvm_type);
- let unique_type_id_str = debug_context(cx)
- .type_map
- .borrow()
- .get_unique_type_id_as_string(unique_type_id);
-
let enum_name = CString::new(enum_name).unwrap();
- let unique_type_id_str = CString::new(unique_type_id_str.as_bytes()).unwrap();
+ let unique_type_id_str = CString::new(
+ debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id).as_bytes()
+ ).unwrap();
let enum_metadata = unsafe {
llvm::LLVMRustDIBuilderCreateUnionType(
DIB(cx),
-> DICompositeType {
let (struct_size, struct_align) = size_and_align_of(cx, struct_llvm_type);
- let unique_type_id_str = debug_context(cx).type_map
- .borrow()
- .get_unique_type_id_as_string(unique_type_id);
let name = CString::new(struct_type_name).unwrap();
- let unique_type_id = CString::new(unique_type_id_str.as_bytes()).unwrap();
+ let unique_type_id = CString::new(
+ debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id).as_bytes()
+ ).unwrap();
let metadata_stub = unsafe {
// LLVMRustDIBuilderCreateStructType() wants an empty array. A null
// pointer will lead to hard to trace and debug LLVM assertions
-> DICompositeType {
let (union_size, union_align) = size_and_align_of(cx, union_llvm_type);
- let unique_type_id_str = debug_context(cx).type_map
- .borrow()
- .get_unique_type_id_as_string(unique_type_id);
let name = CString::new(union_type_name).unwrap();
- let unique_type_id = CString::new(unique_type_id_str.as_bytes()).unwrap();
+ let unique_type_id = CString::new(
+ debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id).as_bytes()
+ ).unwrap();
let metadata_stub = unsafe {
// LLVMRustDIBuilderCreateUnionType() wants an empty array. A null
// pointer will lead to hard to trace and debug LLVM assertions
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 {
}
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 {
#[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 {
}
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
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]
}
}
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.
/// 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)
}
}
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)
}
}