Auto merge of #5027 - sinkuu:vectored_io, r=phansch

Lint vectored IO in unused_io_amount lint

`read_vectored` & `write_vectored` require handling returned value likewise non-vectored methods. https://github.com/rust-lang/rust/issues/68041

---

changelog: lint vectored IO in `unused_io_amount` lint
This commit is contained in:
bors 2020-01-24 06:44:09 +00:00
commit 2c7cfa8321
3 changed files with 38 additions and 15 deletions

View File

@ -6,8 +6,8 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for unused written/read amount. /// **What it does:** Checks for unused written/read amount.
/// ///
/// **Why is this bad?** `io::Write::write` and `io::Read::read` are not /// **Why is this bad?** `io::Write::write(_vectored)` and
/// guaranteed to /// `io::Read::read(_vectored)` are not guaranteed to
/// process the entire buffer. They return how many bytes were processed, which /// process the entire buffer. They return how many bytes were processed, which
/// might be smaller /// might be smaller
/// than a given buffer's length. If you don't need to deal with /// than a given buffer's length. If you don't need to deal with
@ -67,20 +67,25 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedIoAmount {
fn check_method_call(cx: &LateContext<'_, '_>, call: &hir::Expr<'_>, expr: &hir::Expr<'_>) { fn check_method_call(cx: &LateContext<'_, '_>, call: &hir::Expr<'_>, expr: &hir::Expr<'_>) {
if let hir::ExprKind::MethodCall(ref path, _, _) = call.kind { if let hir::ExprKind::MethodCall(ref path, _, _) = call.kind {
let symbol = &*path.ident.as_str(); let symbol = &*path.ident.as_str();
if match_trait_method(cx, call, &paths::IO_READ) && symbol == "read" { let read_trait = match_trait_method(cx, call, &paths::IO_READ);
span_lint( let write_trait = match_trait_method(cx, call, &paths::IO_WRITE);
match (read_trait, write_trait, symbol) {
(true, _, "read") => span_lint(
cx, cx,
UNUSED_IO_AMOUNT, UNUSED_IO_AMOUNT,
expr.span, expr.span,
"handle read amount returned or use `Read::read_exact` instead", "read amount is not handled. Use `Read::read_exact` instead",
); ),
} else if match_trait_method(cx, call, &paths::IO_WRITE) && symbol == "write" { (true, _, "read_vectored") => span_lint(cx, UNUSED_IO_AMOUNT, expr.span, "read amount is not handled"),
span_lint( (_, true, "write") => span_lint(
cx, cx,
UNUSED_IO_AMOUNT, UNUSED_IO_AMOUNT,
expr.span, expr.span,
"handle written amount returned or use `Write::write_all` instead", "written amount is not handled. Use `Write::write_all` instead",
); ),
(_, true, "write_vectored") => span_lint(cx, UNUSED_IO_AMOUNT, expr.span, "written amount is not handled"),
_ => (),
} }
} }
} }

View File

@ -16,4 +16,10 @@ fn unwrap<T: io::Read + io::Write>(s: &mut T) {
s.read(&mut buf).unwrap(); s.read(&mut buf).unwrap();
} }
fn vectored<T: io::Read + io::Write>(s: &mut T) -> io::Result<()> {
s.read_vectored(&mut [io::IoSliceMut::new(&mut [])])?;
s.write_vectored(&[io::IoSlice::new(&[])])?;
Ok(())
}
fn main() {} fn main() {}

View File

@ -1,4 +1,4 @@
error: handle written amount returned or use `Write::write_all` instead error: written amount is not handled. Use `Write::write_all` instead
--> $DIR/unused_io_amount.rs:7:5 --> $DIR/unused_io_amount.rs:7:5
| |
LL | s.write(b"test")?; LL | s.write(b"test")?;
@ -6,23 +6,35 @@ LL | s.write(b"test")?;
| |
= note: `-D clippy::unused-io-amount` implied by `-D warnings` = note: `-D clippy::unused-io-amount` implied by `-D warnings`
error: handle read amount returned or use `Read::read_exact` instead error: read amount is not handled. Use `Read::read_exact` instead
--> $DIR/unused_io_amount.rs:9:5 --> $DIR/unused_io_amount.rs:9:5
| |
LL | s.read(&mut buf)?; LL | s.read(&mut buf)?;
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
error: handle written amount returned or use `Write::write_all` instead error: written amount is not handled. Use `Write::write_all` instead
--> $DIR/unused_io_amount.rs:14:5 --> $DIR/unused_io_amount.rs:14:5
| |
LL | s.write(b"test").unwrap(); LL | s.write(b"test").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error: handle read amount returned or use `Read::read_exact` instead error: read amount is not handled. Use `Read::read_exact` instead
--> $DIR/unused_io_amount.rs:16:5 --> $DIR/unused_io_amount.rs:16:5
| |
LL | s.read(&mut buf).unwrap(); LL | s.read(&mut buf).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 4 previous errors error: read amount is not handled
--> $DIR/unused_io_amount.rs:20:5
|
LL | s.read_vectored(&mut [io::IoSliceMut::new(&mut [])])?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: written amount is not handled
--> $DIR/unused_io_amount.rs:21:5
|
LL | s.write_vectored(&[io::IoSlice::new(&[])])?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 6 previous errors