@@ -2,9 +2,10 @@ use clippy_utils::{
2
2
diagnostics:: { span_lint, span_lint_and_sugg} ,
3
3
higher:: { get_vec_init_kind, VecInitKind } ,
4
4
source:: snippet,
5
- visitors:: expr_visitor_no_bodies ,
5
+ visitors:: for_each_expr ,
6
6
} ;
7
- use hir:: { intravisit:: Visitor , ExprKind , Local , PatKind , PathSegment , QPath , StmtKind } ;
7
+ use core:: ops:: ControlFlow ;
8
+ use hir:: { Expr , ExprKind , Local , PatKind , PathSegment , QPath , StmtKind } ;
8
9
use rustc_errors:: Applicability ;
9
10
use rustc_hir as hir;
10
11
use rustc_lint:: { LateContext , LateLintPass } ;
@@ -58,38 +59,31 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec {
58
59
&& let PatKind :: Binding ( _, _, ident, _) = pat. kind
59
60
&& let Some ( vec_init_kind) = get_vec_init_kind ( cx, init)
60
61
{
61
- // finds use of `_.read(&mut v)`
62
- let mut read_found = false ;
63
- let mut visitor = expr_visitor_no_bodies ( |expr| {
64
- if let ExprKind :: MethodCall ( path, _self, [ arg] , _) = expr. kind
62
+ let visitor = |expr : & Expr < ' _ > | {
63
+ if let ExprKind :: MethodCall ( path, _, [ arg] , _) = expr. kind
65
64
&& let PathSegment { ident : read_or_read_exact, .. } = * path
66
65
&& matches ! ( read_or_read_exact. as_str( ) , "read" | "read_exact" )
67
66
&& let ExprKind :: AddrOf ( _, hir:: Mutability :: Mut , inner) = arg. kind
68
67
&& let ExprKind :: Path ( QPath :: Resolved ( None , inner_path) ) = inner. kind
69
68
&& let [ inner_seg] = inner_path. segments
70
69
&& ident. name == inner_seg. ident . name
71
70
{
72
- read_found = true ;
71
+ ControlFlow :: Break ( ( ) )
72
+ } else {
73
+ ControlFlow :: Continue ( ( ) )
73
74
}
74
- !read_found
75
- } ) ;
75
+ } ;
76
76
77
- let next_stmt_span;
78
- if idx == block. stmts . len ( ) - 1 {
77
+ let ( read_found, next_stmt_span) =
78
+ if let Some ( next_stmt) = block. stmts . get ( idx + 1 ) {
79
+ // case { .. stmt; stmt; .. }
80
+ ( for_each_expr ( next_stmt, visitor) . is_some ( ) , next_stmt. span )
81
+ } else if let Some ( e) = block. expr {
79
82
// case { .. stmt; expr }
80
- if let Some ( e) = block. expr {
81
- visitor. visit_expr ( e) ;
82
- next_stmt_span = e. span ;
83
- } else {
84
- return ;
85
- }
83
+ ( for_each_expr ( e, visitor) . is_some ( ) , e. span )
86
84
} else {
87
- // case { .. stmt; stmt; .. }
88
- let next_stmt = & block. stmts [ idx + 1 ] ;
89
- visitor. visit_stmt ( next_stmt) ;
90
- next_stmt_span = next_stmt. span ;
91
- }
92
- drop ( visitor) ;
85
+ return
86
+ } ;
93
87
94
88
if read_found && !next_stmt_span. from_expansion ( ) {
95
89
let applicability = Applicability :: MaybeIncorrect ;
0 commit comments