rust-lang / project-error-handling

Error handling project group
Apache License 2.0
268 stars 18 forks source link

Move `std::io::Error` out of `std`. #11

Open indolering opened 3 years ago

indolering commented 3 years ago

Having std::io::Error permeates much of std::io, blocking many crates from being used in no_std environments or re-implementing functionality.

I believe Using std::io::{Read, Write, Cursor} in a nostd environment is the canonical tracking issue.

I'm a Rust newbie 🐣, so my apologies if this ticket is not helpful.

djdisodo commented 9 months ago

i don't think there's reason to limit error type to std::io::Error type, which has ability to handle os errors and some other types of errors and sometimes there's no possibility that such errors happen(for example &[u8] implements Read but most of errors the type has isn't even possible to happen here), you may want to avoid using these error types then utilizing Associated Types can solve these error i think

trait Read {
    type Error;
    fn read(...) -> Result<usize, Self::Error>;
}

//slice for example

impl Read for &[u8] {
    type Error: EofError;
    ...
}

struct SomeRandomOsIoStream;

impl Read for SomeRandomOsIoStream {
    type Error = OsError;
    ...
}

//some wrapping reader example

enum ValidationError<T = Infallible> {
    Invalid,
    InnerError(T)
}

struct SomeValidationReader<T: Read, Error=ValidationError> where Error: From<ValidationError> + From<T::Error> (T);

impl Read for SomeValidationReader<T: Read, Error=ValidationErrorM<T::Error> where Error: From<ValidationError::<Infallible>> + From<T::Error> {
    type Error = Error;
    fn read(...) -> Result<usize, Self::Error> {
        if(invalid) {
            Err(ValidationError::Invalid)?;
        }
        Ok(self.0.read(...)?)
    }
}

by using default types we can avoid breaking changes as much as possible,

aruiz commented 6 months ago

It feels to me that the right answer here would be to do something similar to what alloc does, all we need is a way to specify an errno provider for our no_std environment and on std we set that to os::sys:errno()

Something along the lines of:

#[os_error_provider]
fn custom_os_error_func() -> i32 {
  //...
}

If you don't use it then trying to use io::Error should throw a compiler error just like with alloc

gilescope commented 3 months ago

If that's all that's stopping alloc::io::* becoming a thing I'm all in. Making more things wasm is hard without std::io equivalents.

burdges commented 3 months ago

https://github.com/rust-lang/rfcs/pull/3632