@@ -7,6 +7,7 @@ use rustc_ast as ast;
7
7
use rustc_data_structures:: fx:: FxIndexMap ;
8
8
use rustc_data_structures:: unord:: UnordMap ;
9
9
use rustc_span:: symbol:: Symbol ;
10
+ use unicode_security:: general_security_profile:: IdentifierType ;
10
11
11
12
declare_lint ! {
12
13
/// The `non_ascii_idents` lint detects non-ASCII identifiers.
@@ -189,17 +190,104 @@ impl EarlyLintPass for NonAsciiIdents {
189
190
if check_uncommon_codepoints
190
191
&& !symbol_str. chars ( ) . all ( GeneralSecurityProfile :: identifier_allowed)
191
192
{
192
- let codepoints: Vec < _ > = symbol_str
193
- . chars ( )
194
- . filter ( |c| !GeneralSecurityProfile :: identifier_allowed ( * c) )
195
- . collect ( ) ;
196
- let codepoints_len = codepoints. len ( ) ;
197
-
198
- cx. emit_span_lint (
199
- UNCOMMON_CODEPOINTS ,
200
- sp,
201
- IdentifierUncommonCodepoints { codepoints, codepoints_len } ,
202
- ) ;
193
+ let mut chars = symbol_str. chars ( ) . collect :: < Vec < _ > > ( ) ;
194
+
195
+ let exclusion = chars
196
+ . extract_if ( |c| {
197
+ GeneralSecurityProfile :: identifier_type ( * c)
198
+ == Some ( IdentifierType :: Exclusion )
199
+ } )
200
+ . collect :: < Vec < _ > > ( ) ;
201
+ if !exclusion. is_empty ( ) {
202
+ let exclusion_len = exclusion. len ( ) ;
203
+
204
+ cx. emit_span_lint (
205
+ UNCOMMON_CODEPOINTS ,
206
+ sp,
207
+ IdentifierUncommonCodepoints {
208
+ codepoints : exclusion,
209
+ codepoints_len : exclusion_len,
210
+ identifier_type : String :: from ( "Exclusion" ) ,
211
+ } ,
212
+ ) ;
213
+ }
214
+
215
+ let technical = chars
216
+ . extract_if ( |c| {
217
+ GeneralSecurityProfile :: identifier_type ( * c)
218
+ == Some ( IdentifierType :: Technical )
219
+ } )
220
+ . collect :: < Vec < _ > > ( ) ;
221
+ if !technical. is_empty ( ) {
222
+ let technical_len = technical. len ( ) ;
223
+
224
+ cx. emit_span_lint (
225
+ UNCOMMON_CODEPOINTS ,
226
+ sp,
227
+ IdentifierUncommonCodepoints {
228
+ codepoints : technical,
229
+ codepoints_len : technical_len,
230
+ identifier_type : String :: from ( "Technical" ) ,
231
+ } ,
232
+ ) ;
233
+ }
234
+
235
+ let limited_use = chars
236
+ . extract_if ( |c| {
237
+ GeneralSecurityProfile :: identifier_type ( * c)
238
+ == Some ( IdentifierType :: Limited_Use )
239
+ } )
240
+ . collect :: < Vec < _ > > ( ) ;
241
+ if !limited_use. is_empty ( ) {
242
+ let limited_use_len = limited_use. len ( ) ;
243
+
244
+ cx. emit_span_lint (
245
+ UNCOMMON_CODEPOINTS ,
246
+ sp,
247
+ IdentifierUncommonCodepoints {
248
+ codepoints : limited_use,
249
+ codepoints_len : limited_use_len,
250
+ identifier_type : String :: from ( "Limited_Use" ) ,
251
+ } ,
252
+ ) ;
253
+ }
254
+
255
+ let not_nfkc = chars
256
+ . extract_if ( |c| {
257
+ GeneralSecurityProfile :: identifier_type ( * c)
258
+ == Some ( IdentifierType :: Not_NFKC )
259
+ } )
260
+ . collect :: < Vec < _ > > ( ) ;
261
+ if !not_nfkc. is_empty ( ) {
262
+ let not_nfkc_len = not_nfkc. len ( ) ;
263
+
264
+ cx. emit_span_lint (
265
+ UNCOMMON_CODEPOINTS ,
266
+ sp,
267
+ IdentifierUncommonCodepoints {
268
+ codepoints : not_nfkc,
269
+ codepoints_len : not_nfkc_len,
270
+ identifier_type : String :: from ( "Not_NFKC" ) ,
271
+ } ,
272
+ ) ;
273
+ }
274
+
275
+ let remaining = chars
276
+ . extract_if ( |c| !GeneralSecurityProfile :: identifier_allowed ( * c) )
277
+ . collect :: < Vec < _ > > ( ) ;
278
+ if !remaining. is_empty ( ) {
279
+ let remaining_len = remaining. len ( ) ;
280
+
281
+ cx. emit_span_lint (
282
+ UNCOMMON_CODEPOINTS ,
283
+ sp,
284
+ IdentifierUncommonCodepoints {
285
+ codepoints : remaining,
286
+ codepoints_len : remaining_len,
287
+ identifier_type : String :: new ( ) ,
288
+ } ,
289
+ ) ;
290
+ }
203
291
}
204
292
}
205
293
0 commit comments