fn drop(&mut self) { if core::mem::needs_drop::<T>() { let iter = core::mem::take(&mut self.elements); let ptr: *mut [T] = iter.into_slice(); // SAFETY: By the type invariants, we own these values so we may destroy them. unsafe { ptr::drop_in_place(ptr) }; } }} #[cfg(CONFIG_RUST_KVEC_KUNIT_TEST)]#[macros::kunit_tests(rust_kvec)]mod tests { use super::*; use crate::prelude::*; #[test] fn test_kvec_retain() { /// Verify correctness for one specific function. #[expect(clippy::needless_range_loop)] fn verify(c: &[bool]) { let mut vec1: KVec<usize> = KVec::with_capacity(c.len(), GFP_KERNEL).unwrap(); let mut vec2: KVec<usize> = KVec::with_capacity(c.len(), GFP_KERNEL).unwrap(); for i in 0..c.len() { vec1.push_within_capacity(i).unwrap(); if c[i] { vec2.push_within_capacity(i).unwrap(); } } vec1.retain(|i| c[*i]); assert_eq!(vec1, vec2); } /// Add one to a binary integer represented as a boolean array. fn add(value: &mut [bool]) { let mut carry = true; for v in value { let new_v = carry != *v; carry = carry && *v; *v = new_v; } } // This boolean array represents a function from index to boolean. We check that `retain` // behaves correctly for all possible boolean arrays of every possible length less than // ten. let mut func = KVec::with_capacity(10, GFP_KERNEL).unwrap(); for len in 0..10 { for _ in 0u32..1u32 << len { verify(&func); add(&mut func); } func.push_within_capacity(false).unwrap(); } } #[test] fn test_kvvec_shrink_to() { use crate::page::PAGE_SIZE; // Create a vector with capacity spanning multiple pages. let mut v = KVVec::<u8>::with_capacity(PAGE_SIZE * 4, GFP_KERNEL).unwrap(); // Add a few elements. v.push(1, GFP_KERNEL).unwrap(); v.push(2, GFP_KERNEL).unwrap(); v.push(3, GFP_KERNEL).unwrap(); let initial_capacity = v.capacity(); assert!(initial_capacity >= PAGE_SIZE * 4); // Shrink to a capacity that would free at least one page. v.shrink_to(PAGE_SIZE, GFP_KERNEL).unwrap(); // Capacity should have been reduced. assert!(v.capacity() < initial_capacity); assert!(v.capacity() >= PAGE_SIZE); // Elements should be preserved. assert_eq!(v.len(), 3); assert_eq!(v[0], 1); assert_eq!(v[1], 2); assert_eq!(v[2], 3); // Shrink to zero (should shrink to len). v.shrink_to(0, GFP_KERNEL).unwrap(); // Capacity should be at least the length. assert!(v.capacity() >= v.len()); // Elements should still be preserved. assert_eq!(v.len(), 3); assert_eq!(v[0], 1); assert_eq!(v[1], 2); assert_eq!(v[2], 3); } #[test] fn test_kvvec_shrink_to_empty() { use crate::page::PAGE_SIZE; // Create a vector with large capacity but no elements. let mut v = KVVec::<u8>::with_capacity(PAGE_SIZE * 4, GFP_KERNEL).unwrap(); assert!(v.is_empty()); // Shrink empty vector to zero. v.shrink_to(0, GFP_KERNEL).unwrap(); // Should have freed the allocation. assert_eq!(v.capacity(), 0); assert!(v.is_empty()); } #[test] fn test_kvvec_shrink_to_no_op() { use crate::page::PAGE_SIZE; // Create a small vector. let mut v = KVVec::<u8>::with_capacity(PAGE_SIZE, GFP_KERNEL).unwrap(); v.push(1, GFP_KERNEL).unwrap(); let capacity_before = v.capacity(); // Try to shrink to a capacity larger than current - should be no-op. v.shrink_to(capacity_before + 100, GFP_KERNEL).unwrap(); assert_eq!(v.capacity(), capacity_before); assert_eq!(v.len(), 1); assert_eq!(v[0], 1); } #[test] fn test_kvvec_shrink_to_respects_min_capacity() { use crate::page::PAGE_SIZE; // Create a vector with large capacity. let mut v = KVVec::<u8>::with_capacity(PAGE_SIZE * 4, GFP_KERNEL).unwrap(); // Add some elements. for i in 0..10u8 { v.push(i, GFP_KERNEL).unwrap(); } // Shrink to a min_capacity larger than length. let min_cap = PAGE_SIZE * 2; v.shrink_to(min_cap, GFP_KERNEL).unwrap(); // Capacity should be at least min_capacity. assert!(v.capacity() >= min_cap); // All elements preserved. assert_eq!(v.len(), 10); for i in 0..10u8 { assert_eq!(v[i as usize], i); } }}Lines 1501–1661 of 1661. Previous lines
fn drop(&mut self) { if core::mem::needs_drop::<T>() { let iter = core::mem::take(&mut self.elements); let ptr: *mut [T] = iter.into_slice(); // SAFETY: By the type invariants, we own these values so we may destroy them. unsafe { ptr::drop_in_place(ptr) }; } } } #[cfg(CONFIG_RUST_KVEC_KUNIT_TEST)] #[macros::kunit_tests(rust_kvec)] mod tests { use super::*; use crate::prelude::*; #[test] fn test_kvec_retain() { /// Verify correctness for one specific function. #[expect(clippy::needless_range_loop)] fn verify(c: &[bool]) { let mut vec1: KVec<usize> = KVec::with_capacity(c.len(), GFP_KERNEL).unwrap(); let mut vec2: KVec<usize> = KVec::with_capacity(c.len(), GFP_KERNEL).unwrap(); for i in 0..c.len() { vec1.push_within_capacity(i).unwrap(); if c[i] { vec2.push_within_capacity(i).unwrap(); } } vec1.retain(|i| c[*i]); assert_eq!(vec1, vec2); } /// Add one to a binary integer represented as a boolean array. fn add(value: &mut [bool]) { let mut carry = true; for v in value { let new_v = carry != *v; carry = carry && *v; *v = new_v; } } // This boolean array represents a function from index to boolean. We check that `retain` // behaves correctly for all possible boolean arrays of every possible length less than // ten. let mut func = KVec::with_capacity(10, GFP_KERNEL).unwrap(); for len in 0..10 { for _ in 0u32..1u32 << len { verify(&func); add(&mut func); } func.push_within_capacity(false).unwrap(); } } #[test] fn test_kvvec_shrink_to() { use crate::page::PAGE_SIZE; // Create a vector with capacity spanning multiple pages. let mut v = KVVec::<u8>::with_capacity(PAGE_SIZE * 4, GFP_KERNEL).unwrap(); // Add a few elements. v.push(1, GFP_KERNEL).unwrap(); v.push(2, GFP_KERNEL).unwrap(); v.push(3, GFP_KERNEL).unwrap(); let initial_capacity = v.capacity(); assert!(initial_capacity >= PAGE_SIZE * 4); // Shrink to a capacity that would free at least one page. v.shrink_to(PAGE_SIZE, GFP_KERNEL).unwrap(); // Capacity should have been reduced. assert!(v.capacity() < initial_capacity); assert!(v.capacity() >= PAGE_SIZE); // Elements should be preserved. assert_eq!(v.len(), 3); assert_eq!(v[0], 1); assert_eq!(v[1], 2); assert_eq!(v[2], 3); // Shrink to zero (should shrink to len). v.shrink_to(0, GFP_KERNEL).unwrap(); // Capacity should be at least the length. assert!(v.capacity() >= v.len()); // Elements should still be preserved. assert_eq!(v.len(), 3); assert_eq!(v[0], 1); assert_eq!(v[1], 2); assert_eq!(v[2], 3); } #[test] fn test_kvvec_shrink_to_empty() { use crate::page::PAGE_SIZE; // Create a vector with large capacity but no elements. let mut v = KVVec::<u8>::with_capacity(PAGE_SIZE * 4, GFP_KERNEL).unwrap(); assert!(v.is_empty()); // Shrink empty vector to zero. v.shrink_to(0, GFP_KERNEL).unwrap(); // Should have freed the allocation. assert_eq!(v.capacity(), 0); assert!(v.is_empty()); } #[test] fn test_kvvec_shrink_to_no_op() { use crate::page::PAGE_SIZE; // Create a small vector. let mut v = KVVec::<u8>::with_capacity(PAGE_SIZE, GFP_KERNEL).unwrap(); v.push(1, GFP_KERNEL).unwrap(); let capacity_before = v.capacity(); // Try to shrink to a capacity larger than current - should be no-op. v.shrink_to(capacity_before + 100, GFP_KERNEL).unwrap(); assert_eq!(v.capacity(), capacity_before); assert_eq!(v.len(), 1); assert_eq!(v[0], 1); } #[test] fn test_kvvec_shrink_to_respects_min_capacity() { use crate::page::PAGE_SIZE; // Create a vector with large capacity. let mut v = KVVec::<u8>::with_capacity(PAGE_SIZE * 4, GFP_KERNEL).unwrap(); // Add some elements. for i in 0..10u8 { v.push(i, GFP_KERNEL).unwrap(); } // Shrink to a min_capacity larger than length. let min_cap = PAGE_SIZE * 2; v.shrink_to(min_cap, GFP_KERNEL).unwrap(); // Capacity should be at least min_capacity. assert!(v.capacity() >= min_cap); // All elements preserved. assert_eq!(v.len(), 10); for i in 0..10u8 { assert_eq!(v[i as usize], i); } } }