162306a36Sopenharmony_ci// SPDX-License-Identifier: Apache-2.0 OR MIT 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci// Set the length of the vec when the `SetLenOnDrop` value goes out of scope. 462306a36Sopenharmony_ci// 562306a36Sopenharmony_ci// The idea is: The length field in SetLenOnDrop is a local variable 662306a36Sopenharmony_ci// that the optimizer will see does not alias with any stores through the Vec's data 762306a36Sopenharmony_ci// pointer. This is a workaround for alias analysis issue #32155 862306a36Sopenharmony_cipub(super) struct SetLenOnDrop<'a> { 962306a36Sopenharmony_ci len: &'a mut usize, 1062306a36Sopenharmony_ci local_len: usize, 1162306a36Sopenharmony_ci} 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ciimpl<'a> SetLenOnDrop<'a> { 1462306a36Sopenharmony_ci #[inline] 1562306a36Sopenharmony_ci pub(super) fn new(len: &'a mut usize) -> Self { 1662306a36Sopenharmony_ci SetLenOnDrop { local_len: *len, len } 1762306a36Sopenharmony_ci } 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci #[inline] 2062306a36Sopenharmony_ci pub(super) fn increment_len(&mut self, increment: usize) { 2162306a36Sopenharmony_ci self.local_len += increment; 2262306a36Sopenharmony_ci } 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci #[inline] 2562306a36Sopenharmony_ci pub(super) fn current_len(&self) -> usize { 2662306a36Sopenharmony_ci self.local_len 2762306a36Sopenharmony_ci } 2862306a36Sopenharmony_ci} 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ciimpl Drop for SetLenOnDrop<'_> { 3162306a36Sopenharmony_ci #[inline] 3262306a36Sopenharmony_ci fn drop(&mut self) { 3362306a36Sopenharmony_ci *self.len = self.local_len; 3462306a36Sopenharmony_ci } 3562306a36Sopenharmony_ci} 36