add detection unused_io_amount of "or", "or_else" and "ok"

This commit is contained in:
Aliénore Bouttefeux 2021-04-16 20:12:16 +02:00
parent 28dbcd85c8
commit 5625d58f9f
3 changed files with 84 additions and 7 deletions

View file

@ -47,25 +47,35 @@ impl<'tcx> LateLintPass<'tcx> for UnusedIoAmount {
func.kind, func.kind,
hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::TryIntoResult, _)) hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::TryIntoResult, _))
) { ) {
check_method_call(cx, &args[0], expr); check_map_error(cx, &args[0], expr);
} }
} else { } else {
check_method_call(cx, res, expr); check_map_error(cx, res, expr);
} }
}, },
hir::ExprKind::MethodCall(path, _, args, _) => match &*path.ident.as_str() { hir::ExprKind::MethodCall(path, _, args, _) => match &*path.ident.as_str() {
"expect" | "unwrap" | "unwrap_or" | "unwrap_or_else" => { "expect" | "unwrap" | "unwrap_or" | "unwrap_or_else" => {
check_method_call(cx, &args[0], expr); check_map_error(cx, &args[0], expr);
}, },
_ => (), _ => (),
}, },
_ => (), _ => (),
} }
} }
} }
fn check_map_error(cx: &LateContext<'_>, call: &hir::Expr<'_>, expr: &hir::Expr<'_>) {
let mut call = call;
while let hir::ExprKind::MethodCall(ref path, _, ref args, _) = call.kind {
if matches!(&*path.ident.as_str(), "or" | "or_else" | "ok") {
call = &args[0];
} else {
break;
}
}
check_method_call(cx, call, expr);
}
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(path, _, _, _) = call.kind { if let hir::ExprKind::MethodCall(path, _, _, _) = call.kind {
let symbol = &*path.ident.as_str(); let symbol = &*path.ident.as_str();

View file

@ -1,7 +1,7 @@
#![allow(dead_code)] #![allow(dead_code)]
#![warn(clippy::unused_io_amount)] #![warn(clippy::unused_io_amount)]
use std::io; use std::io::{self, Read};
fn question_mark<T: io::Read + io::Write>(s: &mut T) -> io::Result<()> { fn question_mark<T: io::Read + io::Write>(s: &mut T) -> io::Result<()> {
s.write(b"test")?; s.write(b"test")?;
@ -22,4 +22,43 @@ fn vectored<T: io::Read + io::Write>(s: &mut T) -> io::Result<()> {
Ok(()) Ok(())
} }
fn ok(file: &str) -> Option<()> {
let mut reader = std::fs::File::open(file).ok()?;
let mut result = [0u8; 0];
reader.read(&mut result).ok()?;
Some(())
}
#[allow(clippy::redundant_closure)]
#[allow(clippy::bind_instead_of_map)]
fn or_else(file: &str) -> io::Result<()> {
let mut reader = std::fs::File::open(file)?;
let mut result = [0u8; 0];
reader.read(&mut result).or_else(|err| Err(err))?;
Ok(())
}
#[derive(Debug)]
enum Error {
Kind,
}
fn or(file: &str) -> Result<(), Error> {
let mut reader = std::fs::File::open(file).unwrap();
let mut result = [0u8; 0];
reader.read(&mut result).or(Err(Error::Kind))?;
Ok(())
}
fn combine_or(file: &str) -> Result<(), Error> {
let mut reader = std::fs::File::open(file).unwrap();
let mut result = [0u8; 0];
reader
.read(&mut result)
.or(Err(Error::Kind))
.or(Err(Error::Kind))
.expect("error");
Ok(())
}
fn main() {} fn main() {}

View file

@ -36,5 +36,33 @@ error: written amount is not handled
LL | s.write_vectored(&[io::IoSlice::new(&[])])?; LL | s.write_vectored(&[io::IoSlice::new(&[])])?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 6 previous errors error: read amount is not handled. Use `Read::read_exact` instead
--> $DIR/unused_io_amount.rs:28:5
|
LL | reader.read(&mut result).ok()?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: read amount is not handled. Use `Read::read_exact` instead
--> $DIR/unused_io_amount.rs:37:5
|
LL | reader.read(&mut result).or_else(|err| Err(err))?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: read amount is not handled. Use `Read::read_exact` instead
--> $DIR/unused_io_amount.rs:49:5
|
LL | reader.read(&mut result).or(Err(Error::Kind))?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: read amount is not handled. Use `Read::read_exact` instead
--> $DIR/unused_io_amount.rs:56:5
|
LL | / reader
LL | | .read(&mut result)
LL | | .or(Err(Error::Kind))
LL | | .or(Err(Error::Kind))
LL | | .expect("error");
| |________________________^
error: aborting due to 10 previous errors