You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Is assignment to an uninit but non-Drop place okay? #596
The OP code does not drop a MaybeUninit<T>. It drops a T because MaybeUninit::as_mut_ptr() returns a *mut T. The question is whether dropping that invalid value (and thus also unsafe value) is UB, knowing that there's no drop glue. And it seems the answer is that it's not UB. If there's no drop glue, the value to be dropped does not get materialized and its validity is thus irrelevant.
In that case I would assume dereferencing the pointer is immediate UB even if it's only used in a place for an assignment expression. I don't think it's valid to dereference a pointer to a value that contains uninitialized memory anywhere not valid for its type. I'm not sure that place expressions are immune to this, to me they read similarly to a borrow.
I think I would agree that drop semantics don't exist when there's no drop glue.
In that case I would assume dereferencing the pointer is immediate UB even if it's only used in a place for an assignment expression.
It's not UB exactly because it builds a place, not a value. There's no load so there's no materialization of the value.
Regarding the OP question, this is actually more general than just types with no drop glue. Dropping is about a place, and the place is never implicitly loaded during the destruction procedure. In the following example, Foo implements Drop but only loads the first 2 bytes:
Interesting, I didn't know there needed to be a load for uninitialized memory to become UB. (Looking at the issue you linked, it appears the reference taught me wrong.) Thank you for the clarification.
Note that at the moment the Reference still says that it is UB to have a reference pointing to an invalid value. Calling the destructor involves creating a reference, so according to the Reference your last example is UB @ia0. However if we do eventually resolve the question of recursive reference validity to match what Miri currently does, then yeah that code should be fine.
Activity
RalfJung commentedon Dec 30, 2025
Seems fairly clear to me that this is fine. How could this code plausibly have UB?
ChayimFriedman2 commentedon Dec 30, 2025
If we say that dropping a value always touches it, even if it does not has a drop glue.
LoganDark commentedon Jan 29, 2026
I would assume dropping a
MaybeUninit<T>does touch theMaybeUninit<T>, butMaybeUninit<T>does not touch theT.ia0 commentedon Jan 29, 2026
The OP code does not drop a
MaybeUninit<T>. It drops aTbecauseMaybeUninit::as_mut_ptr()returns a*mut T. The question is whether dropping that invalid value (and thus also unsafe value) is UB, knowing that there's no drop glue. And it seems the answer is that it's not UB. If there's no drop glue, the value to be dropped does not get materialized and its validity is thus irrelevant.LoganDark commentedon Jan 29, 2026
In that case I would assume dereferencing the pointer is immediate UB even if it's only used in a place for an assignment expression. I don't think it's valid to dereference a pointer to a value that contains uninitialized memory anywhere not valid for its type. I'm not sure that place expressions are immune to this, to me they read similarly to a borrow.
I think I would agree that drop semantics don't exist when there's no drop glue.
ia0 commentedon Jan 29, 2026
It's not UB exactly because it builds a place, not a value. There's no load so there's no materialization of the value.
Regarding the OP question, this is actually more general than just types with no drop glue. Dropping is about a place, and the place is never implicitly loaded during the destruction procedure. In the following example,
FooimplementsDropbut only loads the first 2 bytes:There's no UB in this code according to the reference and to Miri, because:
Foo::drop()does not load the place and mutable references don't have recursive validity.Foo::drop()only loads the first 2 bytes.Fooare dropped in order, but for each of those fields there's no drop glue, so no load.LoganDark commentedon Jan 29, 2026
Interesting, I didn't know there needed to be a load for uninitialized memory to become UB. (Looking at the issue you linked, it appears the reference taught me wrong.) Thank you for the clarification.
RalfJung commentedon Jan 29, 2026
Note that at the moment the Reference still says that it is UB to have a reference pointing to an invalid value. Calling the destructor involves creating a reference, so according to the Reference your last example is UB @ia0. However if we do eventually resolve the question of recursive reference validity to match what Miri currently does, then yeah that code should be fine.
ia0 commentedon Jan 29, 2026
Ah my bad, I forgot the reference was conservative on that aspect. Thanks!