@@ -71,6 +71,7 @@ mod no_effect_replace;
71
71
mod obfuscated_if_else;
72
72
mod ok_expect;
73
73
mod open_options;
74
+ mod option_as_ref_cloned;
74
75
mod option_as_ref_deref;
75
76
mod option_map_or_err_ok;
76
77
mod option_map_or_none;
@@ -3885,6 +3886,30 @@ declare_clippy_lint! {
3885
3886
pub STR_SPLIT_AT_NEWLINE ,
3886
3887
pedantic,
3887
3888
"splitting a trimmed string at hard-coded newlines"
3889
+
3890
+ declare_clippy_lint! {
3891
+ /// ### What it does
3892
+ /// Checks for usage of `.as_ref().cloned()` on `Option`s
3893
+ ///
3894
+ /// ### Why is this bad?
3895
+ /// This can be written more concisely by cloning the option directly.
3896
+ ///
3897
+ /// ### Example
3898
+ /// ```no_run
3899
+ /// fn foo(bar: &Option<Vec<u8>>) -> Option<Vec<u8>> {
3900
+ /// bar.as_ref().cloned()
3901
+ /// }
3902
+ /// ```
3903
+ /// Use instead:
3904
+ /// ```no_run
3905
+ /// fn foo(bar: &Option<Vec<u8>>) -> Option<Vec<u8>> {
3906
+ /// bar.clone()
3907
+ /// }
3908
+ /// ```
3909
+ #[ clippy:: version = "1.77.0" ]
3910
+ pub OPTION_AS_REF_CLONED ,
3911
+ pedantic,
3912
+ "cloning an `Option` via `as_ref().cloned()`"
3888
3913
}
3889
3914
3890
3915
pub struct Methods {
@@ -4043,6 +4068,7 @@ impl_lint_pass!(Methods => [
4043
4068
ITER_FILTER_IS_OK ,
4044
4069
MANUAL_IS_VARIANT_AND ,
4045
4070
STR_SPLIT_AT_NEWLINE ,
4071
+ OPTION_AS_REF_CLONED ,
4046
4072
] ) ;
4047
4073
4048
4074
/// Extracts a method call name, args, and `Span` of the method name.
@@ -4290,7 +4316,12 @@ impl Methods {
4290
4316
( "as_mut" , [ ] ) => useless_asref:: check( cx, expr, "as_mut" , recv) ,
4291
4317
( "as_ref" , [ ] ) => useless_asref:: check( cx, expr, "as_ref" , recv) ,
4292
4318
( "assume_init" , [ ] ) => uninit_assumed_init:: check( cx, expr, recv) ,
4293
- ( "cloned" , [ ] ) => cloned_instead_of_copied:: check ( cx, expr, recv, span, & self . msrv ) ,
4319
+ ( "cloned" , [ ] ) => {
4320
+ cloned_instead_of_copied:: check( cx, expr, recv, span, & self . msrv) ;
4321
+ if let Some ( ( "as_ref" , recv, .., as_ref_ident_span) ) = method_call( recv) {
4322
+ option_as_ref_cloned:: check( cx, recv, as_ref_ident_span, span) ;
4323
+ }
4324
+ } ,
4294
4325
( "collect" , [ ] ) if is_trait_method( cx, expr, sym:: Iterator ) => {
4295
4326
needless_collect:: check( cx, span, expr, recv, call_span) ;
4296
4327
match method_call( recv) {
0 commit comments