about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAliƩnore Bouttefeux <alienore.bouttefeux@gmail.com>2021-04-16 20:12:16 +0200
committerAliƩnore Bouttefeux <alienore.bouttefeux@gmail.com>2021-04-22 15:52:42 +0200
commit5625d58f9f3fbff3d81cbab76fbbcfc5ff06c833 (patch)
treea07ed8efcc985b7b8e580fcd826d81ed424d45ec
parent28dbcd85c8a956a1d1e39066668fcf1484080949 (diff)
downloadrust-5625d58f9f3fbff3d81cbab76fbbcfc5ff06c833.tar.gz
rust-5625d58f9f3fbff3d81cbab76fbbcfc5ff06c833.zip
add detection unused_io_amount of "or", "or_else" and "ok"
-rw-r--r--clippy_lints/src/unused_io_amount.rs20
-rw-r--r--tests/ui/unused_io_amount.rs41
-rw-r--r--tests/ui/unused_io_amount.stderr30
3 files changed, 84 insertions, 7 deletions
diff --git a/clippy_lints/src/unused_io_amount.rs b/clippy_lints/src/unused_io_amount.rs
index 5e8e530f480..3387f35bac3 100644
--- a/clippy_lints/src/unused_io_amount.rs
+++ b/clippy_lints/src/unused_io_amount.rs
@@ -47,25 +47,35 @@ impl<'tcx> LateLintPass<'tcx> for UnusedIoAmount {
                         func.kind,
                         hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::TryIntoResult, _))
                     ) {
-                        check_method_call(cx, &args[0], expr);
+                        check_map_error(cx, &args[0], expr);
                     }
                 } else {
-                    check_method_call(cx, res, expr);
+                    check_map_error(cx, res, expr);
                 }
             },
-
             hir::ExprKind::MethodCall(path, _, args, _) => match &*path.ident.as_str() {
                 "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<'_>) {
     if let hir::ExprKind::MethodCall(path, _, _, _) = call.kind {
         let symbol = &*path.ident.as_str();
diff --git a/tests/ui/unused_io_amount.rs b/tests/ui/unused_io_amount.rs
index ebaba9629db..8b141e25942 100644
--- a/tests/ui/unused_io_amount.rs
+++ b/tests/ui/unused_io_amount.rs
@@ -1,7 +1,7 @@
 #![allow(dead_code)]
 #![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<()> {
     s.write(b"test")?;
@@ -22,4 +22,43 @@ fn vectored<T: io::Read + io::Write>(s: &mut T) -> io::Result<()> {
     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() {}
diff --git a/tests/ui/unused_io_amount.stderr b/tests/ui/unused_io_amount.stderr
index 5219d63980b..d8dfc0e5a79 100644
--- a/tests/ui/unused_io_amount.stderr
+++ b/tests/ui/unused_io_amount.stderr
@@ -36,5 +36,33 @@ error: written amount is not handled
 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