xref: /openbmc/linux/rust/alloc/vec/set_len_on_drop.rs (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
1*3dcb652aSAsahi Lina // SPDX-License-Identifier: Apache-2.0 OR MIT
2*3dcb652aSAsahi Lina 
365b571afSAsahi Lina // Set the length of the vec when the `SetLenOnDrop` value goes out of scope.
465b571afSAsahi Lina //
565b571afSAsahi Lina // The idea is: The length field in SetLenOnDrop is a local variable
665b571afSAsahi Lina // that the optimizer will see does not alias with any stores through the Vec's data
765b571afSAsahi Lina // pointer. This is a workaround for alias analysis issue #32155
865b571afSAsahi Lina pub(super) struct SetLenOnDrop<'a> {
965b571afSAsahi Lina     len: &'a mut usize,
1065b571afSAsahi Lina     local_len: usize,
1165b571afSAsahi Lina }
1265b571afSAsahi Lina 
1365b571afSAsahi Lina impl<'a> SetLenOnDrop<'a> {
1465b571afSAsahi Lina     #[inline]
new(len: &'a mut usize) -> Self1565b571afSAsahi Lina     pub(super) fn new(len: &'a mut usize) -> Self {
1665b571afSAsahi Lina         SetLenOnDrop { local_len: *len, len }
1765b571afSAsahi Lina     }
1865b571afSAsahi Lina 
1965b571afSAsahi Lina     #[inline]
increment_len(&mut self, increment: usize)2065b571afSAsahi Lina     pub(super) fn increment_len(&mut self, increment: usize) {
2165b571afSAsahi Lina         self.local_len += increment;
2265b571afSAsahi Lina     }
2365b571afSAsahi Lina 
2465b571afSAsahi Lina     #[inline]
current_len(&self) -> usize2565b571afSAsahi Lina     pub(super) fn current_len(&self) -> usize {
2665b571afSAsahi Lina         self.local_len
2765b571afSAsahi Lina     }
2865b571afSAsahi Lina }
2965b571afSAsahi Lina 
3065b571afSAsahi Lina impl Drop for SetLenOnDrop<'_> {
31     #[inline]
drop(&mut self)32     fn drop(&mut self) {
33         *self.len = self.local_len;
34     }
35 }
36