summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs')
-rw-r--r--src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs45
1 files changed, 19 insertions, 26 deletions
diff --git a/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs b/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs
index 2882ba033..fa1078588 100644
--- a/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs
+++ b/src/tools/clippy/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};
@@ -43,7 +44,7 @@ declare_clippy_lint! {
/// ```
#[clippy::version = "1.63.0"]
pub READ_ZERO_BYTE_VEC,
- nursery,
+ correctness,
"checks for reads into a zero-length `Vec`"
}
declare_lint_pass!(ReadZeroByteVec => [READ_ZERO_BYTE_VEC]);
@@ -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;
@@ -101,9 +95,8 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec {
next_stmt_span,
"reading zero byte data to `Vec`",
"try",
- format!("{}.resize({}, 0); {}",
+ format!("{}.resize({len}, 0); {}",
ident.as_str(),
- len,
snippet(cx, next_stmt_span, "..")
),
applicability,