1
- use rustc_hir:: { Expr , ExprKind , HirId , Stmt , StmtKind } ;
2
- use rustc_middle:: ty:: { self , Ty } ;
1
+ use rustc_hir:: { Expr , ExprKind , Stmt , StmtKind } ;
2
+ use rustc_middle:: ty:: { self } ;
3
3
use rustc_session:: { declare_lint, declare_lint_pass} ;
4
+ use rustc_span:: sym;
4
5
5
6
use crate :: lints:: MappingToUnit ;
6
7
use crate :: { LateContext , LateLintPass , LintContext } ;
@@ -39,58 +40,43 @@ declare_lint_pass!(MapUnitFn => [MAP_UNIT_FN]);
39
40
40
41
impl < ' tcx > LateLintPass < ' tcx > for MapUnitFn {
41
42
fn check_stmt ( & mut self , cx : & LateContext < ' tcx > , stmt : & Stmt < ' _ > ) {
42
- if stmt . span . from_expansion ( ) {
43
+ let StmtKind :: Semi ( expr ) = stmt . kind else {
43
44
return ;
44
- }
45
-
46
- if let StmtKind :: Semi ( expr) = stmt. kind
47
- && let ExprKind :: MethodCall ( path, receiver, args, span) = expr. kind
45
+ } ;
46
+ let ExprKind :: MethodCall ( path, receiver, [ arg] , span) = expr. kind else {
47
+ return ;
48
+ } ;
49
+ if path. ident . name != sym:: map
50
+ || stmt. span . from_expansion ( )
51
+ || receiver. span . from_expansion ( )
52
+ || arg. span . from_expansion ( )
53
+ || !is_impl_slice ( cx, receiver)
54
+ || !cx
55
+ . typeck_results ( )
56
+ . type_dependent_def_id ( expr. hir_id )
57
+ . is_some_and ( |id| cx. tcx . is_diagnostic_item ( sym:: IteratorMap , id) )
48
58
{
49
- if path. ident . name . as_str ( ) == "map" {
50
- if receiver. span . from_expansion ( )
51
- || args. iter ( ) . any ( |e| e. span . from_expansion ( ) )
52
- || !is_impl_slice ( cx, receiver)
53
- || !is_diagnostic_name ( cx, expr. hir_id , "IteratorMap" )
54
- {
55
- return ;
56
- }
57
- let arg_ty = cx. typeck_results ( ) . expr_ty ( & args[ 0 ] ) ;
58
- let default_span = args[ 0 ] . span ;
59
- if let ty:: FnDef ( id, _) = arg_ty. kind ( ) {
60
- let fn_ty = cx. tcx . fn_sig ( id) . skip_binder ( ) ;
61
- let ret_ty = fn_ty. output ( ) . skip_binder ( ) ;
62
- if is_unit_type ( ret_ty) {
63
- cx. emit_span_lint (
64
- MAP_UNIT_FN ,
65
- span,
66
- MappingToUnit {
67
- function_label : cx. tcx . span_of_impl ( * id) . unwrap_or ( default_span) ,
68
- argument_label : args[ 0 ] . span ,
69
- map_label : span,
70
- suggestion : path. ident . span ,
71
- replace : "for_each" . to_string ( ) ,
72
- } ,
73
- )
74
- }
75
- } else if let ty:: Closure ( id, subs) = arg_ty. kind ( ) {
76
- let cl_ty = subs. as_closure ( ) . sig ( ) ;
77
- let ret_ty = cl_ty. output ( ) . skip_binder ( ) ;
78
- if is_unit_type ( ret_ty) {
79
- cx. emit_span_lint (
80
- MAP_UNIT_FN ,
81
- span,
82
- MappingToUnit {
83
- function_label : cx. tcx . span_of_impl ( * id) . unwrap_or ( default_span) ,
84
- argument_label : args[ 0 ] . span ,
85
- map_label : span,
86
- suggestion : path. ident . span ,
87
- replace : "for_each" . to_string ( ) ,
88
- } ,
89
- )
90
- }
91
- }
92
- }
59
+ return ;
93
60
}
61
+ let ( id, sig) = match * cx. typeck_results ( ) . expr_ty ( arg) . kind ( ) {
62
+ ty:: Closure ( id, subs) => ( id, subs. as_closure ( ) . sig ( ) ) ,
63
+ ty:: FnDef ( id, _) => ( id, cx. tcx . fn_sig ( id) . skip_binder ( ) ) ,
64
+ _ => return ,
65
+ } ;
66
+ let ret_ty = sig. output ( ) . skip_binder ( ) ;
67
+ if !( ret_ty. is_unit ( ) || ret_ty. is_never ( ) ) {
68
+ return ;
69
+ }
70
+ cx. emit_span_lint (
71
+ MAP_UNIT_FN ,
72
+ span,
73
+ MappingToUnit {
74
+ function_label : cx. tcx . span_of_impl ( id) . unwrap_or ( arg. span ) ,
75
+ argument_label : arg. span ,
76
+ map_label : span,
77
+ suggestion : path. ident . span ,
78
+ } ,
79
+ ) ;
94
80
}
95
81
}
96
82
@@ -102,18 +88,3 @@ fn is_impl_slice(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
102
88
}
103
89
false
104
90
}
105
-
106
- fn is_unit_type ( ty : Ty < ' _ > ) -> bool {
107
- ty. is_unit ( ) || ty. is_never ( )
108
- }
109
-
110
- fn is_diagnostic_name ( cx : & LateContext < ' _ > , id : HirId , name : & str ) -> bool {
111
- if let Some ( def_id) = cx. typeck_results ( ) . type_dependent_def_id ( id)
112
- && let Some ( item) = cx. tcx . get_diagnostic_name ( def_id)
113
- {
114
- if item. as_str ( ) == name {
115
- return true ;
116
- }
117
- }
118
- false
119
- }
0 commit comments