@@ -12,15 +12,15 @@ use super::UNNECESSARY_FALLIBLE_CONVERSIONS;
1212
1313/// What function is being called and whether that call is written as a method call or a function
1414/// call
15- #[ derive( Copy , Clone ) ]
15+ #[ derive( Clone ) ]
1616#[ expect( clippy:: enum_variant_names) ]
1717enum FunctionKind {
1818 /// `T::try_from(U)`
19- TryFromFunction ,
19+ TryFromFunction ( Option < Vec < Span > > ) ,
2020 /// `t.try_into()`
2121 TryIntoMethod ,
2222 /// `U::try_into(t)`
23- TryIntoFunction ,
23+ TryIntoFunction ( Option < Vec < Span > > ) ,
2424}
2525
2626fn check < ' tcx > (
@@ -29,15 +29,14 @@ fn check<'tcx>(
2929 node_args : ty:: GenericArgsRef < ' tcx > ,
3030 kind : FunctionKind ,
3131 primary_span : Span ,
32- qpath : Option < & QPath < ' _ > > ,
3332) {
3433 if let & [ self_ty, other_ty] = node_args. as_slice ( )
3534 // useless_conversion already warns `T::try_from(T)`, so ignore it here
3635 && self_ty != other_ty
3736 && let Some ( self_ty) = self_ty. as_type ( )
3837 && let Some ( from_into_trait) = cx. tcx . get_diagnostic_item ( match kind {
39- FunctionKind :: TryFromFunction => sym:: From ,
40- FunctionKind :: TryIntoMethod | FunctionKind :: TryIntoFunction => sym:: Into ,
38+ FunctionKind :: TryFromFunction ( _ ) => sym:: From ,
39+ FunctionKind :: TryIntoMethod | FunctionKind :: TryIntoFunction ( _ ) => sym:: Into ,
4140 } )
4241 // If `T: TryFrom<U>` and `T: From<U>` both exist, then that means that the `TryFrom`
4342 // _must_ be from the blanket impl and cannot have been manually implemented
@@ -70,21 +69,12 @@ fn check<'tcx>(
7069 primary_span
7170 } ;
7271
73- let qpath_spans = qpath. and_then ( |qpath| match qpath {
74- QPath :: Resolved ( _, path) => {
75- let segments = path. segments . iter ( ) . map ( |seg| seg. ident ) . collect :: < Vec < _ > > ( ) ;
76- ( segments. len ( ) == 2 ) . then ( || vec ! [ segments[ 0 ] . span, segments[ 1 ] . span] )
77- } ,
78- QPath :: TypeRelative ( _, seg) => Some ( vec ! [ seg. ident. span] ) ,
79- QPath :: LangItem ( _, _) => unreachable ! ( "`TryFrom` and `TryInto` are not lang items" ) ,
80- } ) ;
81-
82- let ( source_ty, target_ty, sugg, applicability) = match ( kind, & qpath_spans, parent_unwrap_call) {
83- ( FunctionKind :: TryIntoMethod , _, Some ( unwrap_span) ) => {
72+ let ( source_ty, target_ty, sugg, applicability) = match ( kind, parent_unwrap_call) {
73+ ( FunctionKind :: TryIntoMethod , Some ( unwrap_span) ) => {
8474 let sugg = vec ! [ ( primary_span, String :: from( "into" ) ) , ( unwrap_span, String :: new( ) ) ] ;
8575 ( self_ty, other_ty, sugg, Applicability :: MachineApplicable )
8676 } ,
87- ( FunctionKind :: TryFromFunction , Some ( spans) , Some ( unwrap_span) ) => {
77+ ( FunctionKind :: TryFromFunction ( Some ( spans) ) , Some ( unwrap_span) ) => {
8878 let sugg = match spans. len ( ) {
8979 1 => vec ! [ ( spans[ 0 ] , String :: from( "from" ) ) , ( unwrap_span, String :: new( ) ) ] ,
9080 2 => vec ! [
@@ -96,7 +86,7 @@ fn check<'tcx>(
9686 } ;
9787 ( other_ty, self_ty, sugg, Applicability :: MachineApplicable )
9888 } ,
99- ( FunctionKind :: TryIntoFunction , Some ( spans) , Some ( unwrap_span) ) => {
89+ ( FunctionKind :: TryIntoFunction ( Some ( spans) ) , Some ( unwrap_span) ) => {
10090 let sugg = match spans. len ( ) {
10191 1 => vec ! [ ( spans[ 0 ] , String :: from( "into" ) ) , ( unwrap_span, String :: new( ) ) ] ,
10292 2 => vec ! [
@@ -108,15 +98,15 @@ fn check<'tcx>(
10898 } ;
10999 ( self_ty, other_ty, sugg, Applicability :: MachineApplicable )
110100 } ,
111- ( FunctionKind :: TryFromFunction , _ , _) => {
101+ ( FunctionKind :: TryFromFunction ( _ ) , _) => {
112102 let sugg = vec ! [ ( primary_span, String :: from( "From::from" ) ) ] ;
113103 ( other_ty, self_ty, sugg, Applicability :: Unspecified )
114104 } ,
115- ( FunctionKind :: TryIntoFunction , _ , _) => {
105+ ( FunctionKind :: TryIntoFunction ( _ ) , _) => {
116106 let sugg = vec ! [ ( primary_span, String :: from( "Into::into" ) ) ] ;
117107 ( self_ty, other_ty, sugg, Applicability :: Unspecified )
118108 } ,
119- ( FunctionKind :: TryIntoMethod , _, _ ) => {
109+ ( FunctionKind :: TryIntoMethod , _) => {
120110 let sugg = vec ! [ ( primary_span, String :: from( "into" ) ) ] ;
121111 ( self_ty, other_ty, sugg, Applicability :: Unspecified )
122112 } ,
@@ -147,7 +137,6 @@ pub(super) fn check_method(cx: &LateContext<'_>, expr: &Expr<'_>) {
147137 cx. typeck_results ( ) . node_args ( expr. hir_id ) ,
148138 FunctionKind :: TryIntoMethod ,
149139 path. ident . span ,
150- None ,
151140 ) ;
152141 }
153142}
@@ -160,17 +149,25 @@ pub(super) fn check_function(cx: &LateContext<'_>, expr: &Expr<'_>, callee: &Exp
160149 && let Some ( item_def_id) = cx. qpath_res ( qpath, callee. hir_id ) . opt_def_id ( )
161150 && let Some ( trait_def_id) = cx. tcx . trait_of_item ( item_def_id)
162151 {
152+ let qpath_spans = match qpath {
153+ QPath :: Resolved ( _, path) => {
154+ let segments = path. segments . iter ( ) . map ( |seg| seg. ident ) . collect :: < Vec < _ > > ( ) ;
155+ ( segments. len ( ) == 2 ) . then ( || vec ! [ segments[ 0 ] . span, segments[ 1 ] . span] )
156+ } ,
157+ QPath :: TypeRelative ( _, seg) => Some ( vec ! [ seg. ident. span] ) ,
158+ QPath :: LangItem ( _, _) => unreachable ! ( "`TryFrom` and `TryInto` are not lang items" ) ,
159+ } ;
160+
163161 check (
164162 cx,
165163 expr,
166164 cx. typeck_results ( ) . node_args ( callee. hir_id ) ,
167165 match cx. tcx . get_diagnostic_name ( trait_def_id) {
168- Some ( sym:: TryFrom ) => FunctionKind :: TryFromFunction ,
169- Some ( sym:: TryInto ) => FunctionKind :: TryIntoFunction ,
166+ Some ( sym:: TryFrom ) => FunctionKind :: TryFromFunction ( qpath_spans ) ,
167+ Some ( sym:: TryInto ) => FunctionKind :: TryIntoFunction ( qpath_spans ) ,
170168 _ => return ,
171169 } ,
172170 callee. span ,
173- Some ( qpath) ,
174171 ) ;
175172 }
176173}
0 commit comments