1+ use std:: iter:: once;
2+
13use clippy_utils:: diagnostics:: span_lint_and_sugg;
24use clippy_utils:: source:: snippet;
35use clippy_utils:: { get_expr_use_or_unification_node, is_res_lang_ctor, path_res, std_or_core} ;
46
57use rustc_errors:: Applicability ;
8+ use rustc_hir:: def_id:: DefId ;
9+ use rustc_hir:: hir_id:: HirId ;
610use rustc_hir:: LangItem :: { OptionNone , OptionSome } ;
711use rustc_hir:: { Expr , ExprKind , Node } ;
812use rustc_lint:: LateContext ;
@@ -25,7 +29,25 @@ impl IterType {
2529 }
2630}
2731
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 > ) {
2951 let item = match recv. kind {
3052 ExprKind :: Array ( [ ] ) => None ,
3153 ExprKind :: Array ( [ e] ) => Some ( e) ,
@@ -43,6 +65,25 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: &str, re
4365 let is_unified = match get_expr_use_or_unification_node ( cx. tcx , expr) {
4466 Some ( ( Node :: Expr ( parent) , child_id) ) => match parent. kind {
4567 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+ ) ,
4687 ExprKind :: If ( _, _, _)
4788 | ExprKind :: Match ( _, _, _)
4889 | ExprKind :: Closure ( _)
0 commit comments