@@ -57,6 +57,7 @@ mod uninit_assumed_init;
5757mod unnecessary_filter_map;
5858mod unnecessary_fold;
5959mod unnecessary_lazy_eval;
60+ mod unnecessary_to_owned;
6061mod unwrap_or_else_default;
6162mod unwrap_used;
6263mod useless_asref;
@@ -1885,6 +1886,32 @@ declare_clippy_lint! {
18851886 "usages of `str::splitn` that can be replaced with `str::split`"
18861887}
18871888
1889+ declare_clippy_lint ! {
1890+ /// ### What it does
1891+ /// Checks for unnecessary calls to [`ToOwned::to_owned`](https://doc.rust-lang.org/std/borrow/trait.ToOwned.html#tymethod.to_owned)
1892+ /// and other `to_owned`-like functions.
1893+ ///
1894+ /// ### Why is this bad?
1895+ /// The unnecessary calls result in unnecessary allocations.
1896+ ///
1897+ /// ### Example
1898+ /// ```rust
1899+ /// let path = std::path::Path::new("x");
1900+ /// foo(&path.to_string_lossy().to_string());
1901+ /// fn foo(s: &str) {}
1902+ /// ```
1903+ /// Use instead:
1904+ /// ```rust
1905+ /// let path = std::path::Path::new("x");
1906+ /// foo(&path.to_string_lossy());
1907+ /// fn foo(s: &str) {}
1908+ /// ```
1909+ #[ clippy:: version = "1.58.0" ]
1910+ pub UNNECESSARY_TO_OWNED ,
1911+ perf,
1912+ "unnecessary calls to `to_owned`-like functions"
1913+ }
1914+
18881915pub struct Methods {
18891916 avoid_breaking_exported_api : bool ,
18901917 msrv : Option < RustcVersion > ,
@@ -1964,7 +1991,8 @@ impl_lint_pass!(Methods => [
19641991 MANUAL_STR_REPEAT ,
19651992 EXTEND_WITH_DRAIN ,
19661993 MANUAL_SPLIT_ONCE ,
1967- NEEDLESS_SPLITN
1994+ NEEDLESS_SPLITN ,
1995+ UNNECESSARY_TO_OWNED
19681996] ) ;
19691997
19701998/// Extracts a method call name, args, and `Span` of the method name.
@@ -2007,6 +2035,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
20072035 single_char_add_str:: check ( cx, expr, args) ;
20082036 into_iter_on_ref:: check ( cx, expr, * method_span, method_call. ident . name , args) ;
20092037 single_char_pattern:: check ( cx, expr, method_call. ident . name , args) ;
2038+ unnecessary_to_owned:: check ( cx, expr, method_call. ident . name , args) ;
20102039 } ,
20112040 hir:: ExprKind :: Binary ( op, lhs, rhs) if op. node == hir:: BinOpKind :: Eq || op. node == hir:: BinOpKind :: Ne => {
20122041 let mut info = BinaryExprInfo {
0 commit comments