1- use clippy_utils:: diagnostics:: span_lint_and_sugg ;
1+ use clippy_utils:: diagnostics:: span_lint_and_then ;
22use clippy_utils:: get_parent_expr;
33use clippy_utils:: ty:: implements_trait;
44use rustc_errors:: Applicability ;
55use rustc_hir:: { Expr , ExprKind } ;
66use rustc_lint:: LateContext ;
77use rustc_middle:: ty;
8+ use rustc_middle:: ty:: print:: with_forced_trimmed_paths;
89use rustc_span:: { sym, Span } ;
910
1011use super :: UNNECESSARY_FALLIBLE_CONVERSIONS ;
@@ -42,6 +43,7 @@ fn check<'tcx>(
4243 // (else there would be conflicting impls, even with #![feature(spec)]), so we don't even need to check
4344 // what `<T as TryFrom<U>>::Error` is: it's always `Infallible`
4445 && implements_trait ( cx, self_ty, from_into_trait, & [ other_ty] )
46+ && let Some ( other_ty) = other_ty. as_type ( )
4547 {
4648 let parent_unwrap_call = get_parent_expr ( cx, expr) . and_then ( |parent| {
4749 if let ExprKind :: MethodCall ( path, .., span) = parent. kind
@@ -52,8 +54,7 @@ fn check<'tcx>(
5254 None
5355 }
5456 } ) ;
55-
56- let ( sugg, span, applicability) = match kind {
57+ let ( source_ty, target_ty, sugg, span, applicability) = match kind {
5758 FunctionKind :: TryIntoMethod if let Some ( unwrap_span) = parent_unwrap_call => {
5859 // Extend the span to include the unwrap/expect call:
5960 // `foo.try_into().expect("..")`
@@ -63,24 +64,41 @@ fn check<'tcx>(
6364 // so that can be machine-applicable
6465
6566 (
67+ self_ty,
68+ other_ty,
6669 "into()" ,
6770 primary_span. with_hi ( unwrap_span. hi ( ) ) ,
6871 Applicability :: MachineApplicable ,
6972 )
7073 } ,
71- FunctionKind :: TryFromFunction => ( "From::from" , primary_span, Applicability :: Unspecified ) ,
72- FunctionKind :: TryIntoFunction => ( "Into::into" , primary_span, Applicability :: Unspecified ) ,
73- FunctionKind :: TryIntoMethod => ( "into" , primary_span, Applicability :: Unspecified ) ,
74+ FunctionKind :: TryFromFunction => (
75+ other_ty,
76+ self_ty,
77+ "From::from" ,
78+ primary_span,
79+ Applicability :: Unspecified ,
80+ ) ,
81+ FunctionKind :: TryIntoFunction => (
82+ self_ty,
83+ other_ty,
84+ "Into::into" ,
85+ primary_span,
86+ Applicability :: Unspecified ,
87+ ) ,
88+ FunctionKind :: TryIntoMethod => ( self_ty, other_ty, "into" , primary_span, Applicability :: Unspecified ) ,
7489 } ;
7590
76- span_lint_and_sugg (
91+ span_lint_and_then (
7792 cx,
7893 UNNECESSARY_FALLIBLE_CONVERSIONS ,
7994 span,
8095 "use of a fallible conversion when an infallible one could be used" ,
81- "use" ,
82- sugg. into ( ) ,
83- applicability,
96+ |diag| {
97+ with_forced_trimmed_paths ! ( {
98+ diag. note( format!( "converting `{source_ty}` to `{target_ty}` cannot fail" ) ) ;
99+ } ) ;
100+ diag. span_suggestion ( span, "use" , sugg, applicability) ;
101+ } ,
84102 ) ;
85103 }
86104}
0 commit comments