pub unsafe trait ReadIntoUninit: Read {
    fn read_into_uninit<'buf>(
        &mut self,
        buf: Out<'buf, [u8]>
    ) -> Result<&'buf mut [u8]>; fn read_into_uninit_exact<'buf>(
        &mut self,
        buf: Out<'buf, [u8]>
    ) -> Result<&'buf mut [u8]> { ... } fn chain<R: ReadIntoUninit>(self, next: R) -> Chain<Self, R>Notable traits for Chain<R1, R2>impl<R1, R2> Read for Chain<R1, R2> where
    R1: ReadIntoUninit,
    R2: ReadIntoUninit

    where
        Self: Sized
, { ... } }
Available on crate feature std only.
Expand description

Trait for a Readable type that can output the bytes read into uninitialised memory.

Safety (to implement) / Guarantees (for users of impl ReadIntoUninit types)

The trait is unsafe (to implement) because it needs to guarantee to users of generic R : ReadIntoUninit code (that may use unsafe code relying on it!) that:

  • if let Ok(init_buf) = self.read_into_uninit(buf), then it must be sound to:

    unsafe {
        buf.get_out_unchecked(.. init_buf.len()).assume_init()
    }
  • if self.read_into_uninit_exact(buf).is_ok(), then it must be sound to: buf.assume_init().

Counterexample

use ::uninit::{prelude::*,
    read::{auto_impl, ReadIntoUninit},
};

pub
struct Evil;

auto_impl! { #[derived_from(ReadIntoUninit)] impl Read for Evil }
unsafe // unsound!
impl ReadIntoUninit for Evil {
    fn read_into_uninit<'buf> (
        self: &'_ mut Self,
        buf: Out<'buf, [u8]>,
    ) -> ::std::io::Result<&'buf mut [u8]>
    {
        Ok(Box::leak(vec![0; buf.len()].into_boxed_slice()))
    }
}

Indeed, with such an impl, the following function could cause UB, when instanced with R = Evil:

use ::uninit::{prelude::*, read::ReadIntoUninit};

fn read_byte<R> (reader: &'_ mut R)
  -> ::std::io::Result<u8>
where
    R : ReadIntoUninit,
{
    let mut byte = MaybeUninit::uninit();
    reader.read_into_uninit_exact(::std::slice::from_mut(&mut byte).as_out())?;
    Ok(unsafe {
        // Safety: Guaranteed by `ReadIntoUninit` contract
        byte.assume_init()
    })
}

Required Methods

Single attempt to read bytes from Self into buf.

On success, it returns the bytes having been read.

Guarantees (that unsafe code may rely on)
  • if let Ok(init_buf) = self.read_into_uninit(buf), then it is sound to:

    unsafe {
        buf.get_out_unchecked(.. init_buf.len()).assume_init()
    }

This is not guaranteed to read buf.len() bytes, see the docs of .read() for more information.

Provided Methods

Attempts to fill buf through multiple .read() calls if necessary.

On success, it returns the bytes having been read.

Guarantees (that unsafe code may rely on)
  • if self.read_into_uninit_exact(buf).is_ok(), then it is sound to: buf.assume_init().

See the docs of .read_exact() for more information.

Available on crate feature chain only.

Chains / concats two ReadIntoUninit readers into one.

Implementations on Foreign Types

Implementors