Skip to content

Commit 26bfc7d

Browse files
committed
add unsafe
1 parent ad26b89 commit 26bfc7d

File tree

2 files changed

+31
-14
lines changed

2 files changed

+31
-14
lines changed

src/cargo/core/interning.rs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,51 @@
11
use std::fmt;
22
use std::sync::RwLock;
3-
use std::collections::HashMap;
3+
use std::collections::HashSet;
4+
use std::slice;
5+
use std::str;
6+
use std::mem;
7+
8+
pub fn leek(s: String) -> &'static str {
9+
let ptr = s.as_ptr();
10+
let len = s.len();
11+
mem::forget(s);
12+
unsafe {
13+
let slice = slice::from_raw_parts(ptr, len);
14+
str::from_utf8_unchecked(slice)
15+
}
16+
}
417

518
lazy_static! {
6-
static ref STRING_CASHE: RwLock<(Vec<String>, HashMap<String, usize>)> =
7-
RwLock::new((Vec::new(), HashMap::new()));
19+
static ref STRING_CASHE: RwLock<HashSet<&'static str>> =
20+
RwLock::new(HashSet::new());
821
}
922

1023
#[derive(Eq, PartialEq, Hash, Clone, Copy)]
1124
pub struct InternedString {
12-
id: usize
25+
ptr: *const u8,
26+
len: usize,
1327
}
1428

1529
impl InternedString {
1630
pub fn new(str: &str) -> InternedString {
17-
let (ref mut str_from_id, ref mut id_from_str) = *STRING_CASHE.write().unwrap();
18-
if let Some(&id) = id_from_str.get(str) {
19-
return InternedString { id };
31+
let mut cache = STRING_CASHE.write().unwrap();
32+
if let Some(&s) = cache.get(str) {
33+
return InternedString { ptr: s.as_ptr(), len: s.len() };
2034
}
21-
str_from_id.push(str.to_string());
22-
id_from_str.insert(str.to_string(), str_from_id.len() - 1);
23-
return InternedString { id: str_from_id.len() - 1 }
35+
let s = leek(str.to_string());
36+
cache.insert(s);
37+
InternedString { ptr: s.as_ptr(), len: s.len() }
2438
}
25-
pub fn to_inner(&self) -> String {
26-
STRING_CASHE.read().unwrap().0[self.id].to_string()
39+
pub fn to_inner(&self) -> &'static str {
40+
unsafe {
41+
let slice = slice::from_raw_parts(self.ptr, self.len);
42+
str::from_utf8_unchecked(slice)
43+
}
2744
}
2845
}
2946

3047
impl fmt::Debug for InternedString {
3148
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
32-
write!(f, "InternedString {{ {} }}", STRING_CASHE.read().unwrap().0[self.id])
49+
write!(f, "InternedString {{ {} }}", self.to_inner())
3350
}
3451
}

src/cargo/core/resolver/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ pub fn resolve(summaries: &[(Summary, Method)],
371371
metadata: BTreeMap::new(),
372372
replacements: cx.resolve_replacements(),
373373
features: cx.resolve_features.iter().map(|(k, v)| {
374-
(k.clone(), v.iter().map(|x| x.to_inner()).collect())
374+
(k.clone(), v.iter().map(|x| x.to_inner().to_string()).collect())
375375
}).collect(),
376376
unused_patches: Vec::new(),
377377
};

0 commit comments

Comments
 (0)