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! {
/// **What it does:** Checks for unused written/read amount.
///
/// **Why is this bad?** `io::Write::write` and `io::Read::read` are not
/// guaranteed to
/// **Why is this bad?** `io::Write::write(_vectored)` and
/// `io::Read::read(_vectored)` are not guaranteed to
/// process the entire buffer. They return how many bytes were processed, which
/// might be smaller
/// 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<'_>) {
if let hir::ExprKind::MethodCall(ref path, _, _) = call.kind {
let symbol = &*path.ident.as_str();
if match_trait_method(cx, call, &paths::IO_READ) && symbol == "read" {
span_lint(
let read_trait = match_trait_method(cx, call, &paths::IO_READ);
let write_trait = match_trait_method(cx, call, &paths::IO_WRITE);
match (read_trait, write_trait, symbol) {
(true, _, "read") => span_lint(
cx,
UNUSED_IO_AMOUNT,
expr.span,
"handle read amount returned or use `Read::read_exact` instead",
);
} else if match_trait_method(cx, call, &paths::IO_WRITE) && symbol == "write" {
span_lint(
"read amount is not handled. Use `Read::read_exact` instead",
),
(true, _, "read_vectored") => span_lint(cx, UNUSED_IO_AMOUNT, expr.span, "read amount is not handled"),
(_, true, "write") => span_lint(
cx,
UNUSED_IO_AMOUNT,
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();
}
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() {}

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
|
LL | s.write(b"test")?;
@ -6,23 +6,35 @@ LL | s.write(b"test")?;
|
= 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
|
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
|
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
|
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