diff options
| -rw-r--r-- | library/core/src/hint.rs | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 852882aa7f4..89c64f6d28f 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -788,19 +788,20 @@ pub fn select_unpredictable<T>(condition: bool, true_val: T, false_val: T) -> T let mut false_val = MaybeUninit::new(false_val); struct DropOnPanic<T> { - // Invariant: valid pointer and points to an initialized `MaybeUninit`. - inner: *mut MaybeUninit<T>, + // Invariant: valid pointer and points to an initialized value that is not further used, + // i.e. it can be dropped by this guard. + inner: *mut T, } impl<T> Drop for DropOnPanic<T> { fn drop(&mut self) { // SAFETY: Must be guaranteed on construction of local type `DropOnPanic`. - unsafe { (*self.inner).assume_init_drop() } + unsafe { self.inner.drop_in_place() } } } - let true_ptr = (&mut true_val) as *mut _; - let false_ptr = (&mut false_val) as *mut _; + let true_ptr = true_val.as_mut_ptr(); + let false_ptr = false_val.as_mut_ptr(); // SAFETY: The value that is not selected is dropped, and the selected one // is returned. This is necessary because the intrinsic doesn't drop the @@ -813,10 +814,12 @@ pub fn select_unpredictable<T>(condition: bool, true_val: T, false_val: T) -> T let guard = crate::intrinsics::select_unpredictable(condition, true_ptr, false_ptr); let drop = crate::intrinsics::select_unpredictable(condition, false_ptr, true_ptr); - // SAFETY: both pointers are to valid `MaybeUninit`, in both variants they do not alias but - // the two arguments we have selected from did alias each other. + // SAFETY: both pointers are well-aligned and point to initialized values inside a + // `MaybeUninit` each. In both possible values for `condition` the pointer `guard` and + // `drop` do not alias (even though the two argument pairs we have selected from did alias + // each other). let guard = DropOnPanic { inner: guard }; - (*drop).assume_init_drop(); + drop.drop_in_place(); crate::mem::forget(guard); // Note that it is important to use the values here. Reading from the pointer we got makes |
