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