@@ -113,6 +113,7 @@ mod suspicious_map;
113113mod suspicious_splitn;
114114mod suspicious_to_owned;
115115mod type_id_on_box;
116+ mod unbuffered_bytes;
116117mod uninit_assumed_init;
117118mod unit_hash;
118119mod unnecessary_fallible_conversions;
@@ -4406,6 +4407,33 @@ declare_clippy_lint! {
44064407 "using `Option::and_then` or `Result::and_then` to chain a computation that returns an `Option` or a `Result`"
44074408}
44084409
4410+ declare_clippy_lint ! {
4411+ /// ### What it does
4412+ /// Checks for calls to `Read::bytes` on types which don't implement `BufRead`.
4413+ ///
4414+ /// ### Why is this bad?
4415+ /// The default implementation calls `read` for each byte, which can be very inefficient for data that’s not in memory, such as `File`.
4416+ ///
4417+ /// ### Example
4418+ /// ```no_run
4419+ /// use std::io::Read;
4420+ /// use std::fs::File;
4421+ /// let file = File::open("./bytes.txt").unwrap();
4422+ /// file.bytes();
4423+ /// ```
4424+ /// Use instead:
4425+ /// ```no_run
4426+ /// use std::io::{BufReader, Read};
4427+ /// use std::fs::File;
4428+ /// let file = BufReader::new(std::fs::File::open("./bytes.txt").unwrap());
4429+ /// file.bytes();
4430+ /// ```
4431+ #[ clippy:: version = "1.86.0" ]
4432+ pub UNBUFFERED_BYTES ,
4433+ perf,
4434+ "calling .bytes() is very inefficient when data is not in memory"
4435+ }
4436+
44094437#[ expect( clippy:: struct_excessive_bools) ]
44104438pub struct Methods {
44114439 avoid_breaking_exported_api : bool ,
@@ -4580,6 +4608,7 @@ impl_lint_pass!(Methods => [
45804608 MANUAL_REPEAT_N ,
45814609 SLICED_STRING_AS_BYTES ,
45824610 RETURN_AND_THEN ,
4611+ UNBUFFERED_BYTES ,
45834612] ) ;
45844613
45854614/// Extracts a method call name, args, and `Span` of the method name.
@@ -4856,6 +4885,7 @@ impl Methods {
48564885 ( "as_ptr" , [ ] ) => manual_c_str_literals:: check_as_ptr ( cx, expr, recv, & self . msrv ) ,
48574886 ( "as_ref" , [ ] ) => useless_asref:: check ( cx, expr, "as_ref" , recv) ,
48584887 ( "assume_init" , [ ] ) => uninit_assumed_init:: check ( cx, expr, recv) ,
4888+ ( "bytes" , [ ] ) => unbuffered_bytes:: check ( cx, expr, recv) ,
48594889 ( "cloned" , [ ] ) => {
48604890 cloned_instead_of_copied:: check ( cx, expr, recv, span, & self . msrv ) ;
48614891 option_as_ref_cloned:: check ( cx, recv, span) ;
0 commit comments