From 9665f66323d47f4ea0321eb601de1a466f56871b Mon Sep 17 00:00:00 2001 From: dbaranov34 Date: Tue, 9 Sep 2025 14:04:21 +0400 Subject: [PATCH 1/9] implemeted lint, but the other lint now fails expectedly --- CHANGELOG.md | 1 + clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/lib.rs | 2 + .../src/useless_pathbuf_conversion.rs | 66 +++++++++++++++++++ tests/ui/useless_pathbuf_conversion.fixed | 11 ++++ tests/ui/useless_pathbuf_conversion.rs | 11 ++++ tests/ui/useless_pathbuf_conversion.stderr | 11 ++++ 7 files changed, 103 insertions(+) create mode 100644 clippy_lints/src/useless_pathbuf_conversion.rs create mode 100644 tests/ui/useless_pathbuf_conversion.fixed create mode 100644 tests/ui/useless_pathbuf_conversion.rs create mode 100644 tests/ui/useless_pathbuf_conversion.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 30781d3d33fb..81481350e539 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6791,6 +6791,7 @@ Released 2018-09-13 [`useless_format`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_format [`useless_let_if_seq`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_let_if_seq [`useless_nonzero_new_unchecked`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_nonzero_new_unchecked +[`useless_patbuf_conversion`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_patbuf_conversion [`useless_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_transmute [`useless_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_vec [`vec_box`]: https://rust-lang.github.io/rust-clippy/master/index.html#vec_box diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 7645ac2dd3f7..3faace6ec031 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -775,6 +775,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[ crate::use_self::USE_SELF_INFO, crate::useless_concat::USELESS_CONCAT_INFO, crate::useless_conversion::USELESS_CONVERSION_INFO, + crate::useless_pathbuf_conversion::USELESS_PATHBUF_CONVERSION_INFO, crate::vec::USELESS_VEC_INFO, crate::vec_init_then_push::VEC_INIT_THEN_PUSH_INFO, crate::visibility::NEEDLESS_PUB_SELF_INFO, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 733113fe0d33..fb94a7a98555 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -397,6 +397,7 @@ mod upper_case_acronyms; mod use_self; mod useless_concat; mod useless_conversion; +mod useless_pathbuf_conversion; mod vec; mod vec_init_then_push; mod visibility; @@ -580,6 +581,7 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co store.register_late_pass(|_| Box::new(infinite_iter::InfiniteIter)); store.register_late_pass(|_| Box::new(inline_fn_without_body::InlineFnWithoutBody)); store.register_late_pass(|_| Box::::default()); + store.register_late_pass(|_| Box::new(useless_pathbuf_conversion::UselessPathbufConversion)); store.register_late_pass(|_| Box::new(implicit_hasher::ImplicitHasher)); store.register_late_pass(|_| Box::new(fallible_impl_from::FallibleImplFrom)); store.register_late_pass(move |_| Box::new(question_mark::QuestionMark::new(conf))); diff --git a/clippy_lints/src/useless_pathbuf_conversion.rs b/clippy_lints/src/useless_pathbuf_conversion.rs new file mode 100644 index 000000000000..0a3b71d53f66 --- /dev/null +++ b/clippy_lints/src/useless_pathbuf_conversion.rs @@ -0,0 +1,66 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::snippet; +use clippy_utils::ty::is_type_diagnostic_item; +use rustc_hir::{Expr, ExprKind}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_session::declare_lint_pass; +use rustc_span::symbol::sym; + +declare_clippy_lint! { + /// **What it does:** Detects unnecessary `&PathBuf::from(...)` when `&Path` would suffice. + /// + /// **Why is this bad?** `PathBuf::from` allocates a new heap buffer unnecessarily. + /// + /// **Example:** + /// ```rust + /// fn use_path(p: &std::path::Path) {} + /// use_path(&std::path::PathBuf::from("abc")); + /// ``` + /// Could be written as: + /// ```rust + /// fn use_path(p: &std::path::Path) {} + /// use_path(std::path::Path::new("abc")); + /// ``` + #[clippy::version = "1.91.0"] + pub USELESS_PATHBUF_CONVERSION, + complexity, + "creating a PathBuf only to take a reference, where Path::new would suffice" +} + +declare_lint_pass!(UselessPathbufConversion => [USELESS_PATHBUF_CONVERSION]); + +impl<'tcx> LateLintPass<'tcx> for UselessPathbufConversion { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { + // Only care about &PathBuf::from(...) + if let ExprKind::AddrOf(_, _, inner) = &expr.kind { + if let ExprKind::Call(func, args) = &inner.kind { + if let ExprKind::Path(ref qpath) = func.kind { + if let Some(def_id) = cx.qpath_res(qpath, func.hir_id).opt_def_id() { + // check that the function is `from` + if cx.tcx.item_name(def_id) != sym::from { + return; + } + + // get the type of the function's return value + let ty = cx.typeck_results().expr_ty(inner); + + if is_type_diagnostic_item(cx, ty, sym::PathBuf) { + if let Some(arg) = args.get(0) { + let sugg = format!("Path::new({})", snippet(cx, arg.span, "..")); + span_lint_and_sugg( + cx, + USELESS_PATHBUF_CONVERSION, + expr.span, + "unnecessary `PathBuf::from` when a `&Path` is enough", + "consider using", + sugg, + rustc_errors::Applicability::MachineApplicable, + ); + } + } + } + } + } + } + } +} diff --git a/tests/ui/useless_pathbuf_conversion.fixed b/tests/ui/useless_pathbuf_conversion.fixed new file mode 100644 index 000000000000..38ac2c0085a1 --- /dev/null +++ b/tests/ui/useless_pathbuf_conversion.fixed @@ -0,0 +1,11 @@ +#![warn(clippy::useless_pathbuf_conversion)] +use std::path::{Path, PathBuf}; + +fn use_path(p: &Path) {} + +fn main() { + use_path(Path::new("abc")); + //~^ useless_pathbuf_conversion + + use_path(Path::new("abc")); +} diff --git a/tests/ui/useless_pathbuf_conversion.rs b/tests/ui/useless_pathbuf_conversion.rs new file mode 100644 index 000000000000..45ccc8e4fa04 --- /dev/null +++ b/tests/ui/useless_pathbuf_conversion.rs @@ -0,0 +1,11 @@ +#![warn(clippy::useless_pathbuf_conversion)] +use std::path::{Path, PathBuf}; + +fn use_path(p: &Path) {} + +fn main() { + use_path(&PathBuf::from("abc")); + //~^ useless_pathbuf_conversion + + use_path(Path::new("abc")); +} diff --git a/tests/ui/useless_pathbuf_conversion.stderr b/tests/ui/useless_pathbuf_conversion.stderr new file mode 100644 index 000000000000..0e0de68cbbb8 --- /dev/null +++ b/tests/ui/useless_pathbuf_conversion.stderr @@ -0,0 +1,11 @@ +error: unnecessary `PathBuf::from` when a `&Path` is enough + --> tests/ui/useless_pathbuf_conversion.rs:7:14 + | +LL | use_path(&PathBuf::from("abc")); + | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `Path::new("abc")` + | + = note: `-D clippy::useless-pathbuf-conversion` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::useless_pathbuf_conversion)]` + +error: aborting due to 1 previous error + From 99e971866ede1e0fcb2b160e20e7ddb7328d971c Mon Sep 17 00:00:00 2001 From: dbaranov34 Date: Tue, 9 Sep 2025 14:14:09 +0400 Subject: [PATCH 2/9] rm useless pathbuf check from unnecessary_to_owned_check --- tests/ui/unnecessary_to_owned.fixed | 2 -- tests/ui/unnecessary_to_owned.rs | 2 -- tests/ui/unnecessary_to_owned.stderr | 46 ++++++++++------------------ 3 files changed, 17 insertions(+), 33 deletions(-) diff --git a/tests/ui/unnecessary_to_owned.fixed b/tests/ui/unnecessary_to_owned.fixed index 316eac0b58b7..09e037ac67a6 100644 --- a/tests/ui/unnecessary_to_owned.fixed +++ b/tests/ui/unnecessary_to_owned.fixed @@ -219,8 +219,6 @@ fn main() { //~^ redundant_clone require_os_str(&OsString::from("x")); //~^ redundant_clone - require_path(&std::path::PathBuf::from("x")); - //~^ redundant_clone require_str(&String::from("x")); //~^ redundant_clone require_slice(&[String::from("x")]); diff --git a/tests/ui/unnecessary_to_owned.rs b/tests/ui/unnecessary_to_owned.rs index f2dbd1db3c9f..e343f912b9c4 100644 --- a/tests/ui/unnecessary_to_owned.rs +++ b/tests/ui/unnecessary_to_owned.rs @@ -219,8 +219,6 @@ fn main() { //~^ redundant_clone require_os_str(&OsString::from("x").to_os_string()); //~^ redundant_clone - require_path(&std::path::PathBuf::from("x").to_path_buf()); - //~^ redundant_clone require_str(&String::from("x").to_string()); //~^ redundant_clone require_slice(&[String::from("x")].to_owned()); diff --git a/tests/ui/unnecessary_to_owned.stderr b/tests/ui/unnecessary_to_owned.stderr index 6c52be839301..adcddf731ede 100644 --- a/tests/ui/unnecessary_to_owned.stderr +++ b/tests/ui/unnecessary_to_owned.stderr @@ -25,37 +25,25 @@ LL | require_os_str(&OsString::from("x").to_os_string()); | ^^^^^^^^^^^^^^^^^^^ error: redundant clone - --> tests/ui/unnecessary_to_owned.rs:222:48 - | -LL | require_path(&std::path::PathBuf::from("x").to_path_buf()); - | ^^^^^^^^^^^^^^ help: remove this - | -note: this value is dropped without further use - --> tests/ui/unnecessary_to_owned.rs:222:19 - | -LL | require_path(&std::path::PathBuf::from("x").to_path_buf()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: redundant clone - --> tests/ui/unnecessary_to_owned.rs:224:35 + --> tests/ui/unnecessary_to_owned.rs:222:35 | LL | require_str(&String::from("x").to_string()); | ^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/unnecessary_to_owned.rs:224:18 + --> tests/ui/unnecessary_to_owned.rs:222:18 | LL | require_str(&String::from("x").to_string()); | ^^^^^^^^^^^^^^^^^ error: redundant clone - --> tests/ui/unnecessary_to_owned.rs:226:39 + --> tests/ui/unnecessary_to_owned.rs:224:39 | LL | require_slice(&[String::from("x")].to_owned()); | ^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/unnecessary_to_owned.rs:226:20 + --> tests/ui/unnecessary_to_owned.rs:224:20 | LL | require_slice(&[String::from("x")].to_owned()); | ^^^^^^^^^^^^^^^^^^^ @@ -454,7 +442,7 @@ LL | let _ = IntoIterator::into_iter(slice.to_owned()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()` error: allocating a new `String` only to create a temporary `&str` from it - --> tests/ui/unnecessary_to_owned.rs:230:26 + --> tests/ui/unnecessary_to_owned.rs:228:26 | LL | let _ref_str: &str = &String::from_utf8(slice.to_vec()).expect("not UTF-8"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -466,7 +454,7 @@ LL + let _ref_str: &str = core::str::from_utf8(&slice).expect("not UTF-8"); | error: allocating a new `String` only to create a temporary `&str` from it - --> tests/ui/unnecessary_to_owned.rs:232:26 + --> tests/ui/unnecessary_to_owned.rs:230:26 | LL | let _ref_str: &str = &String::from_utf8(b"foo".to_vec()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -478,7 +466,7 @@ LL + let _ref_str: &str = core::str::from_utf8(b"foo").unwrap(); | error: allocating a new `String` only to create a temporary `&str` from it - --> tests/ui/unnecessary_to_owned.rs:234:26 + --> tests/ui/unnecessary_to_owned.rs:232:26 | LL | let _ref_str: &str = &String::from_utf8(b"foo".as_slice().to_owned()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -490,7 +478,7 @@ LL + let _ref_str: &str = core::str::from_utf8(b"foo".as_slice()).unwrap(); | error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:292:14 + --> tests/ui/unnecessary_to_owned.rs:290:14 | LL | for t in file_types.to_vec() { | ^^^^^^^^^^^^^^^^^^^ @@ -503,52 +491,52 @@ LL ~ let path = match get_file_path(t) { | error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned.rs:358:24 + --> tests/ui/unnecessary_to_owned.rs:356:24 | LL | Box::new(build(y.to_string())) | ^^^^^^^^^^^^^ help: use: `y` error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned.rs:468:12 + --> tests/ui/unnecessary_to_owned.rs:466:12 | LL | id("abc".to_string()) | ^^^^^^^^^^^^^^^^^ help: use: `"abc"` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:612:37 + --> tests/ui/unnecessary_to_owned.rs:610:37 | LL | IntoFuture::into_future(foo([].to_vec(), &0)); | ^^^^^^^^^^^ help: use: `[]` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:623:18 + --> tests/ui/unnecessary_to_owned.rs:621:18 | LL | s.remove(&a.to_vec()); | ^^^^^^^^^^^ help: replace it with: `a` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:628:14 + --> tests/ui/unnecessary_to_owned.rs:626:14 | LL | s.remove(&"b".to_owned()); | ^^^^^^^^^^^^^^^ help: replace it with: `"b"` error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned.rs:630:14 + --> tests/ui/unnecessary_to_owned.rs:628:14 | LL | s.remove(&"b".to_string()); | ^^^^^^^^^^^^^^^^ help: replace it with: `"b"` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:636:14 + --> tests/ui/unnecessary_to_owned.rs:634:14 | LL | s.remove(&["b"].to_vec()); | ^^^^^^^^^^^^^^^ help: replace it with: `["b"].as_slice()` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:638:14 + --> tests/ui/unnecessary_to_owned.rs:636:14 | LL | s.remove(&(&["b"]).to_vec()); | ^^^^^^^^^^^^^^^^^^ help: replace it with: `(&["b"]).as_slice()` -error: aborting due to 82 previous errors +error: aborting due to 81 previous errors From 4380e8354eef19f4071ec6085fd0b46dd68be63b Mon Sep 17 00:00:00 2001 From: dbaranov34 Date: Tue, 9 Sep 2025 14:24:12 +0400 Subject: [PATCH 3/9] cleanup and clippy --- .../src/useless_pathbuf_conversion.rs | 50 +++++++++---------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/clippy_lints/src/useless_pathbuf_conversion.rs b/clippy_lints/src/useless_pathbuf_conversion.rs index 0a3b71d53f66..1b6db11c43d3 100644 --- a/clippy_lints/src/useless_pathbuf_conversion.rs +++ b/clippy_lints/src/useless_pathbuf_conversion.rs @@ -32,34 +32,32 @@ declare_lint_pass!(UselessPathbufConversion => [USELESS_PATHBUF_CONVERSION]); impl<'tcx> LateLintPass<'tcx> for UselessPathbufConversion { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { // Only care about &PathBuf::from(...) - if let ExprKind::AddrOf(_, _, inner) = &expr.kind { - if let ExprKind::Call(func, args) = &inner.kind { - if let ExprKind::Path(ref qpath) = func.kind { - if let Some(def_id) = cx.qpath_res(qpath, func.hir_id).opt_def_id() { - // check that the function is `from` - if cx.tcx.item_name(def_id) != sym::from { - return; - } + if let ExprKind::AddrOf(_, _, inner) = &expr.kind + && let ExprKind::Call(func, args) = &inner.kind + && let ExprKind::Path(ref qpath) = func.kind + && let Some(def_id) = cx.qpath_res(qpath, func.hir_id).opt_def_id() + { + // check that the function is `from` + if cx.tcx.item_name(def_id) != sym::from { + return; + } - // get the type of the function's return value - let ty = cx.typeck_results().expr_ty(inner); + // get the type of the function's return value + let ty = cx.typeck_results().expr_ty(inner); - if is_type_diagnostic_item(cx, ty, sym::PathBuf) { - if let Some(arg) = args.get(0) { - let sugg = format!("Path::new({})", snippet(cx, arg.span, "..")); - span_lint_and_sugg( - cx, - USELESS_PATHBUF_CONVERSION, - expr.span, - "unnecessary `PathBuf::from` when a `&Path` is enough", - "consider using", - sugg, - rustc_errors::Applicability::MachineApplicable, - ); - } - } - } - } + if is_type_diagnostic_item(cx, ty, sym::PathBuf) + && let Some(arg) = args.first() + { + let sugg = format!("Path::new({})", snippet(cx, arg.span, "..")); + span_lint_and_sugg( + cx, + USELESS_PATHBUF_CONVERSION, + expr.span, + "unnecessary `PathBuf::from` when a `&Path` is enough", + "consider using", + sugg, + rustc_errors::Applicability::MachineApplicable, + ); } } } From e7351103d465b77103fda135e819a2dd9f7e476e Mon Sep 17 00:00:00 2001 From: dbaranov34 Date: Tue, 9 Sep 2025 14:28:30 +0400 Subject: [PATCH 4/9] update lints in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81481350e539..ebaff96fbd1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6791,7 +6791,7 @@ Released 2018-09-13 [`useless_format`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_format [`useless_let_if_seq`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_let_if_seq [`useless_nonzero_new_unchecked`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_nonzero_new_unchecked -[`useless_patbuf_conversion`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_patbuf_conversion +[`useless_pathbuf_conversion`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_pathbuf_conversion [`useless_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_transmute [`useless_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_vec [`vec_box`]: https://rust-lang.github.io/rust-clippy/master/index.html#vec_box From a43202ba4246d08a1f8258d0f1268eb18b521cda Mon Sep 17 00:00:00 2001 From: dbaranov34 Date: Tue, 30 Sep 2025 17:12:41 +0400 Subject: [PATCH 5/9] addressed pr comments --- .../src/useless_pathbuf_conversion.rs | 46 ++++++++----------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/clippy_lints/src/useless_pathbuf_conversion.rs b/clippy_lints/src/useless_pathbuf_conversion.rs index 1b6db11c43d3..d22868eb88f5 100644 --- a/clippy_lints/src/useless_pathbuf_conversion.rs +++ b/clippy_lints/src/useless_pathbuf_conversion.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::is_path_diagnostic_item; use clippy_utils::source::snippet; -use clippy_utils::ty::is_type_diagnostic_item; -use rustc_hir::{Expr, ExprKind}; +use rustc_hir::{Expr, ExprKind, QPath}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; use rustc_span::symbol::sym; @@ -21,44 +21,34 @@ declare_clippy_lint! { /// fn use_path(p: &std::path::Path) {} /// use_path(std::path::Path::new("abc")); /// ``` - #[clippy::version = "1.91.0"] + #[clippy::version = "1.92.0"] pub USELESS_PATHBUF_CONVERSION, complexity, - "creating a PathBuf only to take a reference, where Path::new would suffice" + "creating a `PathBuf` only to take a reference, where `Path::new` would suffice" } declare_lint_pass!(UselessPathbufConversion => [USELESS_PATHBUF_CONVERSION]); impl<'tcx> LateLintPass<'tcx> for UselessPathbufConversion { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - // Only care about &PathBuf::from(...) if let ExprKind::AddrOf(_, _, inner) = &expr.kind - && let ExprKind::Call(func, args) = &inner.kind + && let ExprKind::Call(func, [arg]) = &inner.kind && let ExprKind::Path(ref qpath) = func.kind && let Some(def_id) = cx.qpath_res(qpath, func.hir_id).opt_def_id() + && cx.tcx.item_name(def_id) == sym::from + && let QPath::TypeRelative(pathbuf, from) = qpath + && is_path_diagnostic_item(cx, *pathbuf, sym::PathBuf) { - // check that the function is `from` - if cx.tcx.item_name(def_id) != sym::from { - return; - } - - // get the type of the function's return value - let ty = cx.typeck_results().expr_ty(inner); - - if is_type_diagnostic_item(cx, ty, sym::PathBuf) - && let Some(arg) = args.first() - { - let sugg = format!("Path::new({})", snippet(cx, arg.span, "..")); - span_lint_and_sugg( - cx, - USELESS_PATHBUF_CONVERSION, - expr.span, - "unnecessary `PathBuf::from` when a `&Path` is enough", - "consider using", - sugg, - rustc_errors::Applicability::MachineApplicable, - ); - } + let sugg = format!("Path::new({})", snippet(cx, arg.span, "..")); + span_lint_and_sugg( + cx, + USELESS_PATHBUF_CONVERSION, + expr.span, + "unnecessary `PathBuf::from` when a `&Path` is enough", + "consider using", + sugg, + rustc_errors::Applicability::MachineApplicable, + ); } } } From 54211e69a6aa12e11cef98205161e7cb032f5f6b Mon Sep 17 00:00:00 2001 From: dbaranov34 Date: Tue, 30 Sep 2025 17:15:14 +0400 Subject: [PATCH 6/9] addressed pr comments --- clippy_lints/src/useless_pathbuf_conversion.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/useless_pathbuf_conversion.rs b/clippy_lints/src/useless_pathbuf_conversion.rs index d22868eb88f5..08d8ec86c33d 100644 --- a/clippy_lints/src/useless_pathbuf_conversion.rs +++ b/clippy_lints/src/useless_pathbuf_conversion.rs @@ -36,7 +36,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessPathbufConversion { && let ExprKind::Path(ref qpath) = func.kind && let Some(def_id) = cx.qpath_res(qpath, func.hir_id).opt_def_id() && cx.tcx.item_name(def_id) == sym::from - && let QPath::TypeRelative(pathbuf, from) = qpath + && let QPath::TypeRelative(pathbuf, _) = qpath && is_path_diagnostic_item(cx, *pathbuf, sym::PathBuf) { let sugg = format!("Path::new({})", snippet(cx, arg.span, "..")); From e3ec8c0de54a70144a3af7f8386edc483e6a2504 Mon Sep 17 00:00:00 2001 From: dbaranov34 Date: Tue, 30 Sep 2025 20:13:00 +0400 Subject: [PATCH 7/9] addressed pr comments --- .../src/useless_pathbuf_conversion.rs | 21 +- tests/ui/unnecessary_to_owned.fixed | 5 +- tests/ui/unnecessary_to_owned.rs | 5 +- tests/ui/unnecessary_to_owned.stderr | 184 ++++++++++-------- tests/ui/useless_pathbuf_conversion.fixed | 4 + tests/ui/useless_pathbuf_conversion.rs | 4 + tests/ui/useless_pathbuf_conversion.stderr | 2 +- 7 files changed, 130 insertions(+), 95 deletions(-) diff --git a/clippy_lints/src/useless_pathbuf_conversion.rs b/clippy_lints/src/useless_pathbuf_conversion.rs index 08d8ec86c33d..aa4501f9a366 100644 --- a/clippy_lints/src/useless_pathbuf_conversion.rs +++ b/clippy_lints/src/useless_pathbuf_conversion.rs @@ -1,6 +1,9 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::is_path_diagnostic_item; -use clippy_utils::source::snippet; +use clippy_utils::source::snippet_with_context; +use clippy_utils::ty::is_type_diagnostic_item; + +use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, QPath}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; @@ -34,12 +37,18 @@ impl<'tcx> LateLintPass<'tcx> for UselessPathbufConversion { if let ExprKind::AddrOf(_, _, inner) = &expr.kind && let ExprKind::Call(func, [arg]) = &inner.kind && let ExprKind::Path(ref qpath) = func.kind - && let Some(def_id) = cx.qpath_res(qpath, func.hir_id).opt_def_id() - && cx.tcx.item_name(def_id) == sym::from - && let QPath::TypeRelative(pathbuf, _) = qpath + && let QPath::TypeRelative(pathbuf, from) = qpath && is_path_diagnostic_item(cx, *pathbuf, sym::PathBuf) + && from.ident.name == sym::from + && let expr_ty = cx.typeck_results().expr_ty_adjusted(expr) + && let rustc_middle::ty::Ref(_, inner_ty, _) = expr_ty.kind() + && is_type_diagnostic_item(cx, *inner_ty, sym::Path) { - let sugg = format!("Path::new({})", snippet(cx, arg.span, "..")); + let mut app = Applicability::MachineApplicable; + let arg_snippet = snippet_with_context(cx, arg.span, arg.span.ctxt(), "..", &mut app).0; + + let sugg = format!("Path::new({arg_snippet})"); + span_lint_and_sugg( cx, USELESS_PATHBUF_CONVERSION, @@ -47,7 +56,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessPathbufConversion { "unnecessary `PathBuf::from` when a `&Path` is enough", "consider using", sugg, - rustc_errors::Applicability::MachineApplicable, + app, ); } } diff --git a/tests/ui/unnecessary_to_owned.fixed b/tests/ui/unnecessary_to_owned.fixed index 09e037ac67a6..a5ec89174ef6 100644 --- a/tests/ui/unnecessary_to_owned.fixed +++ b/tests/ui/unnecessary_to_owned.fixed @@ -5,7 +5,8 @@ clippy::needless_lifetimes, clippy::owned_cow, clippy::ptr_arg, - clippy::uninlined_format_args + clippy::uninlined_format_args, + clippy::useless_pathbuf_conversion )] #![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)] @@ -219,6 +220,8 @@ fn main() { //~^ redundant_clone require_os_str(&OsString::from("x")); //~^ redundant_clone + require_path(&std::path::PathBuf::from("x")); + //~^ redundant_clone require_str(&String::from("x")); //~^ redundant_clone require_slice(&[String::from("x")]); diff --git a/tests/ui/unnecessary_to_owned.rs b/tests/ui/unnecessary_to_owned.rs index e343f912b9c4..026d8c0b6816 100644 --- a/tests/ui/unnecessary_to_owned.rs +++ b/tests/ui/unnecessary_to_owned.rs @@ -5,7 +5,8 @@ clippy::needless_lifetimes, clippy::owned_cow, clippy::ptr_arg, - clippy::uninlined_format_args + clippy::uninlined_format_args, + clippy::useless_pathbuf_conversion )] #![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)] @@ -219,6 +220,8 @@ fn main() { //~^ redundant_clone require_os_str(&OsString::from("x").to_os_string()); //~^ redundant_clone + require_path(&std::path::PathBuf::from("x").to_path_buf()); + //~^ redundant_clone require_str(&String::from("x").to_string()); //~^ redundant_clone require_slice(&[String::from("x")].to_owned()); diff --git a/tests/ui/unnecessary_to_owned.stderr b/tests/ui/unnecessary_to_owned.stderr index adcddf731ede..4522710bb73b 100644 --- a/tests/ui/unnecessary_to_owned.stderr +++ b/tests/ui/unnecessary_to_owned.stderr @@ -1,11 +1,11 @@ error: redundant clone - --> tests/ui/unnecessary_to_owned.rs:218:64 + --> tests/ui/unnecessary_to_owned.rs:219:64 | LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned()); | ^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/unnecessary_to_owned.rs:218:20 + --> tests/ui/unnecessary_to_owned.rs:219:20 | LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,43 +13,55 @@ LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned()) = help: to override `-D warnings` add `#[allow(clippy::redundant_clone)]` error: redundant clone - --> tests/ui/unnecessary_to_owned.rs:220:40 + --> tests/ui/unnecessary_to_owned.rs:221:40 | LL | require_os_str(&OsString::from("x").to_os_string()); | ^^^^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/unnecessary_to_owned.rs:220:21 + --> tests/ui/unnecessary_to_owned.rs:221:21 | LL | require_os_str(&OsString::from("x").to_os_string()); | ^^^^^^^^^^^^^^^^^^^ error: redundant clone - --> tests/ui/unnecessary_to_owned.rs:222:35 + --> tests/ui/unnecessary_to_owned.rs:223:48 + | +LL | require_path(&std::path::PathBuf::from("x").to_path_buf()); + | ^^^^^^^^^^^^^^ help: remove this + | +note: this value is dropped without further use + --> tests/ui/unnecessary_to_owned.rs:223:19 + | +LL | require_path(&std::path::PathBuf::from("x").to_path_buf()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: redundant clone + --> tests/ui/unnecessary_to_owned.rs:225:35 | LL | require_str(&String::from("x").to_string()); | ^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/unnecessary_to_owned.rs:222:18 + --> tests/ui/unnecessary_to_owned.rs:225:18 | LL | require_str(&String::from("x").to_string()); | ^^^^^^^^^^^^^^^^^ error: redundant clone - --> tests/ui/unnecessary_to_owned.rs:224:39 + --> tests/ui/unnecessary_to_owned.rs:227:39 | LL | require_slice(&[String::from("x")].to_owned()); | ^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/unnecessary_to_owned.rs:224:20 + --> tests/ui/unnecessary_to_owned.rs:227:20 | LL | require_slice(&[String::from("x")].to_owned()); | ^^^^^^^^^^^^^^^^^^^ error: unnecessary use of `into_owned` - --> tests/ui/unnecessary_to_owned.rs:66:36 + --> tests/ui/unnecessary_to_owned.rs:67:36 | LL | require_c_str(&Cow::from(c_str).into_owned()); | ^^^^^^^^^^^^^ help: remove this @@ -58,391 +70,391 @@ LL | require_c_str(&Cow::from(c_str).into_owned()); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_to_owned)]` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:68:19 + --> tests/ui/unnecessary_to_owned.rs:69:19 | LL | require_c_str(&c_str.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `c_str` error: unnecessary use of `to_os_string` - --> tests/ui/unnecessary_to_owned.rs:71:20 + --> tests/ui/unnecessary_to_owned.rs:72:20 | LL | require_os_str(&os_str.to_os_string()); | ^^^^^^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `into_owned` - --> tests/ui/unnecessary_to_owned.rs:73:38 + --> tests/ui/unnecessary_to_owned.rs:74:38 | LL | require_os_str(&Cow::from(os_str).into_owned()); | ^^^^^^^^^^^^^ help: remove this error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:75:20 + --> tests/ui/unnecessary_to_owned.rs:76:20 | LL | require_os_str(&os_str.to_owned()); | ^^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `to_path_buf` - --> tests/ui/unnecessary_to_owned.rs:78:18 + --> tests/ui/unnecessary_to_owned.rs:79:18 | LL | require_path(&path.to_path_buf()); | ^^^^^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `into_owned` - --> tests/ui/unnecessary_to_owned.rs:80:34 + --> tests/ui/unnecessary_to_owned.rs:81:34 | LL | require_path(&Cow::from(path).into_owned()); | ^^^^^^^^^^^^^ help: remove this error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:82:18 + --> tests/ui/unnecessary_to_owned.rs:83:18 | LL | require_path(&path.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned.rs:85:17 + --> tests/ui/unnecessary_to_owned.rs:86:17 | LL | require_str(&s.to_string()); | ^^^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `into_owned` - --> tests/ui/unnecessary_to_owned.rs:87:30 + --> tests/ui/unnecessary_to_owned.rs:88:30 | LL | require_str(&Cow::from(s).into_owned()); | ^^^^^^^^^^^^^ help: remove this error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:89:17 + --> tests/ui/unnecessary_to_owned.rs:90:17 | LL | require_str(&s.to_owned()); | ^^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned.rs:91:17 + --> tests/ui/unnecessary_to_owned.rs:92:17 | LL | require_str(&x_ref.to_string()); | ^^^^^^^^^^^^^^^^^^ help: use: `x_ref.as_ref()` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:94:19 + --> tests/ui/unnecessary_to_owned.rs:95:19 | LL | require_slice(&slice.to_vec()); | ^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `into_owned` - --> tests/ui/unnecessary_to_owned.rs:96:36 + --> tests/ui/unnecessary_to_owned.rs:97:36 | LL | require_slice(&Cow::from(slice).into_owned()); | ^^^^^^^^^^^^^ help: remove this error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:98:19 + --> tests/ui/unnecessary_to_owned.rs:99:19 | LL | require_slice(&array.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `array.as_ref()` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:100:19 + --> tests/ui/unnecessary_to_owned.rs:101:19 | LL | require_slice(&array_ref.to_owned()); | ^^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref.as_ref()` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:102:19 + --> tests/ui/unnecessary_to_owned.rs:103:19 | LL | require_slice(&slice.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `into_owned` - --> tests/ui/unnecessary_to_owned.rs:106:42 + --> tests/ui/unnecessary_to_owned.rs:107:42 | LL | require_x(&Cow::::Owned(x.clone()).into_owned()); | ^^^^^^^^^^^^^ help: remove this error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:110:25 + --> tests/ui/unnecessary_to_owned.rs:111:25 | LL | require_deref_c_str(c_str.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `c_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:112:26 + --> tests/ui/unnecessary_to_owned.rs:113:26 | LL | require_deref_os_str(os_str.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:114:24 + --> tests/ui/unnecessary_to_owned.rs:115:24 | LL | require_deref_path(path.to_owned()); | ^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:116:23 + --> tests/ui/unnecessary_to_owned.rs:117:23 | LL | require_deref_str(s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:118:25 + --> tests/ui/unnecessary_to_owned.rs:119:25 | LL | require_deref_slice(slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:121:30 + --> tests/ui/unnecessary_to_owned.rs:122:30 | LL | require_impl_deref_c_str(c_str.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `c_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:123:31 + --> tests/ui/unnecessary_to_owned.rs:124:31 | LL | require_impl_deref_os_str(os_str.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:125:29 + --> tests/ui/unnecessary_to_owned.rs:126:29 | LL | require_impl_deref_path(path.to_owned()); | ^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:127:28 + --> tests/ui/unnecessary_to_owned.rs:128:28 | LL | require_impl_deref_str(s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:129:30 + --> tests/ui/unnecessary_to_owned.rs:130:30 | LL | require_impl_deref_slice(slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:132:29 + --> tests/ui/unnecessary_to_owned.rs:133:29 | LL | require_deref_str_slice(s.to_owned(), slice.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:132:43 + --> tests/ui/unnecessary_to_owned.rs:133:43 | LL | require_deref_str_slice(s.to_owned(), slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:135:29 + --> tests/ui/unnecessary_to_owned.rs:136:29 | LL | require_deref_slice_str(slice.to_owned(), s.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:135:47 + --> tests/ui/unnecessary_to_owned.rs:136:47 | LL | require_deref_slice_str(slice.to_owned(), s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:139:26 + --> tests/ui/unnecessary_to_owned.rs:140:26 | LL | require_as_ref_c_str(c_str.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `c_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:141:27 + --> tests/ui/unnecessary_to_owned.rs:142:27 | LL | require_as_ref_os_str(os_str.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:143:25 + --> tests/ui/unnecessary_to_owned.rs:144:25 | LL | require_as_ref_path(path.to_owned()); | ^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:145:24 + --> tests/ui/unnecessary_to_owned.rs:146:24 | LL | require_as_ref_str(s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:147:24 + --> tests/ui/unnecessary_to_owned.rs:148:24 | LL | require_as_ref_str(x.to_owned()); | ^^^^^^^^^^^^ help: use: `&x` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:149:26 + --> tests/ui/unnecessary_to_owned.rs:150:26 | LL | require_as_ref_slice(array.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `array` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:151:26 + --> tests/ui/unnecessary_to_owned.rs:152:26 | LL | require_as_ref_slice(array_ref.to_owned()); | ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:153:26 + --> tests/ui/unnecessary_to_owned.rs:154:26 | LL | require_as_ref_slice(slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:156:31 + --> tests/ui/unnecessary_to_owned.rs:157:31 | LL | require_impl_as_ref_c_str(c_str.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `c_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:158:32 + --> tests/ui/unnecessary_to_owned.rs:159:32 | LL | require_impl_as_ref_os_str(os_str.to_owned()); | ^^^^^^^^^^^^^^^^^ help: use: `os_str` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:160:30 + --> tests/ui/unnecessary_to_owned.rs:161:30 | LL | require_impl_as_ref_path(path.to_owned()); | ^^^^^^^^^^^^^^^ help: use: `path` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:162:29 + --> tests/ui/unnecessary_to_owned.rs:163:29 | LL | require_impl_as_ref_str(s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:164:29 + --> tests/ui/unnecessary_to_owned.rs:165:29 | LL | require_impl_as_ref_str(x.to_owned()); | ^^^^^^^^^^^^ help: use: `&x` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:166:31 + --> tests/ui/unnecessary_to_owned.rs:167:31 | LL | require_impl_as_ref_slice(array.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `array` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:168:31 + --> tests/ui/unnecessary_to_owned.rs:169:31 | LL | require_impl_as_ref_slice(array_ref.to_owned()); | ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:170:31 + --> tests/ui/unnecessary_to_owned.rs:171:31 | LL | require_impl_as_ref_slice(slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:173:30 + --> tests/ui/unnecessary_to_owned.rs:174:30 | LL | require_as_ref_str_slice(s.to_owned(), array.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:173:44 + --> tests/ui/unnecessary_to_owned.rs:174:44 | LL | require_as_ref_str_slice(s.to_owned(), array.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `array` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:176:30 + --> tests/ui/unnecessary_to_owned.rs:177:30 | LL | require_as_ref_str_slice(s.to_owned(), array_ref.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:176:44 + --> tests/ui/unnecessary_to_owned.rs:177:44 | LL | require_as_ref_str_slice(s.to_owned(), array_ref.to_owned()); | ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:179:30 + --> tests/ui/unnecessary_to_owned.rs:180:30 | LL | require_as_ref_str_slice(s.to_owned(), slice.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:179:44 + --> tests/ui/unnecessary_to_owned.rs:180:44 | LL | require_as_ref_str_slice(s.to_owned(), slice.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:182:30 + --> tests/ui/unnecessary_to_owned.rs:183:30 | LL | require_as_ref_slice_str(array.to_owned(), s.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `array` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:182:48 + --> tests/ui/unnecessary_to_owned.rs:183:48 | LL | require_as_ref_slice_str(array.to_owned(), s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:185:30 + --> tests/ui/unnecessary_to_owned.rs:186:30 | LL | require_as_ref_slice_str(array_ref.to_owned(), s.to_owned()); | ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:185:52 + --> tests/ui/unnecessary_to_owned.rs:186:52 | LL | require_as_ref_slice_str(array_ref.to_owned(), s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:188:30 + --> tests/ui/unnecessary_to_owned.rs:189:30 | LL | require_as_ref_slice_str(slice.to_owned(), s.to_owned()); | ^^^^^^^^^^^^^^^^ help: use: `slice` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:188:48 + --> tests/ui/unnecessary_to_owned.rs:189:48 | LL | require_as_ref_slice_str(slice.to_owned(), s.to_owned()); | ^^^^^^^^^^^^ help: use: `s` error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned.rs:192:20 + --> tests/ui/unnecessary_to_owned.rs:193:20 | LL | let _ = x.join(&x_ref.to_string()); | ^^^^^^^^^^^^^^^^^^ help: use: `x_ref` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:195:13 + --> tests/ui/unnecessary_to_owned.rs:196:13 | LL | let _ = slice.to_vec().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:197:13 + --> tests/ui/unnecessary_to_owned.rs:198:13 | LL | let _ = slice.to_owned().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:200:13 + --> tests/ui/unnecessary_to_owned.rs:201:13 | LL | let _ = IntoIterator::into_iter(slice.to_vec()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:202:13 + --> tests/ui/unnecessary_to_owned.rs:203:13 | LL | let _ = IntoIterator::into_iter(slice.to_owned()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()` error: allocating a new `String` only to create a temporary `&str` from it - --> tests/ui/unnecessary_to_owned.rs:228:26 + --> tests/ui/unnecessary_to_owned.rs:231:26 | LL | let _ref_str: &str = &String::from_utf8(slice.to_vec()).expect("not UTF-8"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -454,7 +466,7 @@ LL + let _ref_str: &str = core::str::from_utf8(&slice).expect("not UTF-8"); | error: allocating a new `String` only to create a temporary `&str` from it - --> tests/ui/unnecessary_to_owned.rs:230:26 + --> tests/ui/unnecessary_to_owned.rs:233:26 | LL | let _ref_str: &str = &String::from_utf8(b"foo".to_vec()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -466,7 +478,7 @@ LL + let _ref_str: &str = core::str::from_utf8(b"foo").unwrap(); | error: allocating a new `String` only to create a temporary `&str` from it - --> tests/ui/unnecessary_to_owned.rs:232:26 + --> tests/ui/unnecessary_to_owned.rs:235:26 | LL | let _ref_str: &str = &String::from_utf8(b"foo".as_slice().to_owned()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -478,7 +490,7 @@ LL + let _ref_str: &str = core::str::from_utf8(b"foo".as_slice()).unwrap(); | error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:290:14 + --> tests/ui/unnecessary_to_owned.rs:293:14 | LL | for t in file_types.to_vec() { | ^^^^^^^^^^^^^^^^^^^ @@ -491,52 +503,52 @@ LL ~ let path = match get_file_path(t) { | error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned.rs:356:24 + --> tests/ui/unnecessary_to_owned.rs:359:24 | LL | Box::new(build(y.to_string())) | ^^^^^^^^^^^^^ help: use: `y` error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned.rs:466:12 + --> tests/ui/unnecessary_to_owned.rs:469:12 | LL | id("abc".to_string()) | ^^^^^^^^^^^^^^^^^ help: use: `"abc"` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:610:37 + --> tests/ui/unnecessary_to_owned.rs:613:37 | LL | IntoFuture::into_future(foo([].to_vec(), &0)); | ^^^^^^^^^^^ help: use: `[]` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:621:18 + --> tests/ui/unnecessary_to_owned.rs:624:18 | LL | s.remove(&a.to_vec()); | ^^^^^^^^^^^ help: replace it with: `a` error: unnecessary use of `to_owned` - --> tests/ui/unnecessary_to_owned.rs:626:14 + --> tests/ui/unnecessary_to_owned.rs:629:14 | LL | s.remove(&"b".to_owned()); | ^^^^^^^^^^^^^^^ help: replace it with: `"b"` error: unnecessary use of `to_string` - --> tests/ui/unnecessary_to_owned.rs:628:14 + --> tests/ui/unnecessary_to_owned.rs:631:14 | LL | s.remove(&"b".to_string()); | ^^^^^^^^^^^^^^^^ help: replace it with: `"b"` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:634:14 + --> tests/ui/unnecessary_to_owned.rs:637:14 | LL | s.remove(&["b"].to_vec()); | ^^^^^^^^^^^^^^^ help: replace it with: `["b"].as_slice()` error: unnecessary use of `to_vec` - --> tests/ui/unnecessary_to_owned.rs:636:14 + --> tests/ui/unnecessary_to_owned.rs:639:14 | LL | s.remove(&(&["b"]).to_vec()); | ^^^^^^^^^^^^^^^^^^ help: replace it with: `(&["b"]).as_slice()` -error: aborting due to 81 previous errors +error: aborting due to 82 previous errors diff --git a/tests/ui/useless_pathbuf_conversion.fixed b/tests/ui/useless_pathbuf_conversion.fixed index 38ac2c0085a1..d02938df12a5 100644 --- a/tests/ui/useless_pathbuf_conversion.fixed +++ b/tests/ui/useless_pathbuf_conversion.fixed @@ -3,9 +3,13 @@ use std::path::{Path, PathBuf}; fn use_path(p: &Path) {} +fn takes_ref_pathbuf(_: &PathBuf) {} + fn main() { use_path(Path::new("abc")); //~^ useless_pathbuf_conversion use_path(Path::new("abc")); + + takes_ref_pathbuf(&PathBuf::from("path")); } diff --git a/tests/ui/useless_pathbuf_conversion.rs b/tests/ui/useless_pathbuf_conversion.rs index 45ccc8e4fa04..eeaaf2c9880c 100644 --- a/tests/ui/useless_pathbuf_conversion.rs +++ b/tests/ui/useless_pathbuf_conversion.rs @@ -3,9 +3,13 @@ use std::path::{Path, PathBuf}; fn use_path(p: &Path) {} +fn takes_ref_pathbuf(_: &PathBuf) {} + fn main() { use_path(&PathBuf::from("abc")); //~^ useless_pathbuf_conversion use_path(Path::new("abc")); + + takes_ref_pathbuf(&PathBuf::from("path")); } diff --git a/tests/ui/useless_pathbuf_conversion.stderr b/tests/ui/useless_pathbuf_conversion.stderr index 0e0de68cbbb8..c92279cb66e4 100644 --- a/tests/ui/useless_pathbuf_conversion.stderr +++ b/tests/ui/useless_pathbuf_conversion.stderr @@ -1,5 +1,5 @@ error: unnecessary `PathBuf::from` when a `&Path` is enough - --> tests/ui/useless_pathbuf_conversion.rs:7:14 + --> tests/ui/useless_pathbuf_conversion.rs:9:14 | LL | use_path(&PathBuf::from("abc")); | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `Path::new("abc")` From aaa4e1666f7a02d59b351dd904d602170bf7ef3a Mon Sep 17 00:00:00 2001 From: dbaranov34 Date: Tue, 30 Sep 2025 21:44:58 +0400 Subject: [PATCH 8/9] correct usage of snippet_with_context --- clippy_lints/src/useless_pathbuf_conversion.rs | 2 +- clippy_utils/src/source.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/useless_pathbuf_conversion.rs b/clippy_lints/src/useless_pathbuf_conversion.rs index aa4501f9a366..e011db12b84f 100644 --- a/clippy_lints/src/useless_pathbuf_conversion.rs +++ b/clippy_lints/src/useless_pathbuf_conversion.rs @@ -45,7 +45,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessPathbufConversion { && is_type_diagnostic_item(cx, *inner_ty, sym::Path) { let mut app = Applicability::MachineApplicable; - let arg_snippet = snippet_with_context(cx, arg.span, arg.span.ctxt(), "..", &mut app).0; + let arg_snippet = snippet_with_context(cx, arg.span, inner.span.ctxt(), "..", &mut app).0; let sugg = format!("Path::new({arg_snippet})"); diff --git a/clippy_utils/src/source.rs b/clippy_utils/src/source.rs index 638d32903123..a6fb1d712a32 100644 --- a/clippy_utils/src/source.rs +++ b/clippy_utils/src/source.rs @@ -653,6 +653,8 @@ pub fn snippet_block_with_context( /// would result in `box []`. If given the context of the address of expression, this function will /// correctly get a snippet of `vec![]`. /// +/// NOTE: Typically the `outer` context should be taken from the parent node, not from the node itself. +/// /// This will also return whether or not the snippet is a macro call. pub fn snippet_with_context<'a>( sess: &impl HasSession, From 5412590608fc69bcd98f1881996c67762f5eb87b Mon Sep 17 00:00:00 2001 From: dbaranov34 Date: Tue, 30 Sep 2025 22:02:18 +0400 Subject: [PATCH 9/9] fmt --- clippy_utils/src/source.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clippy_utils/src/source.rs b/clippy_utils/src/source.rs index a6fb1d712a32..fd607e95af71 100644 --- a/clippy_utils/src/source.rs +++ b/clippy_utils/src/source.rs @@ -653,7 +653,8 @@ pub fn snippet_block_with_context( /// would result in `box []`. If given the context of the address of expression, this function will /// correctly get a snippet of `vec![]`. /// -/// NOTE: Typically the `outer` context should be taken from the parent node, not from the node itself. +/// NOTE: Typically the `outer` context should be taken from the parent node, not from the node +/// itself. /// /// This will also return whether or not the snippet is a macro call. pub fn snippet_with_context<'a>(