about summary refs log tree commit diff
path: root/clippy_lints/src/read_zero_byte_vec.rs
diff options
context:
space:
mode:
Diffstat (limited to 'clippy_lints/src/read_zero_byte_vec.rs')
-rw-r--r--clippy_lints/src/read_zero_byte_vec.rs40
1 files changed, 17 insertions, 23 deletions
diff --git a/clippy_lints/src/read_zero_byte_vec.rs b/clippy_lints/src/read_zero_byte_vec.rs
index ae80b6f1269..fa107858863 100644
--- a/clippy_lints/src/read_zero_byte_vec.rs
+++ b/clippy_lints/src/read_zero_byte_vec.rs
@@ -2,9 +2,10 @@ use clippy_utils::{
     diagnostics::{span_lint, span_lint_and_sugg},
     higher::{get_vec_init_kind, VecInitKind},
     source::snippet,
-    visitors::expr_visitor_no_bodies,
+    visitors::for_each_expr,
 };
-use hir::{intravisit::Visitor, ExprKind, Local, PatKind, PathSegment, QPath, StmtKind};
+use core::ops::ControlFlow;
+use hir::{Expr, ExprKind, Local, PatKind, PathSegment, QPath, StmtKind};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
@@ -58,10 +59,8 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec {
                 && let PatKind::Binding(_, _, ident, _) = pat.kind
                 && let Some(vec_init_kind) = get_vec_init_kind(cx, init)
             {
-                // finds use of `_.read(&mut v)`
-                let mut read_found = false;
-                let mut visitor = expr_visitor_no_bodies(|expr| {
-                    if let ExprKind::MethodCall(path, _self, [arg], _) = expr.kind
+                let visitor = |expr: &Expr<'_>| {
+                    if let ExprKind::MethodCall(path, _, [arg], _) = expr.kind
                         && let PathSegment { ident: read_or_read_exact, .. } = *path
                         && matches!(read_or_read_exact.as_str(), "read" | "read_exact")
                         && let ExprKind::AddrOf(_, hir::Mutability::Mut, inner) = arg.kind
@@ -69,27 +68,22 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec {
                         && let [inner_seg] = inner_path.segments
                         && ident.name == inner_seg.ident.name
                     {
-                        read_found = true;
+                        ControlFlow::Break(())
+                    } else {
+                        ControlFlow::Continue(())
                     }
-                    !read_found
-                });
+                };
 
-                let next_stmt_span;
-                if idx == block.stmts.len() - 1 {
+                let (read_found, next_stmt_span) =
+                if let Some(next_stmt) = block.stmts.get(idx + 1) {
+                    // case { .. stmt; stmt; .. }
+                    (for_each_expr(next_stmt, visitor).is_some(), next_stmt.span)
+                } else if let Some(e) = block.expr {
                     // case { .. stmt; expr }
-                    if let Some(e) = block.expr {
-                        visitor.visit_expr(e);
-                        next_stmt_span = e.span;
-                    } else {
-                        return;
-                    }
+                    (for_each_expr(e, visitor).is_some(), e.span)
                 } else {
-                    // case { .. stmt; stmt; .. }
-                    let next_stmt = &block.stmts[idx + 1];
-                    visitor.visit_stmt(next_stmt);
-                    next_stmt_span = next_stmt.span;
-                }
-                drop(visitor);
+                    return
+                };
 
                 if read_found && !next_stmt_span.from_expansion() {
                     let applicability = Applicability::MaybeIncorrect;