1
1
use clippy_utils:: diagnostics:: { span_lint, span_lint_and_sugg, span_lint_and_then, span_lint_hir_and_then} ;
2
2
use clippy_utils:: source:: { snippet, snippet_opt} ;
3
- use clippy_utils:: ty:: implements_trait;
3
+ use clippy_utils:: ty:: { implements_trait, is_copy } ;
4
4
use if_chain:: if_chain;
5
5
use rustc_ast:: ast:: LitKind ;
6
6
use rustc_errors:: Applicability ;
@@ -20,8 +20,8 @@ use rustc_span::symbol::sym;
20
20
use clippy_utils:: consts:: { constant, Constant } ;
21
21
use clippy_utils:: sugg:: Sugg ;
22
22
use clippy_utils:: {
23
- get_item_name, get_parent_expr, in_constant, is_diag_trait_item , is_integer_const, iter_input_pats,
24
- last_path_segment , match_any_def_paths, path_def_id, paths, unsext, SpanlessEq ,
23
+ get_item_name, get_parent_expr, in_constant, is_integer_const, iter_input_pats, last_path_segment ,
24
+ match_any_def_paths, path_def_id, paths, unsext, SpanlessEq ,
25
25
} ;
26
26
27
27
declare_clippy_lint ! {
@@ -569,33 +569,34 @@ fn check_to_owned(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left:
569
569
} )
570
570
}
571
571
572
- let ( arg_ty, snip) = match expr. kind {
573
- ExprKind :: MethodCall ( .., args, _) if args. len ( ) == 1 => {
574
- if_chain ! (
575
- if let Some ( expr_def_id) = cx. typeck_results( ) . type_dependent_def_id( expr. hir_id) ;
576
- if is_diag_trait_item( cx, expr_def_id, sym:: ToString )
577
- || is_diag_trait_item( cx, expr_def_id, sym:: ToOwned ) ;
578
- then {
579
- ( cx. typeck_results( ) . expr_ty( & args[ 0 ] ) , snippet( cx, args[ 0 ] . span, ".." ) )
580
- } else {
581
- return ;
582
- }
583
- )
572
+ let typeck = cx. typeck_results ( ) ;
573
+ let ( arg, arg_span) = match expr. kind {
574
+ ExprKind :: MethodCall ( .., [ arg] , _)
575
+ if typeck
576
+ . type_dependent_def_id ( expr. hir_id )
577
+ . and_then ( |id| cx. tcx . trait_of_item ( id) )
578
+ . map_or ( false , |id| {
579
+ matches ! ( cx. tcx. get_diagnostic_name( id) , Some ( sym:: ToString | sym:: ToOwned ) )
580
+ } ) =>
581
+ {
582
+ ( arg, arg. span )
584
583
} ,
585
- ExprKind :: Call ( path, [ arg] ) => {
584
+ ExprKind :: Call ( path, [ arg] )
586
585
if path_def_id ( cx, path)
587
586
. and_then ( |id| match_any_def_paths ( cx, id, & [ & paths:: FROM_STR_METHOD , & paths:: FROM_FROM ] ) )
588
- . is_some ( )
589
- {
590
- ( cx. typeck_results ( ) . expr_ty ( arg) , snippet ( cx, arg. span , ".." ) )
591
- } else {
592
- return ;
593
- }
587
+ . map_or ( false , |idx| match idx {
588
+ 0 => true ,
589
+ 1 => !is_copy ( cx, typeck. expr_ty ( expr) ) ,
590
+ _ => false ,
591
+ } ) =>
592
+ {
593
+ ( arg, arg. span )
594
594
} ,
595
595
_ => return ,
596
596
} ;
597
597
598
- let other_ty = cx. typeck_results ( ) . expr_ty ( other) ;
598
+ let arg_ty = typeck. expr_ty ( arg) ;
599
+ let other_ty = typeck. expr_ty ( other) ;
599
600
600
601
let without_deref = symmetric_partial_eq ( cx, arg_ty, other_ty) . unwrap_or_default ( ) ;
601
602
let with_deref = arg_ty
@@ -627,13 +628,14 @@ fn check_to_owned(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left:
627
628
return ;
628
629
}
629
630
631
+ let arg_snip = snippet ( cx, arg_span, ".." ) ;
630
632
let expr_snip;
631
633
let eq_impl;
632
634
if with_deref. is_implemented ( ) {
633
- expr_snip = format ! ( "*{}" , snip ) ;
635
+ expr_snip = format ! ( "*{}" , arg_snip ) ;
634
636
eq_impl = with_deref;
635
637
} else {
636
- expr_snip = snip . to_string ( ) ;
638
+ expr_snip = arg_snip . to_string ( ) ;
637
639
eq_impl = without_deref;
638
640
} ;
639
641
0 commit comments