11mod bind_instead_of_map;
22mod bytes_nth;
3+ mod clone_on_copy;
34mod clone_on_ref_ptr;
45mod expect_used;
56mod filetype_is_file;
@@ -45,7 +46,6 @@ mod wrong_self_convention;
4546mod zst_offset;
4647
4748use std:: borrow:: Cow ;
48- use std:: iter;
4949
5050use bind_instead_of_map:: BindInsteadOfMap ;
5151use if_chain:: if_chain;
@@ -69,7 +69,7 @@ use crate::utils::{
6969 is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path, match_qpath, match_trait_method,
7070 match_type, meets_msrv, method_calls, method_chain_args, path_to_local_id, paths, remove_blocks, return_ty,
7171 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 ,
7373} ;
7474
7575declare_clippy_lint ! {
@@ -1781,7 +1781,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
17811781
17821782 let self_ty = cx. typeck_results ( ) . expr_ty_adjusted ( & args[ 0 ] ) ;
17831783 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) ;
17851785 clone_on_ref_ptr:: check ( cx, expr, & args[ 0 ] ) ;
17861786 }
17871787 if args. len ( ) == 1 && method_call. ident . name == sym ! ( to_string) {
@@ -2323,106 +2323,6 @@ fn lint_expect_fun_call(
23232323 ) ;
23242324}
23252325
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-
24262326fn lint_unnecessary_fold ( cx : & LateContext < ' _ > , expr : & hir:: Expr < ' _ > , fold_args : & [ hir:: Expr < ' _ > ] , fold_span : Span ) {
24272327 fn check_fold_with_op (
24282328 cx : & LateContext < ' _ > ,
0 commit comments