Skip to content

Commit 0a597bd

Browse files
committed
Remove CowBoxSymStr.
`CowBoxSymStr` is a type that either holds a `SymbolStr` (which is much the same as a `Symbol`), or an owned string. When computing skeletons, a `SymbolStr` is stored if the skeleton is the same as the original string, otherwise an owned string is stored. So, basically, `CowBoxSymStr` is a type for string interning. But we already have one of those: `Symbol` itself. This PR removes `CowBoxSymStr`, using `Symbol` instead. A good thing about this is that it avoids storing `SymbolStr` values in `skeleton_map`, something that is discouraged. The PR also inlines and removes the `calc_skeleton()` function because that simplifies the code.
1 parent 75b67c2 commit 0a597bd

File tree

1 file changed

+23
-61
lines changed

1 file changed

+23
-61
lines changed

src/librustc_lint/non_ascii_idents.rs

+23-61
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{EarlyContext, EarlyLintPass, LintContext};
22
use rustc_ast::ast;
33
use rustc_data_structures::fx::FxHashMap;
4-
use rustc_span::symbol::SymbolStr;
4+
use rustc_span::symbol::Symbol;
55

66
declare_lint! {
77
pub NON_ASCII_IDENTS,
@@ -39,7 +39,6 @@ impl EarlyLintPass for NonAsciiIdents {
3939
use rustc_span::Span;
4040
use std::collections::BTreeMap;
4141
use unicode_security::GeneralSecurityProfile;
42-
use utils::CowBoxSymStr;
4342

4443
let check_non_ascii_idents = cx.builder.lint_level(NON_ASCII_IDENTS).0 != Level::Allow;
4544
let check_uncommon_codepoints =
@@ -83,33 +82,34 @@ impl EarlyLintPass for NonAsciiIdents {
8382
}
8483

8584
if has_non_ascii_idents && check_confusable_idents {
86-
let mut skeleton_map: FxHashMap<CowBoxSymStr, (SymbolStr, Span, bool)> =
85+
let mut skeleton_map: FxHashMap<Symbol, (Symbol, Span, bool)> =
8786
FxHashMap::with_capacity_and_hasher(symbols.len(), Default::default());
88-
let mut str_buf = String::new();
89-
for (symbol, &sp) in symbols.iter() {
90-
fn calc_skeleton(symbol_str: &SymbolStr, buffer: &mut String) -> CowBoxSymStr {
91-
use std::mem::replace;
92-
use unicode_security::confusable_detection::skeleton;
93-
buffer.clear();
94-
buffer.extend(skeleton(symbol_str));
95-
if *symbol_str == *buffer {
96-
CowBoxSymStr::Interned(symbol_str.clone())
97-
} else {
98-
let owned = replace(buffer, String::new());
99-
CowBoxSymStr::Owned(owned.into_boxed_str())
100-
}
101-
}
87+
let mut skeleton_buf = String::new();
88+
89+
for (&symbol, &sp) in symbols.iter() {
90+
use unicode_security::confusable_detection::skeleton;
91+
10292
let symbol_str = symbol.as_str();
10393
let is_ascii = symbol_str.is_ascii();
104-
let skeleton = calc_skeleton(&symbol_str, &mut str_buf);
94+
95+
// Get the skeleton as a `Symbol`.
96+
skeleton_buf.clear();
97+
skeleton_buf.extend(skeleton(&symbol_str));
98+
let skeleton_sym = if *symbol_str == *skeleton_buf {
99+
symbol
100+
} else {
101+
Symbol::intern(&skeleton_buf)
102+
};
103+
105104
skeleton_map
106-
.entry(skeleton)
107-
.and_modify(|(existing_symbolstr, existing_span, existing_is_ascii)| {
105+
.entry(skeleton_sym)
106+
.and_modify(|(existing_symbol, existing_span, existing_is_ascii)| {
108107
if !*existing_is_ascii || !is_ascii {
109108
cx.struct_span_lint(CONFUSABLE_IDENTS, sp, |lint| {
110109
lint.build(&format!(
111110
"identifier pair considered confusable between `{}` and `{}`",
112-
existing_symbolstr, symbol_str
111+
existing_symbol.as_str(),
112+
symbol.as_str()
113113
))
114114
.span_label(
115115
*existing_span,
@@ -119,12 +119,12 @@ impl EarlyLintPass for NonAsciiIdents {
119119
});
120120
}
121121
if *existing_is_ascii && !is_ascii {
122-
*existing_symbolstr = symbol_str.clone();
122+
*existing_symbol = symbol;
123123
*existing_span = sp;
124124
*existing_is_ascii = is_ascii;
125125
}
126126
})
127-
.or_insert((symbol_str, sp, is_ascii));
127+
.or_insert((symbol, sp, is_ascii));
128128
}
129129
}
130130

@@ -238,41 +238,3 @@ impl EarlyLintPass for NonAsciiIdents {
238238
}
239239
}
240240
}
241-
242-
mod utils {
243-
use rustc_span::symbol::SymbolStr;
244-
use std::hash::{Hash, Hasher};
245-
use std::ops::Deref;
246-
247-
pub(super) enum CowBoxSymStr {
248-
Interned(SymbolStr),
249-
Owned(Box<str>),
250-
}
251-
252-
impl Deref for CowBoxSymStr {
253-
type Target = str;
254-
255-
fn deref(&self) -> &str {
256-
match self {
257-
CowBoxSymStr::Interned(interned) => interned,
258-
CowBoxSymStr::Owned(ref owned) => owned,
259-
}
260-
}
261-
}
262-
263-
impl Hash for CowBoxSymStr {
264-
#[inline]
265-
fn hash<H: Hasher>(&self, state: &mut H) {
266-
Hash::hash(&**self, state)
267-
}
268-
}
269-
270-
impl PartialEq<CowBoxSymStr> for CowBoxSymStr {
271-
#[inline]
272-
fn eq(&self, other: &CowBoxSymStr) -> bool {
273-
PartialEq::eq(&**self, &**other)
274-
}
275-
}
276-
277-
impl Eq for CowBoxSymStr {}
278-
}

0 commit comments

Comments
 (0)