bump_scope/
set_len_on_drop_by_ptr.rs

1use core::ptr::NonNull;
2
3use crate::polyfill::non_null;
4
5// Set the length of the vector when the `SetLenOnDropByPtr` value goes out of scope.
6//
7// The idea is: The length field in SetLenOnDropByPtr is a local variable
8// that the optimizer will see does not alias with any stores through the vector's data
9// pointer. This is a workaround for alias analysis issue #32155
10pub(super) struct SetLenOnDropByPtr<'a, T> {
11    slice: &'a mut NonNull<[T]>,
12    local_len: usize,
13}
14
15impl<'a, T> SetLenOnDropByPtr<'a, T> {
16    #[inline]
17    pub(super) fn new(slice: &'a mut NonNull<[T]>) -> Self {
18        SetLenOnDropByPtr {
19            local_len: slice.len(),
20            slice,
21        }
22    }
23
24    #[inline]
25    pub(super) fn increment_len(&mut self, increment: usize) {
26        self.local_len += increment;
27    }
28
29    #[inline]
30    pub(super) fn current_len(&self) -> usize {
31        self.local_len
32    }
33}
34
35impl<T> Drop for SetLenOnDropByPtr<'_, T> {
36    #[inline]
37    fn drop(&mut self) {
38        non_null::set_len(self.slice, self.local_len);
39    }
40}