diff --git a/compiler/rustc_lint/src/non_ascii_idents.rs b/compiler/rustc_lint/src/non_ascii_idents.rs index f78b32ce5e77b..4821e191eb490 100644 --- a/compiler/rustc_lint/src/non_ascii_idents.rs +++ b/compiler/rustc_lint/src/non_ascii_idents.rs @@ -187,20 +187,31 @@ impl EarlyLintPass for NonAsciiIdents { } has_non_ascii_idents = true; cx.emit_span_lint(NON_ASCII_IDENTS, sp, IdentifierNonAsciiChar); - if check_uncommon_codepoints - && !symbol_str.chars().all(GeneralSecurityProfile::identifier_allowed) - { - let codepoints: Vec<_> = symbol_str + if check_uncommon_codepoints { + let mut codepoints: Vec<_> = symbol_str .chars() .filter(|c| !GeneralSecurityProfile::identifier_allowed(*c)) .collect(); - let codepoints_len = codepoints.len(); - cx.emit_span_lint( - UNCOMMON_CODEPOINTS, - sp, - IdentifierUncommonCodepoints { codepoints, codepoints_len }, - ); + // 00B7 MIDDLE DOT '·' is considered by + // [UTS 39](https://unicode.org/reports/tr39/#Identifier_Status_and_Type) + // to be "Allowed - Inclusion" due to its presence in [UTR 31 Table 3a - Optional Characters for Medial] + // (https://www.unicode.org/reports/tr31/#Table_Optional_Medial); + // as such, it is unsuitable for appearing in the final position of identifiers. + if symbol_str.chars().last() == Some('·') { + codepoints.push('·'); + } + + if !codepoints.is_empty() { + cx.emit_span_lint( + UNCOMMON_CODEPOINTS, + sp, + IdentifierUncommonCodepoints { + codepoints_len: codepoints.len(), + codepoints, + }, + ); + } } } diff --git a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.rs b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.rs index c3459930a94c0..1cc0fbb5f2d95 100644 --- a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.rs +++ b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.rs @@ -11,3 +11,9 @@ fn main() { // using the same identifier the second time won't trigger the lint. println!("{}", ㇻㇲㇳ); } + +// 00B7 MIDDLE DOT '·' is linted against only in final position. + +const FOO·: () = (); //~ ERROR identifier contains an uncommon Unicode codepoint + +const FOL·LY: () = (); diff --git a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.stderr b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.stderr index bae5ac654d354..8b9620b6ce2fe 100644 --- a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.stderr +++ b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.stderr @@ -22,6 +22,12 @@ error: identifier contains uncommon Unicode codepoints: 'ㇻ', 'ㇲ', and 'ㇳ' LL | let ㇻㇲㇳ = "rust"; | ^^^^^^ +error: identifier contains an uncommon Unicode codepoint: '·' + --> $DIR/lint-uncommon-codepoints.rs:17:7 + | +LL | const FOO·: () = (); + | ^^^^ + warning: constant `µ` should have an upper case name --> $DIR/lint-uncommon-codepoints.rs:3:7 | @@ -30,5 +36,5 @@ LL | const µ: f64 = 0.000001; | = note: `#[warn(non_upper_case_globals)]` on by default -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 4 previous errors; 1 warning emitted