Replace mem::uninitialized with MaybeUninit

I'm working on a project around embedded systems that needs to use filesystem. I want to use liitlefs crate in rust but it uses mem::uninitialized that deprecated since 1.39.0 . https://github.com/brandonedens/rust-littlefs

pub struct LittleFs<T: Storage> {
    storage: T,
    lfs_config: lfs::lfs_config,
    lfs: lfs::lfs_t,
    read_buffer: [u8; READ_SIZE],
    prog_buffer: [u8; PROG_SIZE],
    lookahead_buffer: [u8; LOOKAHEAD / 8],
}

impl<T: Storage> LittleFs<T> {
    /// Create a new instance of the LittleFS.
    pub fn new(storage: T) -> Self {
        LittleFs {
            storage: storage,
            lfs: unsafe { mem::uninitialized::<lfs::lfs>() },
            lfs_config: unsafe { mem::uninitialized::<lfs::lfs_config>() },
            read_buffer: [0u8; READ_SIZE],
            prog_buffer: [0u8; PROG_SIZE],
            lookahead_buffer: [0u8; LOOKAHEAD / 8],
        }
    }

I tried to replace it in the following way but it caused unspecified behaviors by the system:

pub struct LittleFs<T: Storage> {
    storage: T,
    lfs_config: lfs::lfs_config,
    lfs: lfs::lfs_t,
    read_buffer: [u8; READ_SIZE],
    prog_buffer: [u8; PROG_SIZE],
    lookahead_buffer: [u8; LOOKAHEAD / 8],
}

impl<T: Storage> LittleFs<T> {
    pub fn new(storage: T) -> Self {
        LittleFs {
            storage,
            lfs: unsafe { MaybeUninit::uninit().assume_init() },
            lfs_config: unsafe { MaybeUninit::uninit().assume_init() },
            read_buffer: [0u8; READ_SIZE],
            prog_buffer: [0u8; PROG_SIZE],
            lookahead_buffer: [0u8; LOOKAHEAD / 8],
        }
    }

Does anyone have a solution to this problem? Thank you in advance.


Solution 1:

You can't do uninit().assume_init() — it's definitely not initialized. assume_init() is only to be called once the data has been initialized with real values. The idea behind calling it is that you're promising, "Yes, I know this value is marked as maybe initialized. I promise that it is initialized now. It's not just a maybe."

You'll need to change the types of lfs and lfs_config:

lfs_config: MaybeUninit<lfs::lfs_config>,
lfs: MaybeUninit<lfs::lfs_t>,

That will have a ripple effect downstream, requiring you to then modify any code that accesses the fields.

  • Initialize them with write.
  • Read them with assume_init_ref or assume_init_mut.