diff --git a/clippy_lints/src/path_from_format.rs b/clippy_lints/src/path_from_format.rs index 42bae15cd0e9..1d90cc472e0b 100644 --- a/clippy_lints/src/path_from_format.rs +++ b/clippy_lints/src/path_from_format.rs @@ -6,6 +6,7 @@ use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; +use std::fmt::Write as _; declare_clippy_lint! { /// ### What it does @@ -33,10 +34,10 @@ declare_lint_pass!(PathFromFormat => [PATH_FROM_FORMAT]); impl<'tcx> LateLintPass<'tcx> for PathFromFormat { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if_chain! { - if let ExprKind::Call(_, ref args) = expr.kind; + if let ExprKind::Call(_, args) = expr.kind; if let ty = cx.typeck_results().expr_ty(expr); if is_type_diagnostic_item(cx, ty, sym::PathBuf); - if args.len() > 0; + if !args.is_empty(); if let Some(macro_def_id) = args[0].span.ctxt().outer_expn_data().macro_def_id; if cx.tcx.get_diagnostic_name(macro_def_id) == Some(sym::format_macro); then { @@ -44,7 +45,7 @@ impl<'tcx> LateLintPass<'tcx> for PathFromFormat { let split_expr: Vec<&str> = full_expr.split('!').collect(); let args_to_macro = split_expr[1]; let replaced = args_to_macro.replace('(', "").replace(')', ""); - let unformatted: Vec<&str> = replaced.split(",").collect(); + let unformatted: Vec<&str> = replaced.split(',').collect(); let mut push_targets: Vec = Vec::new(); let mut temp_string = String::new(); for c in unformatted[0].chars() { @@ -65,20 +66,20 @@ impl<'tcx> LateLintPass<'tcx> for PathFromFormat { } for target in push_targets { let target_processed = - if target != unformatted[1].replace(' ', "") { + if target == unformatted[1].replace(' ', "") { + target + } + else { let mut s = String::from("\""); s.push_str(&target); s.push('"'); s - } - else { - target }; if temp_string.is_empty() { - temp_string.push_str(&format!("Path::new({})", target_processed)); + let _ = write!(temp_string, "Path::new({})", target_processed); } else { - temp_string.push_str(&format!(".join({})", target_processed)); + let _ = write!(temp_string, ".join({})", target_processed); } } span_lint_and_sugg( diff --git a/tests/ui/eta.stderr b/tests/ui/eta.stderr index 7481234dbaab..bf2e97e744ab 100644 --- a/tests/ui/eta.stderr +++ b/tests/ui/eta.stderr @@ -68,19 +68,53 @@ error: redundant closure LL | let e: std::vec::Vec = vec!['a', 'b', 'c'].iter().map(|c| c.to_ascii_uppercase()).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_ascii_uppercase` -thread 'rustc' panicked at 'index out of bounds: the len is 0 but the index is 0', clippy_lints/src/path_from_format.rs:39:41 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +error: redundant closure + --> $DIR/eta.rs:160:22 + | +LL | requires_fn_once(|| x()); + | ^^^^^^ help: replace the closure with the function itself: `x` -error: internal compiler error: unexpected panic +error: redundant closure + --> $DIR/eta.rs:167:27 + | +LL | let a = Some(1u8).map(|a| foo_ptr(a)); + | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo_ptr` -note: the compiler unexpectedly panicked. this is a bug. +error: redundant closure + --> $DIR/eta.rs:172:27 + | +LL | let a = Some(1u8).map(|a| closure(a)); + | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `closure` -note: we would appreciate a bug report: https://github.com/rust-lang/rust-clippy/issues/new +error: redundant closure + --> $DIR/eta.rs:204:28 + | +LL | x.into_iter().for_each(|x| add_to_res(x)); + | ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res` -note: Clippy version: clippy 0.1.62 (01d75b195 2022-05-13) +error: redundant closure + --> $DIR/eta.rs:205:28 + | +LL | y.into_iter().for_each(|x| add_to_res(x)); + | ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res` + +error: redundant closure + --> $DIR/eta.rs:206:28 + | +LL | z.into_iter().for_each(|x| add_to_res(x)); + | ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `add_to_res` + +error: redundant closure + --> $DIR/eta.rs:213:21 + | +LL | Some(1).map(|n| closure(n)); + | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut closure` + +error: redundant closure + --> $DIR/eta.rs:217:21 + | +LL | Some(1).map(|n| in_loop(n)); + | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `in_loop` -query stack during panic: -#0 [analysis] running analysis passes on this crate -end of query stack -error: aborting due to 11 previous errors +error: aborting due to 19 previous errors diff --git a/tests/ui/implicit_clone.stderr b/tests/ui/implicit_clone.stderr index a1c09a9a46c9..0f4124241907 100644 --- a/tests/ui/implicit_clone.stderr +++ b/tests/ui/implicit_clone.stderr @@ -36,19 +36,41 @@ error: implicitly cloning a `Kitten` by calling `to_owned` on its dereferenced t LL | let _ = kitten.to_owned(); | ^^^^^^^^^^^^^^^^^ help: consider using: `kitten.clone()` -thread 'rustc' panicked at 'index out of bounds: the len is 0 but the index is 0', clippy_lints/src/path_from_format.rs:39:41 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +error: implicitly cloning a `PathBuf` by calling `to_owned` on its dereferenced type + --> $DIR/implicit_clone.rs:97:13 + | +LL | let _ = pathbuf.to_owned(); + | ^^^^^^^^^^^^^^^^^^ help: consider using: `pathbuf.clone()` -error: internal compiler error: unexpected panic +error: implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenced type + --> $DIR/implicit_clone.rs:98:13 + | +LL | let _ = pathbuf.to_path_buf(); + | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `pathbuf.clone()` -note: the compiler unexpectedly panicked. this is a bug. +error: implicitly cloning a `OsString` by calling `to_owned` on its dereferenced type + --> $DIR/implicit_clone.rs:101:13 + | +LL | let _ = os_string.to_owned(); + | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `os_string.clone()` -note: we would appreciate a bug report: https://github.com/rust-lang/rust-clippy/issues/new +error: implicitly cloning a `OsString` by calling `to_os_string` on its dereferenced type + --> $DIR/implicit_clone.rs:102:13 + | +LL | let _ = os_string.to_os_string(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `os_string.clone()` -note: Clippy version: clippy 0.1.62 (01d75b195 2022-05-13) +error: implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenced type + --> $DIR/implicit_clone.rs:113:13 + | +LL | let _ = pathbuf_ref.to_path_buf(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(*pathbuf_ref).clone()` + +error: implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenced type + --> $DIR/implicit_clone.rs:116:13 + | +LL | let _ = pathbuf_ref.to_path_buf(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(**pathbuf_ref).clone()` -query stack during panic: -#0 [analysis] running analysis passes on this crate -end of query stack -error: aborting due to 6 previous errors +error: aborting due to 12 previous errors diff --git a/tests/ui/option_as_ref_deref.stderr b/tests/ui/option_as_ref_deref.stderr index 61fa03856bc4..62f282324752 100644 --- a/tests/ui/option_as_ref_deref.stderr +++ b/tests/ui/option_as_ref_deref.stderr @@ -64,19 +64,47 @@ error: called `.as_ref().map(PathBuf::as_path)` on an Option value. This can be LL | let _ = Some(PathBuf::new()).as_ref().map(PathBuf::as_path); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `Some(PathBuf::new()).as_deref()` -thread 'rustc' panicked at 'index out of bounds: the len is 0 but the index is 0', clippy_lints/src/path_from_format.rs:39:41 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +error: called `.as_ref().map(Vec::as_slice)` on an Option value. This can be done more directly by calling `Some(Vec::<()>::new()).as_deref()` instead + --> $DIR/option_as_ref_deref.rs:31:13 + | +LL | let _ = Some(Vec::<()>::new()).as_ref().map(Vec::as_slice); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `Some(Vec::<()>::new()).as_deref()` -error: internal compiler error: unexpected panic +error: called `.as_mut().map(Vec::as_mut_slice)` on an Option value. This can be done more directly by calling `Some(Vec::<()>::new()).as_deref_mut()` instead + --> $DIR/option_as_ref_deref.rs:32:13 + | +LL | let _ = Some(Vec::<()>::new()).as_mut().map(Vec::as_mut_slice); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `Some(Vec::<()>::new()).as_deref_mut()` -note: the compiler unexpectedly panicked. this is a bug. +error: called `.as_ref().map(|x| x.deref())` on an Option value. This can be done more directly by calling `opt.as_deref()` instead + --> $DIR/option_as_ref_deref.rs:34:13 + | +LL | let _ = opt.as_ref().map(|x| x.deref()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()` -note: we would appreciate a bug report: https://github.com/rust-lang/rust-clippy/issues/new +error: called `.as_mut().map(|x| x.deref_mut())` on an Option value. This can be done more directly by calling `opt.clone().as_deref_mut()` instead + --> $DIR/option_as_ref_deref.rs:35:13 + | +LL | let _ = opt.clone().as_mut().map(|x| x.deref_mut()).map(|x| x.len()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `opt.clone().as_deref_mut()` -note: Clippy version: clippy 0.1.62 (01d75b195 2022-05-13) +error: called `.as_ref().map(|x| &**x)` on an Option value. This can be done more directly by calling `opt.as_deref()` instead + --> $DIR/option_as_ref_deref.rs:42:13 + | +LL | let _ = opt.as_ref().map(|x| &**x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()` + +error: called `.as_mut().map(|x| &mut **x)` on an Option value. This can be done more directly by calling `opt.as_deref_mut()` instead + --> $DIR/option_as_ref_deref.rs:43:13 + | +LL | let _ = opt.as_mut().map(|x| &mut **x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `opt.as_deref_mut()` + +error: called `.as_ref().map(std::ops::Deref::deref)` on an Option value. This can be done more directly by calling `opt.as_deref()` instead + --> $DIR/option_as_ref_deref.rs:46:13 + | +LL | let _ = opt.as_ref().map(std::ops::Deref::deref); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()` -query stack during panic: -#0 [analysis] running analysis passes on this crate -end of query stack -error: aborting due to 10 previous errors +error: aborting due to 17 previous errors diff --git a/tests/ui/unnecessary_iter_cloned.stderr b/tests/ui/unnecessary_iter_cloned.stderr index 573a29eebb90..e44379f8aa04 100644 --- a/tests/ui/unnecessary_iter_cloned.stderr +++ b/tests/ui/unnecessary_iter_cloned.stderr @@ -1,14 +1,35 @@ -thread 'rustc' panicked at 'index out of bounds: the len is 0 but the index is 0', clippy_lints/src/path_from_format.rs:39:41 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +error: unnecessary use of `copied` + --> $DIR/unnecessary_iter_cloned.rs:31:22 + | +LL | for (t, path) in files.iter().copied() { + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::unnecessary-to-owned` implied by `-D warnings` +help: use + | +LL | for (t, path) in files { + | ~~~~~ +help: remove this `&` + | +LL - let other = match get_file_path(&t) { +LL + let other = match get_file_path(t) { + | -error: internal compiler error: unexpected panic +error: unnecessary use of `copied` + --> $DIR/unnecessary_iter_cloned.rs:46:22 + | +LL | for (t, path) in files.iter().copied() { + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: use + | +LL | for (t, path) in files.iter() { + | ~~~~~~~~~~~~ +help: remove this `&` + | +LL - let other = match get_file_path(&t) { +LL + let other = match get_file_path(t) { + | -note: the compiler unexpectedly panicked. this is a bug. +error: aborting due to 2 previous errors -note: we would appreciate a bug report: https://github.com/rust-lang/rust-clippy/issues/new - -note: Clippy version: clippy 0.1.62 (01d75b195 2022-05-13) - -query stack during panic: -#0 [analysis] running analysis passes on this crate -end of query stack diff --git a/tests/ui/unnecessary_to_owned.stderr b/tests/ui/unnecessary_to_owned.stderr index 969dbe264ecd..af7e7b41fb00 100644 --- a/tests/ui/unnecessary_to_owned.stderr +++ b/tests/ui/unnecessary_to_owned.stderr @@ -445,19 +445,69 @@ error: unnecessary use of `to_vec` LL | let _ = [std::path::PathBuf::new()][..].to_vec().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()` -thread 'rustc' panicked at 'index out of bounds: the len is 0 but the index is 0', clippy_lints/src/path_from_format.rs:39:41 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:131:13 + | +LL | let _ = [std::path::PathBuf::new()][..].to_owned().into_iter(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()` -error: internal compiler error: unexpected panic +error: unnecessary use of `to_vec` + --> $DIR/unnecessary_to_owned.rs:133:13 + | +LL | let _ = IntoIterator::into_iter(slice.to_vec()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()` -note: the compiler unexpectedly panicked. this is a bug. +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:134:13 + | +LL | let _ = IntoIterator::into_iter(slice.to_owned()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()` -note: we would appreciate a bug report: https://github.com/rust-lang/rust-clippy/issues/new +error: unnecessary use of `to_vec` + --> $DIR/unnecessary_to_owned.rs:135:13 + | +LL | let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_vec()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:136:13 + | +LL | let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_owned()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()` -note: Clippy version: clippy 0.1.62 (01d75b195 2022-05-13) +error: unnecessary use of `to_vec` + --> $DIR/unnecessary_to_owned.rs:198:14 + | +LL | for t in file_types.to_vec() { + | ^^^^^^^^^^^^^^^^^^^ + | +help: use + | +LL | for t in file_types { + | ~~~~~~~~~~ +help: remove this `&` + | +LL - let path = match get_file_path(&t) { +LL + let path = match get_file_path(t) { + | + +error: unnecessary use of `to_vec` + --> $DIR/unnecessary_to_owned.rs:221:14 + | +LL | let _ = &["x"][..].to_vec().into_iter(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().cloned()` + +error: unnecessary use of `to_vec` + --> $DIR/unnecessary_to_owned.rs:226:14 + | +LL | let _ = &["x"][..].to_vec().into_iter(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().copied()` + +error: unnecessary use of `to_string` + --> $DIR/unnecessary_to_owned.rs:273:24 + | +LL | Box::new(build(y.to_string())) + | ^^^^^^^^^^^^^ help: use: `y` -query stack during panic: -#0 [analysis] running analysis passes on this crate -end of query stack -error: aborting due to 69 previous errors +error: aborting due to 78 previous errors