Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ArrayVec::leak #235

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/arrayvec.rs
Expand Up @@ -579,6 +579,19 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
Ok(())
}

/// Leak the contents of the vector and return a reference to them as a mutable slice.
///
/// This sets len() to zero. The elements will not be dropped. The backing memory will
/// not be lost however, as the ArrayVec can be used again as soon as the returned slice
/// is dropped.
pub fn leak(&mut self) -> &mut [T] {
let orig_len = self.len();
unsafe {
self.set_len(0);
Copy link
Owner

@bluss bluss May 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be more comfortable to swap the order of these two lines actually!

A. We create a borrow of the whole vec as a &mut [T]
B. We modify self (set_len)

This is better in the order of B, then A, so that it's clear we don't invalidate the borrow. Miri apparently didn't react on this though?

slice::from_raw_parts_mut(self.as_mut_ptr(), orig_len)
}
}

/// Create a draining iterator that removes the specified range in the vector
/// and yields the removed items from start to end. The element range is
/// removed even if the iterator is not consumed until the end.
Expand Down
9 changes: 9 additions & 0 deletions tests/tests.rs
Expand Up @@ -331,6 +331,15 @@ fn test_still_works_with_option_arrayvec() {
println!("{:?}", array);
}

#[test]
fn test_leak() {
let mut v = ArrayVec::from([1,2,3,4,5,6,7,8]);
assert_eq!(v.leak(), [1,2,3,4,5,6,7,8]);
assert_eq!(v.len(), 0);
v.try_extend_from_slice(&[1,2,3]).unwrap();
assert_eq!(v.as_ref(), [1,2,3]);
}

#[test]
fn test_drain() {
let mut v = ArrayVec::from([0; 8]);
Expand Down