11use crate :: utils:: {
2- match_def_path, match_trait_method, paths, same_tys, snippet, snippet_with_macro_callsite, span_lint_and_sugg,
2+ is_type_diagnostic_item, match_def_path, match_trait_method, paths, same_tys, snippet, snippet_with_macro_callsite,
3+ span_lint_and_help, span_lint_and_sugg,
34} ;
5+ use if_chain:: if_chain;
46use rustc_errors:: Applicability ;
57use rustc_hir:: { Expr , ExprKind , HirId , MatchSource } ;
68use rustc_lint:: { LateContext , LateLintPass } ;
9+ use rustc_middle:: ty;
710use rustc_session:: { declare_tool_lint, impl_lint_pass} ;
811
912declare_clippy_lint ! {
10- /// **What it does:** Checks for `Into`/ `From`/ `IntoIter` calls that useless converts
13+ /// **What it does:** Checks for `Into`, `From`, `TryFrom`, `IntoIter` calls that useless converts
1114 /// to the same type as caller.
1215 ///
1316 /// **Why is this bad?** Redundant code.
@@ -26,7 +29,7 @@ declare_clippy_lint! {
2629 /// ```
2730 pub USELESS_CONVERSION ,
2831 complexity,
29- "calls to `Into`/ `From`/ `IntoIter` that performs useless conversions to the same type"
32+ "calls to `Into`, `From`, `TryFrom`, `IntoIter` that performs useless conversions to the same type"
3033}
3134
3235#[ derive( Default ) ]
@@ -68,7 +71,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessConversion {
6871 cx,
6972 USELESS_CONVERSION ,
7073 e. span ,
71- "useless conversion" ,
74+ "Useless conversion to the same type " ,
7275 "consider removing `.into()`" ,
7376 sugg,
7477 Applicability :: MachineApplicable , // snippet
@@ -84,7 +87,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessConversion {
8487 cx,
8588 USELESS_CONVERSION ,
8689 e. span ,
87- "useless conversion" ,
90+ "Useless conversion to the same type " ,
8891 "consider removing `.into_iter()`" ,
8992 sugg,
9093 Applicability :: MachineApplicable , // snippet
@@ -94,11 +97,35 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessConversion {
9497 } ,
9598
9699 ExprKind :: Call ( ref path, ref args) => {
97- if let ExprKind :: Path ( ref qpath) = path. kind {
98- if let Some ( def_id) = cx. tables . qpath_res ( qpath, path. hir_id ) . opt_def_id ( ) {
100+ if_chain ! {
101+ if args. len( ) == 1 ;
102+ if let ExprKind :: Path ( ref qpath) = path. kind;
103+ if let Some ( def_id) = cx. tables. qpath_res( qpath, path. hir_id) . opt_def_id( ) ;
104+ let a = cx. tables. expr_ty( e) ;
105+ let b = cx. tables. expr_ty( & args[ 0 ] ) ;
106+
107+ then {
108+ if_chain! {
109+ if match_def_path( cx, def_id, & paths:: TRY_FROM ) ;
110+ if is_type_diagnostic_item( cx, a, sym!( result_type) ) ;
111+ if let ty:: Adt ( _, substs) = a. kind;
112+ if let Some ( a_type) = substs. types( ) . nth( 0 ) ;
113+ if same_tys( cx, a_type, b) ;
114+
115+ then {
116+ let hint = format!( "consider removing `{}()`" , snippet( cx, path. span, "TryFrom::try_from" ) ) ;
117+ span_lint_and_help(
118+ cx,
119+ USELESS_CONVERSION ,
120+ e. span,
121+ "Useless conversion to the same type" ,
122+ None ,
123+ & hint,
124+ ) ;
125+ }
126+ }
127+
99128 if match_def_path( cx, def_id, & paths:: FROM_FROM ) {
100- let a = cx. tables . expr_ty ( e) ;
101- let b = cx. tables . expr_ty ( & args[ 0 ] ) ;
102129 if same_tys( cx, a, b) {
103130 let sugg = snippet( cx, args[ 0 ] . span. source_callsite( ) , "<expr>" ) . into_owned( ) ;
104131 let sugg_msg =
@@ -107,7 +134,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessConversion {
107134 cx,
108135 USELESS_CONVERSION ,
109136 e. span,
110- "useless conversion" ,
137+ "Useless conversion to the same type " ,
111138 & sugg_msg,
112139 sugg,
113140 Applicability :: MachineApplicable , // snippet
0 commit comments