Stream: t-lang/wg-unsafe-code-guidelines

Topic: &mut T to *mut [MaybeUninit]


DutchGhost (Jan 23 2020 at 21:09, on Zulip):

I wonder, is the resulting pointer from the following function Safe to use ?

pub const fn ptr_to_maybe_uninit_slice<T>(ptr: *mut T) -> *mut [MaybeUninit<u8>] {
    ptr::slice_from_raw_parts_mut(
        ptr as *mut MaybeUninit<T> as *mut MaybeUninit<u8>,
        mem::size_of::<T>(),
    )
}

Im using the raw slice to be able to perform a const swap and replace: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=f9520ce70378a708f229ff2e1965e356 .

Elichai Turkel (Jan 26 2020 at 12:28, on Zulip):

Interesting question, but why not use ptr::swap_nonoverlapping(lhs, rhs, 1)?

DutchGhost (Jan 26 2020 at 17:03, on Zulip):

Interesting question, but why not use ptr::swap_nonoverlapping(lhs, rhs, 1)?

Which seems to actually do something somewhat similar but vetted and utilizing simd

That function is non-const, and Im trying to make an array type which is fully usable in const-fn's. That requires stuff like push and pop to work. And the latter is implementable with a swap

comex (Jan 27 2020 at 00:49, on Zulip):

The code seems fine to me.

RalfJ (Feb 01 2020 at 13:52, on Zulip):

@DutchGhost *mut T is always safe as there's no assumotion safe code can make about raw ptrs... probably I am just not understanding the question

RalfJ (Feb 01 2020 at 13:54, on Zulip):

but if you used references I think that would be a sound function indeed

DutchGhost (Feb 01 2020 at 14:00, on Zulip):

The question is whether that resulting *mut [MaybeUninit<u8>] is sound to use, especially if I originally called ptr_to_maybe_unint_slice with an &mut T.
Basically, is the T referenced by the mutable reference interpretable as a [MaybeUninit<u8>]

RalfJ (Feb 01 2020 at 14:07, on Zulip):

the thing is that for e.g. &mut T I know what "sound to use" means (give it to arbitrary safe code and there is no UB)

RalfJ (Feb 01 2020 at 14:07, on Zulip):

for raw ptrs, I guess you mean doing reads and writes inside the bounds of the slice, but that's far from given

RalfJ (Feb 01 2020 at 14:07, on Zulip):

maybe you mean also getting &mut MaybeUninit<u8> to slice elemtents and doing arbitrary safe things with them

RalfJ (Feb 01 2020 at 14:08, on Zulip):

and while all of these do not cause immediate UB, they can cause UB later... like, turn &mut Vec<i32> into *mut [MaybeUninit<u8>] and then fill this will all-0, now the original Vec ref points to something invalid

DutchGhost (Feb 01 2020 at 14:17, on Zulip):

So summerized, in general, yes its okey to go from &mut T -> *mut [MaybeUninit<u8>], and use that raw slice, except it depends on the type of T what operations are considered 'sound' on that raw slice.

RalfJ (Feb 01 2020 at 16:20, on Zulip):

"soundness" is defined as "cannot be used by safe code to cause UB"

RalfJ (Feb 01 2020 at 16:21, on Zulip):

so it's just not a term that makes much sense when it comes to raw pointers

RalfJ (Feb 01 2020 at 16:21, on Zulip):

but other than terminology nits I think we are in agreement

RalfJ (Feb 01 2020 at 16:21, on Zulip):

(I think careful use of terminology is important when talking about subtle issues such as this, hence the nitpicking. I hope I'm not overdoing it.)

Lokathor (Feb 02 2020 at 07:51, on Zulip):

We need a term for "unsafe code can do this and it's okay" contrasted with the opposite of "unsafe code can do that but it's not okay" (which we call "UB" of course).

Lokathor (Feb 02 2020 at 07:52, on Zulip):

So, that term doesn't have to be "sound" but also since it's a state of being able to do something and not cause UB, "sound" seems fine to me.

Lokathor (Feb 02 2020 at 07:53, on Zulip):

@DutchGhost correct, creation of the *mut [MaybeUninit<u8>] is always fine, usage isn't necessarily fine.

RalfJ (Feb 05 2020 at 19:03, on Zulip):

@Lokathor hm... "UB-free"?^^

Last update: Jun 07 2020 at 10:35UTC