11use clippy_utils:: diagnostics:: { span_lint, span_lint_and_sugg, span_lint_and_then, span_lint_hir_and_then} ;
22use clippy_utils:: source:: { snippet, snippet_opt} ;
3- use clippy_utils:: ty:: implements_trait;
3+ use clippy_utils:: ty:: { implements_trait, is_copy } ;
44use if_chain:: if_chain;
55use rustc_ast:: ast:: LitKind ;
66use rustc_errors:: Applicability ;
@@ -20,8 +20,8 @@ use rustc_span::symbol::sym;
2020use clippy_utils:: consts:: { constant, Constant } ;
2121use clippy_utils:: sugg:: Sugg ;
2222use 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 ,
2525} ;
2626
2727declare_clippy_lint ! {
@@ -569,33 +569,34 @@ fn check_to_owned(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left:
569569 } )
570570 }
571571
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 )
584583 } ,
585- ExprKind :: Call ( path, [ arg] ) => {
584+ ExprKind :: Call ( path, [ arg] )
586585 if path_def_id ( cx, path)
587586 . 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 )
594594 } ,
595595 _ => return ,
596596 } ;
597597
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) ;
599600
600601 let without_deref = symmetric_partial_eq ( cx, arg_ty, other_ty) . unwrap_or_default ( ) ;
601602 let with_deref = arg_ty
@@ -627,13 +628,14 @@ fn check_to_owned(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left:
627628 return ;
628629 }
629630
631+ let arg_snip = snippet ( cx, arg_span, ".." ) ;
630632 let expr_snip;
631633 let eq_impl;
632634 if with_deref. is_implemented ( ) {
633- expr_snip = format ! ( "*{}" , snip ) ;
635+ expr_snip = format ! ( "*{}" , arg_snip ) ;
634636 eq_impl = with_deref;
635637 } else {
636- expr_snip = snip . to_string ( ) ;
638+ expr_snip = arg_snip . to_string ( ) ;
637639 eq_impl = without_deref;
638640 } ;
639641
0 commit comments