summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/clippy_lints/src/methods/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/clippy/clippy_lints/src/methods/mod.rs')
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs44
1 files changed, 38 insertions, 6 deletions
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index 77be61b47..702df4b28 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -80,6 +80,7 @@ mod skip_while_next;
mod stable_sort_primitive;
mod str_splitn;
mod string_extend_chars;
+mod suspicious_command_arg_space;
mod suspicious_map;
mod suspicious_splitn;
mod suspicious_to_owned;
@@ -1818,6 +1819,7 @@ declare_clippy_lint! {
/// - `or_else` to `or`
/// - `get_or_insert_with` to `get_or_insert`
/// - `ok_or_else` to `ok_or`
+ /// - `then` to `then_some` (for msrv >= 1.62.0)
///
/// ### Why is this bad?
/// Using eager evaluation is shorter and simpler in some cases.
@@ -3102,7 +3104,7 @@ declare_clippy_lint! {
/// Ok(())
/// }
/// ```
- #[clippy::version = "1.66.0"]
+ #[clippy::version = "1.67.0"]
pub SEEK_FROM_CURRENT,
complexity,
"use dedicated method for seek from current position"
@@ -3133,7 +3135,7 @@ declare_clippy_lint! {
/// t.rewind();
/// }
/// ```
- #[clippy::version = "1.66.0"]
+ #[clippy::version = "1.67.0"]
pub SEEK_TO_START_INSTEAD_OF_REWIND,
complexity,
"jumping to the start of stream using `seek` method"
@@ -3161,6 +3163,32 @@ declare_clippy_lint! {
"collecting an iterator when collect is not needed"
}
+declare_clippy_lint! {
+ /// ### What it does
+ ///
+ /// Checks for `Command::arg()` invocations that look like they
+ /// should be multiple arguments instead, such as `arg("-t ext2")`.
+ ///
+ /// ### Why is this bad?
+ ///
+ /// `Command::arg()` does not split arguments by space. An argument like `arg("-t ext2")`
+ /// will be passed as a single argument to the command,
+ /// which is likely not what was intended.
+ ///
+ /// ### Example
+ /// ```rust
+ /// std::process::Command::new("echo").arg("-n hello").spawn().unwrap();
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// std::process::Command::new("echo").args(["-n", "hello"]).spawn().unwrap();
+ /// ```
+ #[clippy::version = "1.67.0"]
+ pub SUSPICIOUS_COMMAND_ARG_SPACE,
+ suspicious,
+ "single command line argument that looks like it should be multiple arguments"
+}
+
pub struct Methods {
avoid_breaking_exported_api: bool,
msrv: Msrv,
@@ -3288,6 +3316,7 @@ impl_lint_pass!(Methods => [
SEEK_FROM_CURRENT,
SEEK_TO_START_INSTEAD_OF_REWIND,
NEEDLESS_COLLECT,
+ SUSPICIOUS_COMMAND_ARG_SPACE,
]);
/// Extracts a method call name, args, and `Span` of the method name.
@@ -3348,11 +3377,11 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
let name = impl_item.ident.name.as_str();
let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id;
let item = cx.tcx.hir().expect_item(parent);
- let self_ty = cx.tcx.type_of(item.owner_id);
+ let self_ty = cx.tcx.type_of(item.owner_id).subst_identity();
let implements_trait = matches!(item.kind, hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }));
if let hir::ImplItemKind::Fn(ref sig, id) = impl_item.kind {
- let method_sig = cx.tcx.fn_sig(impl_item.owner_id);
+ let method_sig = cx.tcx.fn_sig(impl_item.owner_id).subst_identity();
let method_sig = cx.tcx.erase_late_bound_regions(method_sig);
let first_arg_ty_opt = method_sig.inputs().iter().next().copied();
// if this impl block implements a trait, lint in trait definition instead
@@ -3412,7 +3441,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
}
if let hir::ImplItemKind::Fn(_, _) = impl_item.kind {
- let ret_ty = return_ty(cx, impl_item.hir_id());
+ let ret_ty = return_ty(cx, impl_item.owner_id);
if contains_ty_adt_constructor_opaque(cx, ret_ty, self_ty) {
return;
@@ -3460,7 +3489,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
if_chain! {
if item.ident.name == sym::new;
if let TraitItemKind::Fn(_, _) = item.kind;
- let ret_ty = return_ty(cx, item.hir_id());
+ let ret_ty = return_ty(cx, item.owner_id);
let self_ty = TraitRef::identity(cx.tcx, item.owner_id.to_def_id())
.self_ty()
.skip_binder();
@@ -3495,6 +3524,9 @@ impl Methods {
unnecessary_lazy_eval::check(cx, expr, recv, arg, "and");
}
},
+ ("arg", [arg]) => {
+ suspicious_command_arg_space::check(cx, recv, arg, span);
+ }
("as_deref" | "as_deref_mut", []) => {
needless_option_as_deref::check(cx, expr, recv, name);
},