@@ -113,6 +113,7 @@ mod suspicious_map;
113
113
mod suspicious_splitn;
114
114
mod suspicious_to_owned;
115
115
mod type_id_on_box;
116
+ mod unbuffered_bytes;
116
117
mod uninit_assumed_init;
117
118
mod unit_hash;
118
119
mod unnecessary_fallible_conversions;
@@ -4392,6 +4393,34 @@ declare_clippy_lint! {
4392
4393
"slicing a string and immediately calling as_bytes is less efficient and can lead to panics"
4393
4394
}
4394
4395
4396
+ declare_clippy_lint ! {
4397
+ /// ### What it does
4398
+ /// Checks for `Read::bytes()` on an unbuffered Read type
4399
+ ///
4400
+ /// ### Why is this bad?
4401
+ /// The default implementation calls `read` for each byte, which can be very inefficient for data that’s not in memory, such as `File`.
4402
+ ///
4403
+ /// ### Example
4404
+ /// ```no_run
4405
+ /// use std::io::Read;
4406
+ /// use std::fs::File;
4407
+ /// let file = File::open("./bytes.txt").unwrap();
4408
+ /// file.bytes()
4409
+ /// ```
4410
+ /// Use instead:
4411
+ /// ```no_run
4412
+ /// use std::io::Read;
4413
+ /// use std::fs::File;
4414
+ /// use std::fs::BufReader;
4415
+ /// let file = BufReader::new(std::fs::File::open("./bytes.txt").unwrap());
4416
+ /// file.bytes()
4417
+ /// ```
4418
+ #[ clippy:: version = "1.86.0" ]
4419
+ pub UNBUFFERED_BYTES ,
4420
+ perf,
4421
+ "calling .bytes() is very inefficient when data is not in memory"
4422
+ }
4423
+
4395
4424
pub struct Methods {
4396
4425
avoid_breaking_exported_api : bool ,
4397
4426
msrv : Msrv ,
@@ -4561,6 +4590,7 @@ impl_lint_pass!(Methods => [
4561
4590
USELESS_NONZERO_NEW_UNCHECKED ,
4562
4591
MANUAL_REPEAT_N ,
4563
4592
SLICED_STRING_AS_BYTES ,
4593
+ UNBUFFERED_BYTES ,
4564
4594
] ) ;
4565
4595
4566
4596
/// Extracts a method call name, args, and `Span` of the method name.
@@ -4834,6 +4864,7 @@ impl Methods {
4834
4864
( "as_ptr" , [ ] ) => manual_c_str_literals:: check_as_ptr ( cx, expr, recv, & self . msrv ) ,
4835
4865
( "as_ref" , [ ] ) => useless_asref:: check ( cx, expr, "as_ref" , recv) ,
4836
4866
( "assume_init" , [ ] ) => uninit_assumed_init:: check ( cx, expr, recv) ,
4867
+ ( "bytes" , [ ] ) => unbuffered_bytes:: check ( cx, expr, recv) ,
4837
4868
( "cloned" , [ ] ) => {
4838
4869
cloned_instead_of_copied:: check ( cx, expr, recv, span, & self . msrv ) ;
4839
4870
option_as_ref_cloned:: check ( cx, recv, span) ;
0 commit comments