Skip to content

Commit cc17b1b

Browse files
committed
Add Symbol::{with,with2}.
And remove the `unsafe` blocks, they're not necessary. Also rewrite `InternedString::{with,with2}` to use the new functions. Finally, add some comments about the speed of the `as_str()`/`as_interned_str()` functions.
1 parent 7a1bc79 commit cc17b1b

File tree

1 file changed

+29
-13
lines changed

1 file changed

+29
-13
lines changed

src/libsyntax_pos/symbol.rs

+29-13
Original file line numberDiff line numberDiff line change
@@ -818,10 +818,14 @@ impl Ident {
818818
with_interner(|interner| interner.is_gensymed(self.name))
819819
}
820820

821+
/// Convert the name to a `LocalInternedString`. This is a slowish
822+
/// operation because it requires locking the symbol interner.
821823
pub fn as_str(self) -> LocalInternedString {
822824
self.name.as_str()
823825
}
824826

827+
/// Convert the name to an `InternedString`. This is a slowish operation
828+
/// because it requires locking the symbol interner.
825829
pub fn as_interned_str(self) -> InternedString {
826830
self.name.as_interned_str()
827831
}
@@ -916,6 +920,25 @@ impl Symbol {
916920
with_interner(|interner| interner.intern(string))
917921
}
918922

923+
/// Access the symbol's chars. This is a slowish operation because it
924+
/// requires locking the symbol interner.
925+
pub fn with<F: FnOnce(&str) -> R, R>(self, f: F) -> R {
926+
with_interner(|interner| {
927+
f(interner.get(self))
928+
})
929+
}
930+
931+
/// Access two symbols' chars. This is a slowish operation because it
932+
/// requires locking the symbol interner, but it is faster than calling
933+
/// `with()` twice.
934+
fn with2<F: FnOnce(&str, &str) -> R, R>(self, other: Symbol, f: F) -> R {
935+
with_interner(|interner| {
936+
f(interner.get(self), interner.get(other))
937+
})
938+
}
939+
940+
/// Convert to a `LocalInternedString`. This is a slowish operation because
941+
/// it requires locking the symbol interner.
919942
pub fn as_str(self) -> LocalInternedString {
920943
with_interner(|interner| unsafe {
921944
LocalInternedString {
@@ -924,6 +947,8 @@ impl Symbol {
924947
})
925948
}
926949

950+
/// Convert to an `InternedString`. This is a slowish operation because it
951+
/// requires locking the symbol interner.
927952
pub fn as_interned_str(self) -> InternedString {
928953
with_interner(|interner| InternedString {
929954
symbol: interner.interned(self)
@@ -1245,28 +1270,19 @@ impl InternedString {
12451270
}
12461271

12471272
pub fn with<F: FnOnce(&str) -> R, R>(self, f: F) -> R {
1248-
let str = with_interner(|interner| {
1249-
interner.get(self.symbol) as *const str
1250-
});
1251-
// This is safe because the interner keeps string alive until it is dropped.
1252-
// We can access it because we know the interner is still alive since we use a
1253-
// scoped thread local to access it, and it was alive at the beginning of this scope
1254-
unsafe { f(&*str) }
1273+
self.symbol.with(f)
12551274
}
12561275

12571276
fn with2<F: FnOnce(&str, &str) -> R, R>(self, other: &InternedString, f: F) -> R {
1258-
let (self_str, other_str) = with_interner(|interner| {
1259-
(interner.get(self.symbol) as *const str,
1260-
interner.get(other.symbol) as *const str)
1261-
});
1262-
// This is safe for the same reason that `with` is safe.
1263-
unsafe { f(&*self_str, &*other_str) }
1277+
self.symbol.with2(other.symbol, f)
12641278
}
12651279

12661280
pub fn as_symbol(self) -> Symbol {
12671281
self.symbol
12681282
}
12691283

1284+
/// Convert to a `LocalInternedString`. This is a slowish operation because it
1285+
/// requires locking the symbol interner.
12701286
pub fn as_str(self) -> LocalInternedString {
12711287
self.symbol.as_str()
12721288
}

0 commit comments

Comments
 (0)