Auto merge of #91957 - nnethercote:rm-SymbolStr, r=oli-obk
Remove `SymbolStr` This was originally proposed in https://github.com/rust-lang/rust/pull/74554#discussion_r466203544. As well as removing the icky `SymbolStr` type, it allows the removal of a lot of `&` and `*` occurrences. Best reviewed one commit at a time. r? `@oli-obk`
This commit is contained in:
commit
a41a6925ba
140 changed files with 354 additions and 415 deletions
|
@ -55,7 +55,7 @@ pub fn find_best_match_for_name(
|
|||
lookup: Symbol,
|
||||
dist: Option<usize>,
|
||||
) -> Option<Symbol> {
|
||||
let lookup = &lookup.as_str();
|
||||
let lookup = lookup.as_str();
|
||||
let max_dist = dist.unwrap_or_else(|| cmp::max(lookup.len(), 3) / 3);
|
||||
|
||||
// Priority of matches:
|
||||
|
@ -70,7 +70,7 @@ pub fn find_best_match_for_name(
|
|||
let levenshtein_match = name_vec
|
||||
.iter()
|
||||
.filter_map(|&name| {
|
||||
let dist = lev_distance(lookup, &name.as_str());
|
||||
let dist = lev_distance(lookup, name.as_str());
|
||||
if dist <= max_dist { Some((name, dist)) } else { None }
|
||||
})
|
||||
// Here we are collecting the next structure:
|
||||
|
@ -88,7 +88,7 @@ pub fn find_best_match_for_name(
|
|||
|
||||
fn find_match_by_sorted_words(iter_names: &[Symbol], lookup: &str) -> Option<Symbol> {
|
||||
iter_names.iter().fold(None, |result, candidate| {
|
||||
if sort_by_words(&candidate.as_str()) == sort_by_words(lookup) {
|
||||
if sort_by_words(candidate.as_str()) == sort_by_words(lookup) {
|
||||
Some(*candidate)
|
||||
} else {
|
||||
result
|
||||
|
|
|
@ -1512,9 +1512,12 @@ impl Ident {
|
|||
Ident::new(self.name, self.span.normalize_to_macro_rules())
|
||||
}
|
||||
|
||||
/// Convert the name to a `SymbolStr`. This is a slowish operation because
|
||||
/// it requires locking the symbol interner.
|
||||
pub fn as_str(self) -> SymbolStr {
|
||||
/// Access the underlying string. This is a slowish operation because it
|
||||
/// requires locking the symbol interner.
|
||||
///
|
||||
/// Note that the lifetime of the return value is a lie. See
|
||||
/// `Symbol::as_str()` for details.
|
||||
pub fn as_str(&self) -> &str {
|
||||
self.name.as_str()
|
||||
}
|
||||
}
|
||||
|
@ -1650,12 +1653,17 @@ impl Symbol {
|
|||
with_session_globals(|session_globals| session_globals.symbol_interner.intern(string))
|
||||
}
|
||||
|
||||
/// Convert to a `SymbolStr`. This is a slowish operation because it
|
||||
/// Access the underlying string. This is a slowish operation because it
|
||||
/// requires locking the symbol interner.
|
||||
pub fn as_str(self) -> SymbolStr {
|
||||
with_session_globals(|session_globals| {
|
||||
let symbol_str = session_globals.symbol_interner.get(self);
|
||||
unsafe { SymbolStr { string: std::mem::transmute::<&str, &str>(symbol_str) } }
|
||||
///
|
||||
/// Note that the lifetime of the return value is a lie. It's not the same
|
||||
/// as `&self`, but actually tied to the lifetime of the underlying
|
||||
/// interner. Interners are long-lived, and there are very few of them, and
|
||||
/// this function is typically used for short-lived things, so in practice
|
||||
/// it works out ok.
|
||||
pub fn as_str(&self) -> &str {
|
||||
with_session_globals(|session_globals| unsafe {
|
||||
std::mem::transmute::<&str, &str>(session_globals.symbol_interner.get(*self))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1678,19 +1686,19 @@ impl Symbol {
|
|||
|
||||
impl fmt::Debug for Symbol {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Debug::fmt(&self.as_str(), f)
|
||||
fmt::Debug::fmt(self.as_str(), f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Symbol {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Display::fmt(&self.as_str(), f)
|
||||
fmt::Display::fmt(self.as_str(), f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Encoder> Encodable<S> for Symbol {
|
||||
fn encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
s.emit_str(&self.as_str())
|
||||
s.emit_str(self.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1709,11 +1717,10 @@ impl<CTX> HashStable<CTX> for Symbol {
|
|||
}
|
||||
|
||||
impl<CTX> ToStableHashKey<CTX> for Symbol {
|
||||
type KeyType = SymbolStr;
|
||||
|
||||
type KeyType = String;
|
||||
#[inline]
|
||||
fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
|
||||
self.as_str()
|
||||
fn to_stable_hash_key(&self, _: &CTX) -> String {
|
||||
self.as_str().to_string()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1905,70 +1912,3 @@ impl Ident {
|
|||
self.name.can_be_raw() && self.is_reserved()
|
||||
}
|
||||
}
|
||||
|
||||
/// An alternative to [`Symbol`], useful when the chars within the symbol need to
|
||||
/// be accessed. It deliberately has limited functionality and should only be
|
||||
/// used for temporary values.
|
||||
///
|
||||
/// Because the interner outlives any thread which uses this type, we can
|
||||
/// safely treat `string` which points to interner data, as an immortal string,
|
||||
/// as long as this type never crosses between threads.
|
||||
//
|
||||
// FIXME: ensure that the interner outlives any thread which uses `SymbolStr`,
|
||||
// by creating a new thread right after constructing the interner.
|
||||
#[derive(Clone, Eq, PartialOrd, Ord)]
|
||||
pub struct SymbolStr {
|
||||
string: &'static str,
|
||||
}
|
||||
|
||||
// This impl allows a `SymbolStr` to be directly equated with a `String` or
|
||||
// `&str`.
|
||||
impl<T: std::ops::Deref<Target = str>> std::cmp::PartialEq<T> for SymbolStr {
|
||||
fn eq(&self, other: &T) -> bool {
|
||||
self.string == other.deref()
|
||||
}
|
||||
}
|
||||
|
||||
impl !Send for SymbolStr {}
|
||||
impl !Sync for SymbolStr {}
|
||||
|
||||
/// This impl means that if `ss` is a `SymbolStr`:
|
||||
/// - `*ss` is a `str`;
|
||||
/// - `&*ss` is a `&str` (and `match &*ss { ... }` is a common pattern).
|
||||
/// - `&ss as &str` is a `&str`, which means that `&ss` can be passed to a
|
||||
/// function expecting a `&str`.
|
||||
impl std::ops::Deref for SymbolStr {
|
||||
type Target = str;
|
||||
#[inline]
|
||||
fn deref(&self) -> &str {
|
||||
self.string
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for SymbolStr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Debug::fmt(self.string, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for SymbolStr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Display::fmt(self.string, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<CTX> HashStable<CTX> for SymbolStr {
|
||||
#[inline]
|
||||
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
|
||||
self.string.hash_stable(hcx, hasher)
|
||||
}
|
||||
}
|
||||
|
||||
impl<CTX> ToStableHashKey<CTX> for SymbolStr {
|
||||
type KeyType = SymbolStr;
|
||||
|
||||
#[inline]
|
||||
fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue