1
- use clippy_utils:: diagnostics:: span_lint_and_sugg ;
1
+ use clippy_utils:: diagnostics:: span_lint_and_then ;
2
2
use clippy_utils:: get_parent_expr;
3
3
use clippy_utils:: ty:: implements_trait;
4
4
use rustc_errors:: Applicability ;
5
5
use rustc_hir:: { Expr , ExprKind } ;
6
6
use rustc_lint:: LateContext ;
7
7
use rustc_middle:: ty;
8
+ use rustc_middle:: ty:: print:: with_forced_trimmed_paths;
8
9
use rustc_span:: { sym, Span } ;
9
10
10
11
use super :: UNNECESSARY_FALLIBLE_CONVERSIONS ;
@@ -42,6 +43,7 @@ fn check<'tcx>(
42
43
// (else there would be conflicting impls, even with #![feature(spec)]), so we don't even need to check
43
44
// what `<T as TryFrom<U>>::Error` is: it's always `Infallible`
44
45
&& implements_trait ( cx, self_ty, from_into_trait, & [ other_ty] )
46
+ && let Some ( other_ty) = other_ty. as_type ( )
45
47
{
46
48
let parent_unwrap_call = get_parent_expr ( cx, expr) . and_then ( |parent| {
47
49
if let ExprKind :: MethodCall ( path, .., span) = parent. kind
@@ -52,8 +54,7 @@ fn check<'tcx>(
52
54
None
53
55
}
54
56
} ) ;
55
-
56
- let ( sugg, span, applicability) = match kind {
57
+ let ( source_ty, target_ty, sugg, span, applicability) = match kind {
57
58
FunctionKind :: TryIntoMethod if let Some ( unwrap_span) = parent_unwrap_call => {
58
59
// Extend the span to include the unwrap/expect call:
59
60
// `foo.try_into().expect("..")`
@@ -63,24 +64,41 @@ fn check<'tcx>(
63
64
// so that can be machine-applicable
64
65
65
66
(
67
+ self_ty,
68
+ other_ty,
66
69
"into()" ,
67
70
primary_span. with_hi ( unwrap_span. hi ( ) ) ,
68
71
Applicability :: MachineApplicable ,
69
72
)
70
73
} ,
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 ) ,
74
89
} ;
75
90
76
- span_lint_and_sugg (
91
+ span_lint_and_then (
77
92
cx,
78
93
UNNECESSARY_FALLIBLE_CONVERSIONS ,
79
94
span,
80
95
"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
+ } ,
84
102
) ;
85
103
}
86
104
}
0 commit comments