1
1
use crate::{EarlyContext, EarlyLintPass, LintContext};
2
2
use rustc_ast::ast;
3
3
use rustc_data_structures::fx::FxHashMap;
4
- use rustc_span::symbol::SymbolStr ;
4
+ use rustc_span::symbol::Symbol ;
5
5
6
6
declare_lint! {
7
7
pub NON_ASCII_IDENTS,
@@ -39,7 +39,6 @@ impl EarlyLintPass for NonAsciiIdents {
39
39
use rustc_span::Span;
40
40
use std::collections::BTreeMap;
41
41
use unicode_security::GeneralSecurityProfile;
42
- use utils::CowBoxSymStr;
43
42
44
43
let check_non_ascii_idents = cx.builder.lint_level(NON_ASCII_IDENTS).0 != Level::Allow;
45
44
let check_uncommon_codepoints =
@@ -83,33 +82,34 @@ impl EarlyLintPass for NonAsciiIdents {
83
82
}
84
83
85
84
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)> =
87
86
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
+
102
92
let symbol_str = symbol.as_str();
103
93
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
+
105
104
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)| {
108
107
if !*existing_is_ascii || !is_ascii {
109
108
cx.struct_span_lint(CONFUSABLE_IDENTS, sp, |lint| {
110
109
lint.build(&format!(
111
110
"identifier pair considered confusable between `{}` and `{}`",
112
- existing_symbolstr, symbol_str
111
+ existing_symbol.as_str(),
112
+ symbol.as_str()
113
113
))
114
114
.span_label(
115
115
*existing_span,
@@ -119,12 +119,12 @@ impl EarlyLintPass for NonAsciiIdents {
119
119
});
120
120
}
121
121
if *existing_is_ascii && !is_ascii {
122
- *existing_symbolstr = symbol_str.clone() ;
122
+ *existing_symbol = symbol ;
123
123
*existing_span = sp;
124
124
*existing_is_ascii = is_ascii;
125
125
}
126
126
})
127
- .or_insert((symbol_str , sp, is_ascii));
127
+ .or_insert((symbol , sp, is_ascii));
128
128
}
129
129
}
130
130
@@ -238,41 +238,3 @@ impl EarlyLintPass for NonAsciiIdents {
238
238
}
239
239
}
240
240
}
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