/// ### Example
/// You don't see it, but there may be a zero-width space or soft hyphen
/// somewhere in this text.
+ #[clippy::version = "1.49.0"]
pub INVISIBLE_CHARACTERS,
correctness,
"using an invisible character in a string literal, which is confusing"
declare_clippy_lint! {
/// ### What it does
- /// Checks for non-ASCII characters in string literals.
+ /// Checks for non-ASCII characters in string and char literals.
///
/// ### Why is this bad?
/// Yeah, we know, the 90's called and wanted their charset
/// ```rust
/// let x = String::from("\u{20ac}");
/// ```
+ #[clippy::version = "pre 1.29.0"]
pub NON_ASCII_LITERAL,
- pedantic,
+ restriction,
"using any literal non-ASCII chars in a string literal instead of using the `\\u` escape"
}
/// ### Example
/// You may not see it, but "à"" and "à"" aren't the same string. The
/// former when escaped is actually `"a\u{300}"` while the latter is `"\u{e0}"`.
+ #[clippy::version = "pre 1.29.0"]
pub UNICODE_NOT_NFC,
pedantic,
"using a Unicode literal not in NFC normal form (see [Unicode tr15](http://www.unicode.org/reports/tr15/) for further information)"
impl LateLintPass<'_> for Unicode {
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {
if let ExprKind::Lit(ref lit) = expr.kind {
- if let LitKind::Str(_, _) = lit.node {
+ if let LitKind::Str(_, _) | LitKind::Char(_) = lit.node {
check_str(cx, lit.span, expr.hir_id);
}
}
"invisible character detected",
"consider replacing the string with",
string
- .replace("\u{200B}", "\\u{200B}")
- .replace("\u{ad}", "\\u{AD}")
- .replace("\u{2060}", "\\u{2060}"),
+ .replace('\u{200B}', "\\u{200B}")
+ .replace('\u{ad}', "\\u{AD}")
+ .replace('\u{2060}', "\\u{2060}"),
Applicability::MachineApplicable,
);
}