1
+ use std:: iter:: once;
2
+
1
3
use clippy_utils:: diagnostics:: span_lint_and_sugg;
2
4
use clippy_utils:: source:: snippet;
3
5
use clippy_utils:: { get_expr_use_or_unification_node, is_res_lang_ctor, path_res, std_or_core} ;
4
6
5
7
use rustc_errors:: Applicability ;
8
+ use rustc_hir:: def_id:: DefId ;
9
+ use rustc_hir:: hir_id:: HirId ;
6
10
use rustc_hir:: LangItem :: { OptionNone , OptionSome } ;
7
11
use rustc_hir:: { Expr , ExprKind , Node } ;
8
12
use rustc_lint:: LateContext ;
@@ -25,7 +29,25 @@ impl IterType {
25
29
}
26
30
}
27
31
28
- pub ( super ) fn check ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > , method_name : & str , recv : & Expr < ' _ > ) {
32
+ fn is_arg_ty_unified_in_fn < ' tcx > (
33
+ cx : & LateContext < ' tcx > ,
34
+ fn_id : DefId ,
35
+ arg_id : HirId ,
36
+ args : impl Iterator < Item = & ' tcx Expr < ' tcx > > + Clone ,
37
+ ) -> bool {
38
+ let fn_sig = cx. tcx . fn_sig ( fn_id) . instantiate_identity ( ) ;
39
+ let arg_id_in_args = args. clone ( ) . position ( |e| e. hir_id == arg_id) . unwrap ( ) ;
40
+ let arg_ty_in_args = fn_sig. input ( arg_id_in_args) ;
41
+
42
+ cx. tcx . predicates_of ( fn_id) . predicates . iter ( ) . any ( |( clause, _) | {
43
+ clause
44
+ . as_projection_clause ( )
45
+ . and_then ( |p| p. map_bound ( |p| p. term . ty ( ) ) . transpose ( ) )
46
+ . is_some_and ( |ty| ty == arg_ty_in_args)
47
+ } )
48
+ }
49
+
50
+ pub ( super ) fn check < ' tcx > ( cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' tcx > , method_name : & str , recv : & ' tcx Expr < ' tcx > ) {
29
51
let item = match recv. kind {
30
52
ExprKind :: Array ( [ ] ) => None ,
31
53
ExprKind :: Array ( [ e] ) => Some ( e) ,
@@ -43,6 +65,25 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: &str, re
43
65
let is_unified = match get_expr_use_or_unification_node ( cx. tcx , expr) {
44
66
Some ( ( Node :: Expr ( parent) , child_id) ) => match parent. kind {
45
67
ExprKind :: If ( e, _, _) | ExprKind :: Match ( e, _, _) if e. hir_id == child_id => false ,
68
+ ExprKind :: Call (
69
+ Expr {
70
+ kind : ExprKind :: Path ( path) ,
71
+ hir_id,
72
+ ..
73
+ } ,
74
+ args,
75
+ ) => is_arg_ty_unified_in_fn (
76
+ cx,
77
+ cx. typeck_results ( ) . qpath_res ( path, * hir_id) . def_id ( ) ,
78
+ expr. hir_id ,
79
+ args. iter ( ) ,
80
+ ) ,
81
+ ExprKind :: MethodCall ( _name, recv, args, _span) => is_arg_ty_unified_in_fn (
82
+ cx,
83
+ cx. typeck_results ( ) . type_dependent_def_id ( parent. hir_id ) . unwrap ( ) ,
84
+ expr. hir_id ,
85
+ once ( recv) . chain ( args. iter ( ) ) ,
86
+ ) ,
46
87
ExprKind :: If ( _, _, _)
47
88
| ExprKind :: Match ( _, _, _)
48
89
| ExprKind :: Closure ( _)
0 commit comments