Skip to content

Commit 7f75533

Browse files
committed
Add a fast code path to optimize confusable_idents lint for ASCII code base.
1 parent 7ff936b commit 7f75533

File tree

1 file changed

+47
-1
lines changed

1 file changed

+47
-1
lines changed

src/librustc_lint/non_ascii_idents.rs

+47-1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,35 @@ fn calc_skeleton(symbol_str: SymbolStr, buffer: &'_ mut String) -> CowBoxSymStr
7272
}
7373
}
7474

75+
fn is_in_ascii_confusable_closure(c: char) -> bool {
76+
// FIXME: move this table to `unicode_security` crate.
77+
// data here corresponds to Unicode 13.
78+
const ASCII_CONFUSABLE_CLOSURE: &[(u64, u64)] = &[(0x00, 0x7f), (0xba, 0xba), (0x2080, 0x2080)];
79+
let c = c as u64;
80+
for &(range_start, range_end) in ASCII_CONFUSABLE_CLOSURE {
81+
if c >= range_start && c <= range_end {
82+
return true;
83+
}
84+
}
85+
false
86+
}
87+
88+
fn is_in_ascii_confusable_closure_relevant_list(c: char) -> bool {
89+
// FIXME: move this table to `unicode_security` crate.
90+
// data here corresponds to Unicode 13.
91+
const ASCII_CONFUSABLE_CLOSURE_RELEVANT_LIST: &[u64] = &[
92+
0x22, 0x25, 0x27, 0x2f, 0x30, 0x31, 0x49, 0x4f, 0x60, 0x6c, 0x6d, 0x6e, 0x72, 0x7c, 0xba,
93+
0x2080,
94+
];
95+
let c = c as u64;
96+
for &item in ASCII_CONFUSABLE_CLOSURE_RELEVANT_LIST {
97+
if c == item {
98+
return true;
99+
}
100+
}
101+
false
102+
}
103+
75104
impl EarlyLintPass for NonAsciiIdents {
76105
fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) {
77106
use rustc_session::lint::Level;
@@ -80,9 +109,26 @@ impl EarlyLintPass for NonAsciiIdents {
80109
}
81110
let symbols = cx.sess.parse_sess.symbol_gallery.symbols.lock();
82111
let mut symbol_strs_and_spans = Vec::with_capacity(symbols.len());
112+
let mut in_fast_path = true;
83113
for (symbol, sp) in symbols.iter() {
114+
// fast path
84115
let symbol_str = symbol.as_str();
85-
symbol_strs_and_spans.push((symbol_str, *sp));
116+
if !symbol_str.chars().all(is_in_ascii_confusable_closure) {
117+
// fallback to slow path.
118+
symbol_strs_and_spans.clear();
119+
in_fast_path = false;
120+
break;
121+
}
122+
if symbol_str.chars().any(is_in_ascii_confusable_closure_relevant_list) {
123+
symbol_strs_and_spans.push((symbol_str, *sp));
124+
}
125+
}
126+
if !in_fast_path {
127+
// slow path
128+
for (symbol, sp) in symbols.iter() {
129+
let symbol_str = symbol.as_str();
130+
symbol_strs_and_spans.push((symbol_str, *sp));
131+
}
86132
}
87133
drop(symbols);
88134
symbol_strs_and_spans.sort_by_key(|x| x.0.clone());

0 commit comments

Comments
 (0)