Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement From<TryReserveError> for io::Error #96505

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions library/std/src/io/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ mod repr_unpacked;
#[cfg(not(target_pointer_width = "64"))]
use repr_unpacked::Repr;

use crate::collections::{TryReserveError, TryReserveErrorKind};
use crate::convert::From;
use crate::error;
use crate::fmt;
Expand Down Expand Up @@ -465,6 +466,19 @@ impl From<ErrorKind> for Error {
}
}

#[stable(feature = "io_error_from_try_reserve", since = "1.62.0")]
impl From<TryReserveError> for Error {
#[inline]
fn from(error: TryReserveError) -> Error {
let kind = match error.kind() {
TryReserveErrorKind::CapacityOverflow => ErrorKind::InvalidInput,
TryReserveErrorKind::AllocError { .. } => ErrorKind::OutOfMemory,
};

Error::new(kind, error)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this involves a double allocation, effectively a Box<Box<dyn io::Error>>.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't realize io::Error::new was a double-allocation! I wonder if thin dyn box would solve that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even worse: if you pass it a string literal ( Error::new(kind, "...")) you get a triple allocation (and a strcpy/memcpy) as the inner box will contain a String.

ThinBox can save one allocation here. I think that'd be a simple change to make, but there might be some non-obvious pitfall.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #83352

}
}

impl Error {
/// Creates a new I/O error from a known kind of error as well as an
/// arbitrary error payload.
Expand Down