Skip to content

Commit 891523d

Browse files
committed
fix: read_zero_byte_vec suggests wrongly inside let stmt
1 parent b3d0a09 commit 891523d

File tree

3 files changed

+109
-10
lines changed

3 files changed

+109
-10
lines changed

clippy_lints/src/read_zero_byte_vec.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};
22
use clippy_utils::higher::{VecInitKind, get_vec_init_kind};
3-
use clippy_utils::source::snippet;
3+
use clippy_utils::source::{indent_of, snippet};
44
use clippy_utils::{get_enclosing_block, sym};
55

66
use rustc_errors::Applicability;
@@ -83,10 +83,12 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec {
8383
expr.span,
8484
"reading zero byte data to `Vec`",
8585
|diag| {
86+
let span = first_stmt_containing_expr(cx, expr).map_or(expr.span, |stmt| stmt.span);
87+
let indent = indent_of(cx, span).unwrap_or(0);
8688
diag.span_suggestion(
87-
expr.span,
89+
span.shrink_to_lo(),
8890
"try",
89-
format!("{}.resize({len}, 0); {}", ident, snippet(cx, expr.span, "..")),
91+
format!("{ident}.resize({len}, 0);\n{}", " ".repeat(indent)),
9092
applicability,
9193
);
9294
},
@@ -100,14 +102,15 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec {
100102
expr.span,
101103
"reading zero byte data to `Vec`",
102104
|diag| {
105+
let span = first_stmt_containing_expr(cx, expr).map_or(expr.span, |stmt| stmt.span);
106+
let indent = indent_of(cx, span).unwrap_or(0);
103107
diag.span_suggestion(
104-
expr.span,
108+
span.shrink_to_lo(),
105109
"try",
106110
format!(
107-
"{}.resize({}, 0); {}",
108-
ident,
111+
"{ident}.resize({}, 0);\n{}",
109112
snippet(cx, e.span, ".."),
110-
snippet(cx, expr.span, "..")
113+
" ".repeat(indent)
111114
),
112115
applicability,
113116
);
@@ -130,6 +133,16 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec {
130133
}
131134
}
132135

136+
fn first_stmt_containing_expr<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx hir::Stmt<'tcx>> {
137+
cx.tcx.hir_parent_iter(expr.hir_id).find_map(|(_, node)| {
138+
if let hir::Node::Stmt(stmt) = node {
139+
Some(stmt)
140+
} else {
141+
None
142+
}
143+
})
144+
}
145+
133146
struct ReadVecVisitor<'tcx> {
134147
local_id: HirId,
135148
read_zero_expr: Option<&'tcx Expr<'tcx>>,

tests/ui/read_zero_byte_vec.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,30 @@ fn allow_works<F: std::io::Read>(mut f: F) {
120120
}
121121

122122
fn main() {}
123+
124+
fn issue15575() -> usize {
125+
use std::io::Read;
126+
use std::net::TcpListener;
127+
128+
let listener = TcpListener::bind("127.0.0.1:9010").unwrap();
129+
let mut stream_and_addr = listener.accept().unwrap();
130+
let mut buf = Vec::with_capacity(32);
131+
let num_bytes_received = stream_and_addr.0.read(&mut buf).unwrap();
132+
//~^ read_zero_byte_vec
133+
134+
let cap = 1000;
135+
let mut buf = Vec::with_capacity(cap);
136+
let num_bytes_received = stream_and_addr.0.read(&mut buf).unwrap();
137+
//~^ read_zero_byte_vec
138+
139+
let cap = 1000;
140+
let mut buf = Vec::with_capacity(cap);
141+
let num_bytes_received = { stream_and_addr.0.read(&mut buf) }.unwrap();
142+
//~^ read_zero_byte_vec
143+
144+
use std::fs::File;
145+
let mut f = File::open("foo.txt").unwrap();
146+
let mut data = Vec::with_capacity(100);
147+
f.read(&mut data).unwrap()
148+
//~^ read_zero_byte_vec
149+
}

tests/ui/read_zero_byte_vec.stderr

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,27 @@ error: reading zero byte data to `Vec`
22
--> tests/ui/read_zero_byte_vec.rs:22:5
33
|
44
LL | f.read_exact(&mut data).unwrap();
5-
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `data.resize(20, 0); f.read_exact(&mut data)`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^
66
|
77
= note: `-D clippy::read-zero-byte-vec` implied by `-D warnings`
88
= help: to override `-D warnings` add `#[allow(clippy::read_zero_byte_vec)]`
9+
help: try
10+
|
11+
LL ~ data.resize(20, 0);
12+
LL ~ f.read_exact(&mut data).unwrap();
13+
|
914

1015
error: reading zero byte data to `Vec`
1116
--> tests/ui/read_zero_byte_vec.rs:28:5
1217
|
1318
LL | f.read_exact(&mut data2)?;
14-
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `data2.resize(cap, 0); f.read_exact(&mut data2)`
19+
| ^^^^^^^^^^^^^^^^^^^^^^^^
20+
|
21+
help: try
22+
|
23+
LL ~ data2.resize(cap, 0);
24+
LL ~ f.read_exact(&mut data2)?;
25+
|
1526

1627
error: reading zero byte data to `Vec`
1728
--> tests/ui/read_zero_byte_vec.rs:33:5
@@ -67,5 +78,53 @@ error: reading zero byte data to `Vec`
6778
LL | r.read_exact(&mut data2).await.unwrap();
6879
| ^^^^^^^^^^^^^^^^^^^^^^^^
6980

70-
error: aborting due to 11 previous errors
81+
error: reading zero byte data to `Vec`
82+
--> tests/ui/read_zero_byte_vec.rs:131:30
83+
|
84+
LL | let num_bytes_received = stream_and_addr.0.read(&mut buf).unwrap();
85+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
86+
|
87+
help: try
88+
|
89+
LL ~ buf.resize(32, 0);
90+
LL ~ let num_bytes_received = stream_and_addr.0.read(&mut buf).unwrap();
91+
|
92+
93+
error: reading zero byte data to `Vec`
94+
--> tests/ui/read_zero_byte_vec.rs:136:30
95+
|
96+
LL | let num_bytes_received = stream_and_addr.0.read(&mut buf).unwrap();
97+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
98+
|
99+
help: try
100+
|
101+
LL ~ buf.resize(cap, 0);
102+
LL ~ let num_bytes_received = stream_and_addr.0.read(&mut buf).unwrap();
103+
|
104+
105+
error: reading zero byte data to `Vec`
106+
--> tests/ui/read_zero_byte_vec.rs:141:32
107+
|
108+
LL | let num_bytes_received = { stream_and_addr.0.read(&mut buf) }.unwrap();
109+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
110+
|
111+
help: try
112+
|
113+
LL ~ buf.resize(cap, 0);
114+
LL ~ let num_bytes_received = { stream_and_addr.0.read(&mut buf) }.unwrap();
115+
|
116+
117+
error: reading zero byte data to `Vec`
118+
--> tests/ui/read_zero_byte_vec.rs:147:5
119+
|
120+
LL | f.read(&mut data).unwrap()
121+
| ^^^^^^^^^^^^^^^^^
122+
|
123+
help: try
124+
|
125+
LL ~ data.resize(100, 0);
126+
LL ~ f.read(&mut data).unwrap()
127+
|
128+
129+
error: aborting due to 15 previous errors
71130

0 commit comments

Comments
 (0)