Skip to content

Remove uses of nightly maybe_uninit_* features #238

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

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

matthew-e-brown
Copy link
Contributor

Continuing with #44, this PR will remove the dependency on three additional nightly features.

  • The few uses of [MaybeUninit<T>]::assume_init_ref() have been replaced with a shim in src/helpers.rs that just contains the exact same transmute call found in the nightly implementation of assume_init_ref(). This should be totally safe, relatievly speaking, since the two types have the exact same layout and the transmute relies on the same initialization invariants that make assume_init_ref() unsafe anyways.
  • I was unable to directly replace MaybeUninit<[T; N]>::transpose() -> [MaybeUninit<T>; N], since the implementation used by the stdlib works by using intrinsics::transmute_unchecked, which omits the size_of check between arguments. It seems that a regular transmute is not quite smart enough to realize that the two have the same size, resulting in a warning about how one of the types have a variable size (even though both are parameterized by a constant N?). Instead, I simply added a new method on the Arena that will return a [MaybeUninit<T>; N] directly using the same logic as the surrounding allocator methods. Hopefully that doesn't result in too noticeable an increase to binary size. 🤞🏻

Still planned for this PR (probably tomorrow or over the weekend):

  • Still need to make a replacement for maybe_uninit_fill. It's only used in one spot to fill a slice of MaybeUninit<Option<&RefCell<Node>>> with a bunch of Nones. Making a general replacement of write_fill might be a bit annoying (barring just copying directly from the nightly impl. again), but I think a better approach would be to make use of Default in this particular case to fill the slice of MaybeUninit<Option<T>> with Option<T>::Nones.

Like the transpose() change, I'm a bit apprehensive on what the code-gen and performance implications of the possible approaches will be here, though. I'm a little worried that writing any sort of loop over the slice will result in something slower than what's in the stdlib. Overall, I'd like to try and avoid doing too much "oh, just copy the nightly implementation directly from the stdlib", if possible. That feels like it kind of defeats the purpose of trying to replace nightly APIs with stable ones. 😅

As before, looking forward to feedback and discussion. Let me know if the comments are too long! 😝

Implementation is copied almost exactly from the unstable code in core.

Includes an unused `_mut` version of the shim because why not. Might be
handy.
Replaces the single use of `alloc_uninit().transpose()` with a dedicated
method for allocating an array. Unfortunately a shim for `transpose`
could not be directly created since it relies on the
`transmute_unchecked()` intrinsic to bypass a `size_of` limitation, but
intrinsics are "perma-unstable."
Copy link
Member

@lhecker lhecker left a comment

Choose a reason for hiding this comment

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

This looks great! I'm happy to merge it once you feel that it's ready.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants