@@ -72,6 +72,35 @@ fn calc_skeleton(symbol_str: SymbolStr, buffer: &'_ mut String) -> CowBoxSymStr
72
72
}
73
73
}
74
74
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
+
75
104
impl EarlyLintPass for NonAsciiIdents {
76
105
fn check_crate ( & mut self , cx : & EarlyContext < ' _ > , _: & ast:: Crate ) {
77
106
use rustc_session:: lint:: Level ;
@@ -80,9 +109,26 @@ impl EarlyLintPass for NonAsciiIdents {
80
109
}
81
110
let symbols = cx. sess . parse_sess . symbol_gallery . symbols . lock ( ) ;
82
111
let mut symbol_strs_and_spans = Vec :: with_capacity ( symbols. len ( ) ) ;
112
+ let mut in_fast_path = true ;
83
113
for ( symbol, sp) in symbols. iter ( ) {
114
+ // fast path
84
115
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
+ }
86
132
}
87
133
drop ( symbols) ;
88
134
symbol_strs_and_spans. sort_by_key ( |x| x. 0 . clone ( ) ) ;
0 commit comments