@@ -65,6 +65,7 @@ mod or_fun_call;
65
65
mod or_then_unwrap;
66
66
mod path_buf_push_overwrite;
67
67
mod range_zip_with_len;
68
+ mod repeat_once;
68
69
mod search_is_some;
69
70
mod single_char_add_str;
70
71
mod single_char_insert_string;
@@ -2760,6 +2761,38 @@ declare_clippy_lint! {
2760
2761
"zipping iterator with a range when `enumerate()` would do"
2761
2762
}
2762
2763
2764
+ declare_clippy_lint ! {
2765
+ /// ### What it does
2766
+ /// Checks for usage of `.repeat(1)` and suggest the following method for each types.
2767
+ /// - `.to_string()` for `str`
2768
+ /// - `.clone()` for `String`
2769
+ /// - `.to_vec()` for `slice`
2770
+ ///
2771
+ /// The lint will evaluate constant expressions and values as arguments of `.repeat(..)` and emit a message if
2772
+ /// they are equivalent to `1`. (Related discussion in [rust-clippy#7306](https://github.com/rust-lang/rust-clippy/issues/7306))
2773
+ ///
2774
+ /// ### Why is this bad?
2775
+ /// For example, `String.repeat(1)` is equivalent to `.clone()`. If cloning
2776
+ /// the string is the intention behind this, `clone()` should be used.
2777
+ ///
2778
+ /// ### Example
2779
+ /// ```rust
2780
+ /// fn main() {
2781
+ /// let x = String::from("hello world").repeat(1);
2782
+ /// }
2783
+ /// ```
2784
+ /// Use instead:
2785
+ /// ```rust
2786
+ /// fn main() {
2787
+ /// let x = String::from("hello world").clone();
2788
+ /// }
2789
+ /// ```
2790
+ #[ clippy:: version = "1.47.0" ]
2791
+ pub REPEAT_ONCE ,
2792
+ complexity,
2793
+ "using `.repeat(1)` instead of `String.clone()`, `str.to_string()` or `slice.to_vec()` "
2794
+ }
2795
+
2763
2796
pub struct Methods {
2764
2797
avoid_breaking_exported_api : bool ,
2765
2798
msrv : Option < RustcVersion > ,
@@ -2875,6 +2908,7 @@ impl_lint_pass!(Methods => [
2875
2908
NONSENSICAL_OPEN_OPTIONS ,
2876
2909
PATH_BUF_PUSH_OVERWRITE ,
2877
2910
RANGE_ZIP_WITH_LEN ,
2911
+ REPEAT_ONCE ,
2878
2912
] ) ;
2879
2913
2880
2914
/// Extracts a method call name, args, and `Span` of the method name.
@@ -3263,6 +3297,9 @@ impl Methods {
3263
3297
( "push" , [ arg] ) => {
3264
3298
path_buf_push_overwrite:: check ( cx, expr, arg) ;
3265
3299
} ,
3300
+ ( "repeat" , [ arg] ) => {
3301
+ repeat_once:: check ( cx, expr, recv, arg) ;
3302
+ } ,
3266
3303
( "splitn" | "rsplitn" , [ count_arg, pat_arg] ) => {
3267
3304
if let Some ( ( Constant :: Int ( count) , _) ) = constant ( cx, cx. typeck_results ( ) , count_arg) {
3268
3305
suspicious_splitn:: check ( cx, name, expr, recv, count) ;
0 commit comments