@@ -114,6 +114,7 @@ mod suspicious_map;
114
114
mod suspicious_splitn;
115
115
mod suspicious_to_owned;
116
116
mod type_id_on_box;
117
+ mod unbuffered_bytes;
117
118
mod uninit_assumed_init;
118
119
mod unit_hash;
119
120
mod unnecessary_fallible_conversions;
@@ -4433,6 +4434,33 @@ declare_clippy_lint! {
4433
4434
"using `Option::and_then` or `Result::and_then` to chain a computation that returns an `Option` or a `Result`"
4434
4435
}
4435
4436
4437
+ declare_clippy_lint ! {
4438
+ /// ### What it does
4439
+ /// Checks for calls to `Read::bytes` on types which don't implement `BufRead`.
4440
+ ///
4441
+ /// ### Why is this bad?
4442
+ /// The default implementation calls `read` for each byte, which can be very inefficient for data that’s not in memory, such as `File`.
4443
+ ///
4444
+ /// ### Example
4445
+ /// ```no_run
4446
+ /// use std::io::Read;
4447
+ /// use std::fs::File;
4448
+ /// let file = File::open("./bytes.txt").unwrap();
4449
+ /// file.bytes();
4450
+ /// ```
4451
+ /// Use instead:
4452
+ /// ```no_run
4453
+ /// use std::io::{BufReader, Read};
4454
+ /// use std::fs::File;
4455
+ /// let file = BufReader::new(std::fs::File::open("./bytes.txt").unwrap());
4456
+ /// file.bytes();
4457
+ /// ```
4458
+ #[ clippy:: version = "1.86.0" ]
4459
+ pub UNBUFFERED_BYTES ,
4460
+ perf,
4461
+ "calling .bytes() is very inefficient when data is not in memory"
4462
+ }
4463
+
4436
4464
pub struct Methods {
4437
4465
avoid_breaking_exported_api : bool ,
4438
4466
msrv : Msrv ,
@@ -4603,6 +4631,7 @@ impl_lint_pass!(Methods => [
4603
4631
MANUAL_REPEAT_N ,
4604
4632
SLICED_STRING_AS_BYTES ,
4605
4633
RETURN_AND_THEN ,
4634
+ UNBUFFERED_BYTES ,
4606
4635
] ) ;
4607
4636
4608
4637
/// Extracts a method call name, args, and `Span` of the method name.
@@ -4879,6 +4908,7 @@ impl Methods {
4879
4908
( "as_ptr" , [ ] ) => manual_c_str_literals:: check_as_ptr ( cx, expr, recv, & self . msrv ) ,
4880
4909
( "as_ref" , [ ] ) => useless_asref:: check ( cx, expr, "as_ref" , recv) ,
4881
4910
( "assume_init" , [ ] ) => uninit_assumed_init:: check ( cx, expr, recv) ,
4911
+ ( "bytes" , [ ] ) => unbuffered_bytes:: check ( cx, expr, recv) ,
4882
4912
( "cloned" , [ ] ) => {
4883
4913
cloned_instead_of_copied:: check ( cx, expr, recv, span, & self . msrv ) ;
4884
4914
option_as_ref_cloned:: check ( cx, recv, span) ;
0 commit comments