What changed, and why it matters
This commit is a routine code-quality cleanup. It moves linting rules from an individual crate's configuration to the shared workspace configuration, adds missing documentation comments, fixes minor test-code style issues, and adds a missing import in test code. There is no change to runtime behavior or security-sensitive logic.
No security action required. Treat as normal maintenance.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch migrates the io crate from per-crate lints to workspace-level lints ([lints] workspace = true). It removes local allow attributes and Cargo.toml lint entries. It adds # Errors documentation sections to public trait methods and helper functions. In tests, it replaces stack-allocated large arrays (&[99; 64000]) with heap-allocated Vecs and adds the missing alloc::vec import. It also adds trailing semicolons to two assertion lines. No functional code paths are modified.
Changed components
io/Cargo.tomlio/src/hash.rsio/src/lib.rsInspect captured patch +44 / −16
diff --git a/io/Cargo.toml b/io/Cargo.toml
index a686cc16..cedb2076 100644
--- a/io/Cargo.toml
+++ b/io/Cargo.toml
@@ -31,9 +31,5 @@ hashes = { package = "bitcoin_hashes", path = "../hashes", version = "0.19.0", d
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
-[lints.rust]
-unexpected_cfgs = { level = "deny" }
-
-[lints.clippy]
-redundant_clone = "warn"
-use_self = "warn"
+[lints]
+workspace = true
diff --git a/io/src/hash.rs b/io/src/hash.rs
index 8fa4ce12..044562bf 100644
--- a/io/src/hash.rs
+++ b/io/src/hash.rs
@@ -133,6 +133,10 @@ impl_write!(
);
/// Hashes data from a reader.
+///
+/// # Errors
+///
+/// If an I/O error occurs while reading from the underlying reader.
pub fn hash_reader<T>(reader: &mut impl BufRead) -> Result<T::Hash, crate::Error>
where
T: hashes::HashEngine + Default,
@@ -157,6 +161,7 @@ where
#[cfg(feature = "alloc")]
mod tests {
use alloc::format;
+ use alloc::vec;
use hashes::hmac;
@@ -176,7 +181,8 @@ mod tests {
assert_eq!(format!("{}", $mod::Hash::from_engine(engine)), $exp_256);
let mut engine = $mod::Hash::engine();
- engine.write_all(&[99; 64000]).unwrap();
+ let large_buffer = vec![99u8; 64000];
+ engine.write_all(&large_buffer).unwrap();
assert_eq!(format!("{}", $mod::Hash::from_engine(engine)), $exp_64k);
}
};
@@ -258,7 +264,8 @@ mod tests {
);
let mut engine = hmac::HmacEngine::<sha256::HashEngine>::new(&[0xde, 0xad, 0xbe, 0xef]);
- engine.write_all(&[99; 64000]).unwrap();
+ let large_buffer = vec![99u8; 64000];
+ engine.write_all(&large_buffer).unwrap();
assert_eq!(
format!("{}", engine.finalize()),
"30df499717415a395379a1eaabe50038036e4abb5afc94aa55c952f4aa57be08"
@@ -276,7 +283,8 @@ mod tests {
assert_eq!(format!("{}", siphash24::Hash::from_engine(engine)), "3a3ccefde9b5b1e3");
let mut engine = siphash24::HashEngine::with_keys(0, 0);
- engine.write_all(&[99; 64000]).unwrap();
+ let large_buffer = vec![99u8; 64000];
+ engine.write_all(&large_buffer).unwrap();
assert_eq!(format!("{}", siphash24::Hash::from_engine(engine)), "ce456e4e4ecbc5bf");
}
diff --git a/io/src/lib.rs b/io/src/lib.rs
index 9a2f82c7..57d3149f 100644
--- a/io/src/lib.rs
+++ b/io/src/lib.rs
@@ -19,10 +19,6 @@
#![doc(test(attr(warn(unused))))]
// Pedantic lints that we enforce.
#![warn(clippy::return_self_not_must_use)]
-// Exclude lints we don't think are valuable.
-#![allow(clippy::needless_question_mark)] // https://github.com/rust-bitcoin/rust-bitcoin/pull/2134
-#![allow(clippy::manual_range_contains)] // More readable than clippy's format.
-#![allow(clippy::uninlined_format_args)] // Allow `format!("{}", x)` instead of enforcing `format!("{x}")`
#[cfg(feature = "alloc")]
extern crate alloc;
@@ -62,6 +58,10 @@ pub trait Read {
/// # Returns
///
/// The number of bytes read if successful or an [`Error`] if reading fails.
+ ///
+ /// # Errors
+ ///
+ /// If the underlying reader encounters an I/O error.
fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
/// Reads bytes from source until `buf` is full.
@@ -101,6 +101,10 @@ pub trait Read {
/// # Returns
///
/// The number of bytes read if successful or an [`Error`] if reading fails.
+ ///
+ /// # Errors
+ ///
+ /// If an I/O error occurs while reading from the underlying reader.
#[doc(alias = "read_to_end")]
#[cfg(feature = "alloc")]
#[inline]
@@ -143,6 +147,10 @@ impl<R: Read> Take<R> {
/// # Returns
///
/// The number of bytes read if successful or an [`Error`] if reading fails.
+ ///
+ /// # Errors
+ ///
+ /// If an I/O error occurs while reading from the underlying reader.
#[cfg(feature = "alloc")]
#[inline]
pub fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
@@ -330,13 +338,25 @@ impl<T: AsMut<[u8]>> Write for Cursor<T> {
/// See [`std::io::Write`] for more information.
pub trait Write {
/// Writes `buf` into this writer, returning how many bytes were written.
+ ///
+ /// # Errors
+ ///
+ /// If an I/O error occurs while writing to the underlying writer.
fn write(&mut self, buf: &[u8]) -> Result<usize>;
/// Flushes this output stream, ensuring that all intermediately buffered contents
/// reach their destination.
+ ///
+ /// # Errors
+ ///
+ /// If an I/O error occurs while flushing the underlying writer.
fn flush(&mut self) -> Result<()>;
/// Attempts to write an entire buffer into this writer.
+ ///
+ /// # Errors
+ ///
+ /// If an I/O error occurs while writing to the underlying writer.
#[inline]
fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
while !buf.is_empty() {
@@ -424,7 +444,11 @@ pub const fn from_std<T>(std_io: T) -> FromStd<T> { FromStd::new(std_io) }
#[inline]
pub fn from_std_mut<T>(std_io: &mut T) -> &mut FromStd<T> { FromStd::new_mut(std_io) }
-/// Encodes a consensus_encoding object to an I/O writer.
+/// Encodes a `consensus_encoding` object to an I/O writer.
+///
+/// # Errors
+///
+/// If an I/O error occurs while writing to the underlying writer.
pub fn encode_to_writer<T, W>(object: &T, mut writer: W) -> Result<()>
where
T: encoding::Encodable + ?Sized,
@@ -642,7 +666,7 @@ mod tests {
// 32 is greater than the reader length.
let read = reader.read_to_limit(&mut buf, 32).expect("failed to read to limit");
assert_eq!(read, s.len());
- assert_eq!(&buf, s.as_bytes())
+ assert_eq!(&buf, s.as_bytes());
}
#[test]
@@ -654,7 +678,7 @@ mod tests {
let read = reader.read_to_limit(&mut buf, 2).expect("failed to read to limit");
assert_eq!(read, 2);
- assert_eq!(&buf, "16".as_bytes())
+ assert_eq!(&buf, "16".as_bytes());
}
#[test]
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.