Skip to content

Commit ecabf1e

Browse files
committed
Remove FIXME and make it retain old raw string hashes
1 parent d1f04e7 commit ecabf1e

File tree

3 files changed

+60
-40
lines changed

3 files changed

+60
-40
lines changed

clippy_lints/src/bare_dos_device_names.rs

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
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};
66
use rustc_errors::Applicability;
77
use rustc_hir::def_id::DefId;
88
use rustc_hir::{Expr, ExprKind, QPath};
99
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;
1112
use rustc_session::{declare_lint_pass, declare_tool_lint};
1213
use rustc_span::{sym, Symbol};
14+
use std::borrow::Cow;
1315

1416
declare_clippy_lint! {
1517
/// ### What it does
@@ -41,7 +43,7 @@ impl<'tcx> LateLintPass<'tcx> for BareDosDeviceNames {
4143
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
4244
if !in_external_macro(cx.sess(), expr.span)
4345
&& let ExprKind::Lit(arg) = expr.kind
44-
&& let LitKind::Str(str_sym, _) = arg.node
46+
&& let LitKind::Str(str_sym, str_style) = arg.node
4547
&& matches!(
4648
&*str_sym.as_str().to_ascii_lowercase(),
4749
"aux"
@@ -86,20 +88,26 @@ impl<'tcx> LateLintPass<'tcx> for BareDosDeviceNames {
8688
expr.span,
8789
"this path refers to a DOS device",
8890
|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+
8998
// Suggest making current behavior explicit
9099
diag.span_suggestion_verbose(
91100
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}"#),
95103
Applicability::MaybeIncorrect,
96104
);
97105

98106
// Suggest making the code refer to a file or folder in the current directory
99107
diag.span_suggestion_verbose(
100108
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}"#),
103111
Applicability::MaybeIncorrect,
104112
);
105113
}
@@ -165,12 +173,10 @@ fn is_path_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, parent: &'tc
165173
const LINTED_TRAITS: &[(Symbol, Symbol)] = &[
166174
(sym::AsRef, sym::Path),
167175
(sym::AsMut, sym::Path),
168-
// Basically useless, but let's lint these anyway
169176
(sym::AsRef, sym::PathBuf),
170177
(sym::AsMut, sym::PathBuf),
171178
(sym::Into, sym::Path),
172179
(sym::Into, sym::PathBuf),
173-
// Never seen `From` used in a generic context before, but let's lint these anyway
174180
(sym::From, sym::Path),
175181
(sym::From, sym::PathBuf),
176182
// 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
204210
// I believe `0` is always `Self`, i.e., `T` or `impl <trait>` so get `1` instead
205211
&& let [_, subst] = trit.trait_ref.substs.as_slice()
206212
&& 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)
210215
&& is_type_diagnostic_item(cx, as_ref_ty, *ty_sym)
211-
{
212-
return true;
213-
}
214-
}
216+
}) {
217+
return true;
215218
}
216219
}
217220

tests/ui/bare_dos_device_names.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
//@aux-build:proc_macros.rs:proc-macro
2-
#![allow(clippy::no_effect, unused)]
2+
#![allow(clippy::needless_raw_string_hashes, clippy::no_effect, unused)]
33
#![warn(clippy::bare_dos_device_names)]
44

55
#[macro_use]
66
extern crate proc_macros;
77

88
use std::fs::File;
9-
use std::path::Path;
10-
use std::path::PathBuf;
9+
use std::path::{Path, PathBuf};
1110

1211
fn a<T: AsRef<Path>>(t: T) {}
1312

@@ -20,6 +19,9 @@ fn main() {
2019
b("conin$");
2120
File::open("conin$");
2221
std::path::PathBuf::from("a");
22+
// Keep raw string
23+
Path::new(r##"aux"##);
24+
// Don't lint
2325
PathBuf::from("a");
2426
Path::new("a");
2527
external! {

tests/ui/bare_dos_device_names.stderr

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,63 @@
11
error: this path refers to a DOS device
2-
--> $DIR/bare_dos_device_names.rs:19:7
2+
--> $DIR/bare_dos_device_names.rs:18:7
33
|
44
LL | a("con");
55
| ^^^^^
66
|
77
= note: `-D clippy::bare-dos-device-names` implied by `-D warnings`
8-
help: if this is intended, try
8+
help: if this is intended, use
99
|
10-
LL | a(r"//./con"/);
11-
| ~~~~~~~~~~~
12-
help: if this was intended to point to a file or folder, try
10+
LL | a(r"//./con");
11+
| ~~~~~~~~~~
12+
help: if this was intended to point to a file or folder, use
1313
|
1414
LL | a("./con");
1515
| ~~~~~~~
1616

1717
error: this path refers to a DOS device
18-
--> $DIR/bare_dos_device_names.rs:20:7
18+
--> $DIR/bare_dos_device_names.rs:19:7
1919
|
2020
LL | b("conin$");
2121
| ^^^^^^^^
2222
|
23-
help: if this is intended, try
23+
help: if this is intended, use
2424
|
25-
LL | b(r"//./conin$"/);
26-
| ~~~~~~~~~~~~~~
27-
help: if this was intended to point to a file or folder, try
25+
LL | b(r"//./conin$");
26+
| ~~~~~~~~~~~~~
27+
help: if this was intended to point to a file or folder, use
2828
|
2929
LL | b("./conin$");
3030
| ~~~~~~~~~~
3131

3232
error: this path refers to a DOS device
33-
--> $DIR/bare_dos_device_names.rs:21:16
33+
--> $DIR/bare_dos_device_names.rs:20:16
3434
|
3535
LL | File::open("conin$");
3636
| ^^^^^^^^
3737
|
38-
help: if this is intended, try
38+
help: if this is intended, use
3939
|
40-
LL | File::open(r"//./conin$"/);
41-
| ~~~~~~~~~~~~~~
42-
help: if this was intended to point to a file or folder, try
40+
LL | File::open(r"//./conin$");
41+
| ~~~~~~~~~~~~~
42+
help: if this was intended to point to a file or folder, use
4343
|
4444
LL | File::open("./conin$");
4545
| ~~~~~~~~~~
4646

47-
error: aborting due to 3 previous errors
47+
error: this path refers to a DOS device
48+
--> $DIR/bare_dos_device_names.rs:23:15
49+
|
50+
LL | Path::new(r##"aux"##);
51+
| ^^^^^^^^^^
52+
|
53+
help: if this is intended, use
54+
|
55+
LL | Path::new(r##"//./aux"##);
56+
| ~~~~~~~~~~~~~~
57+
help: if this was intended to point to a file or folder, use
58+
|
59+
LL | Path::new(r##"./aux"##);
60+
| ~~~~~~~~~~~~
61+
62+
error: aborting due to 4 previous errors
4863

0 commit comments

Comments
 (0)