|
1 |
| -use clippy_utils::{ |
2 |
| - diagnostics::span_lint_and_then, get_parent_expr, is_from_proc_macro, match_def_path, path_res, paths::PATH_NEW, |
3 |
| - ty::is_type_diagnostic_item, |
4 |
| -}; |
5 |
| -use rustc_ast::LitKind; |
| 1 | +use clippy_utils::diagnostics::span_lint_and_then; |
| 2 | +use clippy_utils::paths::PATH_NEW; |
| 3 | +use clippy_utils::ty::is_type_diagnostic_item; |
| 4 | +use clippy_utils::{get_parent_expr, is_from_proc_macro, match_def_path, path_res}; |
| 5 | +use rustc_ast::{LitKind, StrStyle}; |
6 | 6 | use rustc_errors::Applicability;
|
7 | 7 | use rustc_hir::def_id::DefId;
|
8 | 8 | use rustc_hir::{Expr, ExprKind, QPath};
|
9 | 9 | use rustc_lint::{LateContext, LateLintPass, LintContext};
|
10 |
| -use rustc_middle::{lint::in_external_macro, ty}; |
| 10 | +use rustc_middle::lint::in_external_macro; |
| 11 | +use rustc_middle::ty; |
11 | 12 | use rustc_session::{declare_lint_pass, declare_tool_lint};
|
12 | 13 | use rustc_span::{sym, Symbol};
|
| 14 | +use std::borrow::Cow; |
13 | 15 |
|
14 | 16 | declare_clippy_lint! {
|
15 | 17 | /// ### What it does
|
@@ -41,7 +43,7 @@ impl<'tcx> LateLintPass<'tcx> for BareDosDeviceNames {
|
41 | 43 | fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
42 | 44 | if !in_external_macro(cx.sess(), expr.span)
|
43 | 45 | && let ExprKind::Lit(arg) = expr.kind
|
44 |
| - && let LitKind::Str(str_sym, _) = arg.node |
| 46 | + && let LitKind::Str(str_sym, str_style) = arg.node |
45 | 47 | && matches!(
|
46 | 48 | &*str_sym.as_str().to_ascii_lowercase(),
|
47 | 49 | "aux"
|
@@ -86,20 +88,26 @@ impl<'tcx> LateLintPass<'tcx> for BareDosDeviceNames {
|
86 | 88 | expr.span,
|
87 | 89 | "this path refers to a DOS device",
|
88 | 90 | |diag| {
|
| 91 | + // Keep `r###` and `###` |
| 92 | + let (prefix, hashes) = if let StrStyle::Raw(num) = str_style { |
| 93 | + (Cow::Borrowed("r"), "#".repeat(num as usize).into()) |
| 94 | + } else { |
| 95 | + (Cow::Borrowed(""), Cow::Borrowed("")) |
| 96 | + }; |
| 97 | + |
89 | 98 | // Suggest making current behavior explicit
|
90 | 99 | diag.span_suggestion_verbose(
|
91 | 100 | expr.span,
|
92 |
| - "if this is intended, try", |
93 |
| - // FIXME: I have zero clue why it normalizes this. `\` -> `/` |
94 |
| - format!(r#"r"\\.\{str_sym}"\"#), |
| 101 | + "if this is intended, use", |
| 102 | + format!(r#"r{hashes}"\\.\{str_sym}"{hashes}"#), |
95 | 103 | Applicability::MaybeIncorrect,
|
96 | 104 | );
|
97 | 105 |
|
98 | 106 | // Suggest making the code refer to a file or folder in the current directory
|
99 | 107 | diag.span_suggestion_verbose(
|
100 | 108 | expr.span,
|
101 |
| - "if this was intended to point to a file or folder, try", |
102 |
| - format!("\"./{str_sym}\""), |
| 109 | + "if this was intended to point to a file or folder, use", |
| 110 | + format!(r#"{prefix}{hashes}"./{str_sym}"{hashes}"#), |
103 | 111 | Applicability::MaybeIncorrect,
|
104 | 112 | );
|
105 | 113 | }
|
@@ -165,12 +173,10 @@ fn is_path_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, parent: &'tc
|
165 | 173 | const LINTED_TRAITS: &[(Symbol, Symbol)] = &[
|
166 | 174 | (sym::AsRef, sym::Path),
|
167 | 175 | (sym::AsMut, sym::Path),
|
168 |
| - // Basically useless, but let's lint these anyway |
169 | 176 | (sym::AsRef, sym::PathBuf),
|
170 | 177 | (sym::AsMut, sym::PathBuf),
|
171 | 178 | (sym::Into, sym::Path),
|
172 | 179 | (sym::Into, sym::PathBuf),
|
173 |
| - // Never seen `From` used in a generic context before, but let's lint these anyway |
174 | 180 | (sym::From, sym::Path),
|
175 | 181 | (sym::From, sym::PathBuf),
|
176 | 182 | // TODO: Let's add more traits here.
|
@@ -204,14 +210,11 @@ fn is_path_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, parent: &'tc
|
204 | 210 | // I believe `0` is always `Self`, i.e., `T` or `impl <trait>` so get `1` instead
|
205 | 211 | && let [_, subst] = trit.trait_ref.substs.as_slice()
|
206 | 212 | && let Some(as_ref_ty) = subst.as_type()
|
207 |
| - { |
208 |
| - for (trait_sym, ty_sym) in LINTED_TRAITS { |
209 |
| - if cx.tcx.is_diagnostic_item(*trait_sym, trit.trait_ref.def_id) |
| 213 | + && LINTED_TRAITS.iter().any(|(trait_sym, ty_sym)| { |
| 214 | + cx.tcx.is_diagnostic_item(*trait_sym, trit.trait_ref.def_id) |
210 | 215 | && is_type_diagnostic_item(cx, as_ref_ty, *ty_sym)
|
211 |
| - { |
212 |
| - return true; |
213 |
| - } |
214 |
| - } |
| 216 | + }) { |
| 217 | + return true; |
215 | 218 | }
|
216 | 219 | }
|
217 | 220 |
|
|
0 commit comments