1
1
mod bind_instead_of_map;
2
2
mod bytes_nth;
3
+ mod clone_on_copy;
3
4
mod clone_on_ref_ptr;
4
5
mod expect_used;
5
6
mod filetype_is_file;
@@ -45,7 +46,6 @@ mod wrong_self_convention;
45
46
mod zst_offset;
46
47
47
48
use std:: borrow:: Cow ;
48
- use std:: iter;
49
49
50
50
use bind_instead_of_map:: BindInsteadOfMap ;
51
51
use if_chain:: if_chain;
@@ -69,7 +69,7 @@ use crate::utils::{
69
69
is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path, match_qpath, match_trait_method,
70
70
match_type, meets_msrv, method_calls, method_chain_args, path_to_local_id, paths, remove_blocks, return_ty,
71
71
single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint,
72
- span_lint_and_help, span_lint_and_sugg, span_lint_and_then , strip_pat_refs, sugg , walk_ptrs_ty_depth, SpanlessEq ,
72
+ span_lint_and_help, span_lint_and_sugg, strip_pat_refs, walk_ptrs_ty_depth, SpanlessEq ,
73
73
} ;
74
74
75
75
declare_clippy_lint ! {
@@ -1781,7 +1781,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
1781
1781
1782
1782
let self_ty = cx. typeck_results ( ) . expr_ty_adjusted ( & args[ 0 ] ) ;
1783
1783
if args. len ( ) == 1 && method_call. ident . name == sym:: clone {
1784
- lint_clone_on_copy ( cx, expr, & args[ 0 ] , self_ty) ;
1784
+ clone_on_copy :: check ( cx, expr, & args[ 0 ] , self_ty) ;
1785
1785
clone_on_ref_ptr:: check ( cx, expr, & args[ 0 ] ) ;
1786
1786
}
1787
1787
if args. len ( ) == 1 && method_call. ident . name == sym ! ( to_string) {
@@ -2323,106 +2323,6 @@ fn lint_expect_fun_call(
2323
2323
) ;
2324
2324
}
2325
2325
2326
- /// Checks for the `CLONE_ON_COPY` lint.
2327
- fn lint_clone_on_copy ( cx : & LateContext < ' _ > , expr : & hir:: Expr < ' _ > , arg : & hir:: Expr < ' _ > , arg_ty : Ty < ' _ > ) {
2328
- let ty = cx. typeck_results ( ) . expr_ty ( expr) ;
2329
- if let ty:: Ref ( _, inner, _) = arg_ty. kind ( ) {
2330
- if let ty:: Ref ( _, innermost, _) = inner. kind ( ) {
2331
- span_lint_and_then (
2332
- cx,
2333
- CLONE_DOUBLE_REF ,
2334
- expr. span ,
2335
- & format ! (
2336
- "using `clone` on a double-reference; \
2337
- this will copy the reference of type `{}` instead of cloning the inner type",
2338
- ty
2339
- ) ,
2340
- |diag| {
2341
- if let Some ( snip) = sugg:: Sugg :: hir_opt ( cx, arg) {
2342
- let mut ty = innermost;
2343
- let mut n = 0 ;
2344
- while let ty:: Ref ( _, inner, _) = ty. kind ( ) {
2345
- ty = inner;
2346
- n += 1 ;
2347
- }
2348
- let refs: String = iter:: repeat ( '&' ) . take ( n + 1 ) . collect ( ) ;
2349
- let derefs: String = iter:: repeat ( '*' ) . take ( n) . collect ( ) ;
2350
- let explicit = format ! ( "<{}{}>::clone({})" , refs, ty, snip) ;
2351
- diag. span_suggestion (
2352
- expr. span ,
2353
- "try dereferencing it" ,
2354
- format ! ( "{}({}{}).clone()" , refs, derefs, snip. deref( ) ) ,
2355
- Applicability :: MaybeIncorrect ,
2356
- ) ;
2357
- diag. span_suggestion (
2358
- expr. span ,
2359
- "or try being explicit if you are sure, that you want to clone a reference" ,
2360
- explicit,
2361
- Applicability :: MaybeIncorrect ,
2362
- ) ;
2363
- }
2364
- } ,
2365
- ) ;
2366
- return ; // don't report clone_on_copy
2367
- }
2368
- }
2369
-
2370
- if is_copy ( cx, ty) {
2371
- let snip;
2372
- if let Some ( snippet) = sugg:: Sugg :: hir_opt ( cx, arg) {
2373
- let parent = cx. tcx . hir ( ) . get_parent_node ( expr. hir_id ) ;
2374
- match & cx. tcx . hir ( ) . get ( parent) {
2375
- hir:: Node :: Expr ( parent) => match parent. kind {
2376
- // &*x is a nop, &x.clone() is not
2377
- hir:: ExprKind :: AddrOf ( ..) => return ,
2378
- // (*x).func() is useless, x.clone().func() can work in case func borrows mutably
2379
- hir:: ExprKind :: MethodCall ( _, _, parent_args, _) if expr. hir_id == parent_args[ 0 ] . hir_id => {
2380
- return ;
2381
- } ,
2382
-
2383
- _ => { } ,
2384
- } ,
2385
- hir:: Node :: Stmt ( stmt) => {
2386
- if let hir:: StmtKind :: Local ( ref loc) = stmt. kind {
2387
- if let hir:: PatKind :: Ref ( ..) = loc. pat . kind {
2388
- // let ref y = *x borrows x, let ref y = x.clone() does not
2389
- return ;
2390
- }
2391
- }
2392
- } ,
2393
- _ => { } ,
2394
- }
2395
-
2396
- // x.clone() might have dereferenced x, possibly through Deref impls
2397
- if cx. typeck_results ( ) . expr_ty ( arg) == ty {
2398
- snip = Some ( ( "try removing the `clone` call" , format ! ( "{}" , snippet) ) ) ;
2399
- } else {
2400
- let deref_count = cx
2401
- . typeck_results ( )
2402
- . expr_adjustments ( arg)
2403
- . iter ( )
2404
- . filter ( |adj| matches ! ( adj. kind, ty:: adjustment:: Adjust :: Deref ( _) ) )
2405
- . count ( ) ;
2406
- let derefs: String = iter:: repeat ( '*' ) . take ( deref_count) . collect ( ) ;
2407
- snip = Some ( ( "try dereferencing it" , format ! ( "{}{}" , derefs, snippet) ) ) ;
2408
- }
2409
- } else {
2410
- snip = None ;
2411
- }
2412
- span_lint_and_then (
2413
- cx,
2414
- CLONE_ON_COPY ,
2415
- expr. span ,
2416
- & format ! ( "using `clone` on type `{}` which implements the `Copy` trait" , ty) ,
2417
- |diag| {
2418
- if let Some ( ( text, snip) ) = snip {
2419
- diag. span_suggestion ( expr. span , text, snip, Applicability :: MachineApplicable ) ;
2420
- }
2421
- } ,
2422
- ) ;
2423
- }
2424
- }
2425
-
2426
2326
fn lint_unnecessary_fold ( cx : & LateContext < ' _ > , expr : & hir:: Expr < ' _ > , fold_args : & [ hir:: Expr < ' _ > ] , fold_span : Span ) {
2427
2327
fn check_fold_with_op (
2428
2328
cx : & LateContext < ' _ > ,
0 commit comments