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

Topic: validity of unions


gnzlbg (Jun 20 2019 at 14:23, on Zulip):

https://github.com/rust-lang/unsafe-code-guidelines/issues/73

Could we allow Option<MaybeUninit<T>> to have the same size as MaybeUninit<T> ?

This case appears to me to be much simpler than layout optimizations for unions in general, yet I am not sure how we could ever allow that.

gnzlbg (Jun 20 2019 at 14:23, on Zulip):

Consider unions that could be repr(transparent) (but don't necessarily need to be), that is, unions with a single non-zero-sized field. These unions do always have valid fields because, independently of the bytes of the union, all zero-sized fields are always valid.

The non-zero-sized field is, however, not always valid, and we want to support that to support partial initialization.

gnzlbg (Jun 20 2019 at 14:26, on Zulip):

For example,

union U { a: (), b: NonNull<T> }
let mut u = U { a: () }; // U::b == undef
let opt = Some(u); // ??
let opt: Option<U> = transmute(u); // ??
gnzlbg (Jun 20 2019 at 14:28, on Zulip):

So even though NonNull<T> has a niche, when constructing an Option<U>, we would need extra requirements about the contents of the niche, even though the union has a valid field (U::a).

gnzlbg (Jun 20 2019 at 14:28, on Zulip):

We would at least have to require that the niche is always "valid" (whatever that might mean).

gnzlbg (Jun 20 2019 at 14:30, on Zulip):

That means that this would be ok:

let u = MaybeUninit::<NonNull<T>>::zeroed();
let opt = Some(u);  // niche is "valid"

but this wouldn't:

let u = MaybeUninit::<NonNull<T>>::uninitialized();
let opt = Some(u);  // niche is "invalid"
gnzlbg (Jun 20 2019 at 14:36, on Zulip):

AFAICT this means that we wouldn't only have to require that the union has at least one valid field to perform niche optimizations, but also that all fields "share" at least one niche. E.g., if we had:

union U { a: NonNull<T>, b: &'static mut T }

then I think we could make Option<U> and U have the same size.

RalfJ (Jun 20 2019 at 14:44, on Zulip):

Could we allow Option<MaybeUninit<T>> to have the same size as MaybeUninit<T> ?

given the goals of MaybeUninit I think that is impossible

RalfJ (Jun 20 2019 at 14:44, on Zulip):

we wouldn't only have to require that the union has at least one valid field to perform niche optimizations, but also that all fields "share" at least one niche

yes

RalfJ (Jun 20 2019 at 14:44, on Zulip):

but I still think we shouldn't

gnzlbg (Jun 20 2019 at 14:49, on Zulip):

@RalfJ adding a ZST field to an union would have big consequences from a point-of-view of layout optimizations

gnzlbg (Jun 20 2019 at 14:49, on Zulip):

that feels brittle

gnzlbg (Jun 20 2019 at 14:50, on Zulip):

anyways, your Mix example here: https://github.com/rust-lang/unsafe-code-guidelines/issues/73#issuecomment-460572178 is not optimizable AFAICT

gnzlbg (Jun 20 2019 at 14:50, on Zulip):

the fields there do not share a niche

RalfJ (Jun 20 2019 at 14:51, on Zulip):

absolutely, that's why I brought it up

RalfJ (Jun 20 2019 at 14:52, on Zulip):

I have spelled out the ivnariant that we might use somewhere, and it's basically what you are suggesting here

gnzlbg (Jun 20 2019 at 14:52, on Zulip):

is that summarized somewhere ?

RalfJ (Jun 20 2019 at 14:52, on Zulip):

"for bit/byte at position i of the union, that bit/byte is allowed to have value v if any variant of the union allows the bit/byte at index i to have value v"

RalfJ (Jun 20 2019 at 14:53, on Zulip):

but I think this is an awful invariant. it is too complicated, it is crazy to check for at run-time, the benefit is too minimal IMO

gnzlbg (Jun 20 2019 at 14:53, on Zulip):

i think we can at least write down the validity invariant for unions that do not share a niche

RalfJ (Jun 20 2019 at 14:54, on Zulip):

well I think we all agree that if there is a field (), then the union may contain any data

gnzlbg (Jun 20 2019 at 14:54, on Zulip):

yes

RalfJ (Jun 20 2019 at 14:54, on Zulip):

niche as a notion is derived from validity invariant, so defining validity in terms of niche is a bit cyclic ;)

gnzlbg (Jun 20 2019 at 15:00, on Zulip):

I thought niche was being moved to layout, maybe ?

gnzlbg (Jun 20 2019 at 15:00, on Zulip):

I can't remember, there was an issue about that somewhere

Last update: Nov 19 2019 at 19:00UTC