diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 39b0d183..7683c42c 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] - rust: [stable, nightly] + rust: ["1.95", stable, nightly] cargo_features: ['', 'alloc', 'default'] env: diff --git a/croaring/Cargo.toml b/croaring/Cargo.toml index 36196729..a7d5946f 100644 --- a/croaring/Cargo.toml +++ b/croaring/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "croaring" version = "2.6.0" -edition = "2021" +edition = "2024" authors = ["croaring-rs developers"] license = "Apache-2.0" description = "Rust wrapper for CRoaring" @@ -10,6 +10,7 @@ readme = "../README.md" keywords = ["RoaringBitmap", "croaring", "bitmap"] categories = ["data-structures", "api-bindings", "no-std::no-alloc"] documentation = "https://docs.rs/croaring" +rust-version = "1.95.0" [features] default = ["std", "allocator-api2"] diff --git a/croaring/benches/benches.rs b/croaring/benches/benches.rs index 37170886..76cfadbf 100644 --- a/croaring/benches/benches.rs +++ b/croaring/benches/benches.rs @@ -1,6 +1,5 @@ -use criterion::{ - black_box, criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion, Throughput, -}; +use criterion::{BatchSize, BenchmarkId, Criterion, Throughput, criterion_group, criterion_main}; +use std::hint::black_box; use std::ops::ControlFlow; use croaring::{Bitmap, Bitmap64, Portable}; diff --git a/croaring/benches/performance_comparison.rs b/croaring/benches/performance_comparison.rs index 68dab729..fb575e6a 100644 --- a/croaring/benches/performance_comparison.rs +++ b/croaring/benches/performance_comparison.rs @@ -1,9 +1,10 @@ use croaring::Bitmap; use roaring::RoaringBitmap; +use std::hint::black_box; use criterion::measurement::Measurement; use criterion::{ - black_box, criterion_group, criterion_main, BatchSize, BenchmarkGroup, BenchmarkId, Criterion, + BatchSize, BenchmarkGroup, BenchmarkId, Criterion, criterion_group, criterion_main, }; fn compare( @@ -151,7 +152,7 @@ fn binops(c: &mut Criterion) { }; macro_rules! comp_op { - ($new1:ident, $inplace1:ident, $new2:expr, $inplace2:expr $(,)?) => {{ + ($new1:ident, $inplace1:ident, $new2:expr_2021, $inplace2:expr_2021 $(,)?) => {{ compare( &mut c.benchmark_group(concat!(stringify!($new1), "_new")), gen_ours, diff --git a/croaring/src/bitmap/imp.rs b/croaring/src/bitmap/imp.rs index 7b0e3bc5..dd4b3211 100644 --- a/croaring/src/bitmap/imp.rs +++ b/croaring/src/bitmap/imp.rs @@ -16,18 +16,20 @@ impl Bitmap { #[allow(clippy::assertions_on_constants)] #[must_use] pub(crate) unsafe fn take_heap(p: *mut roaring_bitmap_t) -> Self { - // Based heavily on the `roaring.hh` cpp header from croaring - - assert!(!p.is_null()); - let result = Self { bitmap: *p }; - // This depends somewhat heavily on the implementation of croaring, - // In particular, that `roaring_bitmap_t` doesn't store any pointers into itself - // (it can be moved safely), and can be freed with `free`, without freeing the underlying - // containers and auxiliary data. Ensure this is still valid every time we update - // the version of croaring. - const _: () = assert!(ffi::ROARING_VERSION_MAJOR == 4); - ffi::roaring_free(p.cast::()); - result + unsafe { + // Based heavily on the `roaring.hh` cpp header from croaring + + assert!(!p.is_null()); + let result = Self { bitmap: *p }; + // This depends somewhat heavily on the implementation of croaring, + // In particular, that `roaring_bitmap_t` doesn't store any pointers into itself + // (it can be moved safely), and can be freed with `free`, without freeing the underlying + // containers and auxiliary data. Ensure this is still valid every time we update + // the version of croaring. + const _: () = assert!(ffi::ROARING_VERSION_MAJOR == 4); + ffi::roaring_free(p.cast::()); + result + } } /// Creates a new bitmap (initially empty) @@ -1523,11 +1525,7 @@ impl Bitmap { let mut element: u32 = 0; let result = unsafe { ffi::roaring_bitmap_select(&self.bitmap, position, &mut element) }; - if result { - Some(element) - } else { - None - } + if result { Some(element) } else { None } } /// Returns statistics about the composition of a roaring bitmap. diff --git a/croaring/src/bitmap/serialization.rs b/croaring/src/bitmap/serialization.rs index 1adf2503..ce3e4d02 100644 --- a/croaring/src/bitmap/serialization.rs +++ b/croaring/src/bitmap/serialization.rs @@ -157,8 +157,10 @@ impl Deserializer for Portable { #[doc(alias = "roaring_bitmap_portable_deserialize")] unsafe fn try_deserialize_unchecked(buffer: &[u8]) -> Bitmap { - let bitmap = ffi::roaring_bitmap_portable_deserialize(buffer.as_ptr().cast::()); - Bitmap::take_heap(bitmap) + unsafe { + let bitmap = ffi::roaring_bitmap_portable_deserialize(buffer.as_ptr().cast::()); + Bitmap::take_heap(bitmap) + } } } @@ -175,13 +177,15 @@ impl ViewDeserializer for Portable { /// #[doc(alias = "roaring_bitmap_portable_deserialize_frozen")] unsafe fn deserialize_view(data: &[u8]) -> BitmapView<'_> { - // portable_deserialize_size does some amount of checks, and returns zero if data cannot be valid - debug_assert_ne!( - ffi::roaring_bitmap_portable_deserialize_size(data.as_ptr().cast(), data.len()), - 0, - ); - let roaring = ffi::roaring_bitmap_portable_deserialize_frozen(data.as_ptr().cast()); - BitmapView::take_heap(roaring) + unsafe { + // portable_deserialize_size does some amount of checks, and returns zero if data cannot be valid + debug_assert_ne!( + ffi::roaring_bitmap_portable_deserialize_size(data.as_ptr().cast(), data.len()), + 0, + ); + let roaring = ffi::roaring_bitmap_portable_deserialize_frozen(data.as_ptr().cast()); + BitmapView::take_heap(roaring) + } } } @@ -226,8 +230,10 @@ impl Deserializer for Native { #[doc(alias = "roaring_bitmap_deserialize")] unsafe fn try_deserialize_unchecked(buffer: &[u8]) -> Bitmap { - let bitmap = ffi::roaring_bitmap_deserialize(buffer.as_ptr().cast::()); - Bitmap::take_heap(bitmap) + unsafe { + let bitmap = ffi::roaring_bitmap_deserialize(buffer.as_ptr().cast::()); + Bitmap::take_heap(bitmap) + } } } @@ -261,9 +267,11 @@ impl ViewDeserializer for Frozen { /// /// See [`BitmapView::deserialize`] for examples. unsafe fn deserialize_view(data: &[u8]) -> BitmapView<'_> { - assert_eq!(data.as_ptr() as usize % Self::REQUIRED_ALIGNMENT, 0); + unsafe { + assert_eq!(data.as_ptr() as usize % Self::REQUIRED_ALIGNMENT, 0); - let roaring = ffi::roaring_bitmap_frozen_view(data.as_ptr().cast(), data.len()); - BitmapView::take_heap(roaring) + let roaring = ffi::roaring_bitmap_frozen_view(data.as_ptr().cast(), data.len()); + BitmapView::take_heap(roaring) + } } } diff --git a/croaring/src/bitmap/view.rs b/croaring/src/bitmap/view.rs index 763b65fc..7d00f615 100644 --- a/croaring/src/bitmap/view.rs +++ b/croaring/src/bitmap/view.rs @@ -21,23 +21,25 @@ impl<'a> BitmapView<'a> { #[inline] #[allow(clippy::assertions_on_constants)] pub(crate) unsafe fn take_heap(p: *const roaring_bitmap_t) -> Self { - // This depends somewhat heavily on the implementation of croaring, - // In particular, that `roaring_bitmap_t` doesn't store any pointers into itself - // (it can be moved safely), and a "frozen" bitmap is stored in an arena, and the - // `containers` array is stored immediately after the roaring_bitmap_t data. - // Ensure this is still valid every time we update - // the version of croaring. - const _: () = assert!(ffi::ROARING_VERSION_MAJOR == 4); + unsafe { + // This depends somewhat heavily on the implementation of croaring, + // In particular, that `roaring_bitmap_t` doesn't store any pointers into itself + // (it can be moved safely), and a "frozen" bitmap is stored in an arena, and the + // `containers` array is stored immediately after the roaring_bitmap_t data. + // Ensure this is still valid every time we update + // the version of croaring. + const _: () = assert!(ffi::ROARING_VERSION_MAJOR == 4); - assert!(!p.is_null()); + assert!(!p.is_null()); - // We will use this in the Drop implementation to re-create this pointer to pass to roaring_bitmap_free - // If this fails, we would pass junk to roaring_bitmap_free in Drop. - assert_eq!(p, original_bitmap_ptr(&*p)); + // We will use this in the Drop implementation to re-create this pointer to pass to roaring_bitmap_free + // If this fails, we would pass junk to roaring_bitmap_free in Drop. + assert_eq!(p, original_bitmap_ptr(&*p)); - Self { - bitmap: *p, - phantom: PhantomData, + Self { + bitmap: *p, + phantom: PhantomData, + } } } @@ -60,7 +62,7 @@ impl<'a> BitmapView<'a> { /// The data must be the result of serializing a bitmap with the same serialization format #[must_use] pub unsafe fn deserialize(data: &'a [u8]) -> Self { - S::deserialize_view(data) + unsafe { S::deserialize_view(data) } } /// Create an owned, mutable bitmap from this view diff --git a/croaring/src/bitmap64/iter.rs b/croaring/src/bitmap64/iter.rs index 49175155..067770cd 100644 --- a/croaring/src/bitmap64/iter.rs +++ b/croaring/src/bitmap64/iter.rs @@ -129,7 +129,7 @@ impl<'a> Bitmap64Cursor<'a> { } unsafe fn current_unchecked(&self) -> u64 { - ffi::roaring64_iterator_value(self.raw.as_ptr()) + unsafe { ffi::roaring64_iterator_value(self.raw.as_ptr()) } } /// Moves the cursor to the next value in the bitmap diff --git a/croaring/src/bitmap64/serialization.rs b/croaring/src/bitmap64/serialization.rs index 26785222..920196b7 100644 --- a/croaring/src/bitmap64/serialization.rs +++ b/croaring/src/bitmap64/serialization.rs @@ -159,7 +159,7 @@ impl Deserializer for Portable { } unsafe fn try_deserialize_unchecked(buffer: &[u8]) -> Bitmap64 { - Self::try_deserialize(buffer).unwrap_unchecked() + unsafe { Self::try_deserialize(buffer).unwrap_unchecked() } } fn find_end(buffer: &[u8]) -> Option { diff --git a/croaring/src/bitset/imp.rs b/croaring/src/bitset/imp.rs index e96cfaf9..32fe89a8 100644 --- a/croaring/src/bitset/imp.rs +++ b/croaring/src/bitset/imp.rs @@ -5,13 +5,15 @@ impl Bitset { #[inline] #[allow(clippy::assertions_on_constants)] pub(super) unsafe fn take_heap(p: *mut ffi::bitset_t) -> Self { - assert!(!p.is_null()); - let result = Self { bitset: p.read() }; - // It seems unlikely that the bitset type will meaningfully change, but check if we ever go - // to a version 3. - const _: () = assert!(ffi::ROARING_VERSION_MAJOR == 4); - ffi::roaring_free(p.cast()); - result + unsafe { + assert!(!p.is_null()); + let result = Self { bitset: p.read() }; + // It seems unlikely that the bitset type will meaningfully change, but check if we ever go + // to a version 3. + const _: () = assert!(ffi::ROARING_VERSION_MAJOR == 4); + ffi::roaring_free(p.cast()); + result + } } /// Access the raw underlying slice diff --git a/croaring/src/callback.rs b/croaring/src/callback.rs index ec27ba4a..56a812d1 100644 --- a/croaring/src/callback.rs +++ b/croaring/src/callback.rs @@ -24,19 +24,21 @@ impl CallbackWrapper { F: FnMut(I) -> ControlFlow, I: panic::UnwindSafe, { - let wrapper = &mut *(arg as *mut Self); - let f = &mut wrapper.f; - let f = AssertUnwindSafe(|| f(value)); - let result = std::panic::catch_unwind(f); - match result { - Ok(ControlFlow::Continue(())) => true, - Ok(cf @ ControlFlow::Break(_)) => { - wrapper.result = Ok(cf); - false - } - Err(err) => { - wrapper.result = Err(err); - false + unsafe { + let wrapper = &mut *(arg as *mut Self); + let f = &mut wrapper.f; + let f = AssertUnwindSafe(|| f(value)); + let result = std::panic::catch_unwind(f); + match result { + Ok(ControlFlow::Continue(())) => true, + Ok(cf @ ControlFlow::Break(_)) => { + wrapper.result = Ok(cf); + false + } + Err(err) => { + wrapper.result = Err(err); + false + } } } } diff --git a/croaring/src/rust_alloc/custom_alloc.rs b/croaring/src/rust_alloc/custom_alloc.rs index c989f325..8e4c97b3 100644 --- a/croaring/src/rust_alloc/custom_alloc.rs +++ b/croaring/src/rust_alloc/custom_alloc.rs @@ -1,95 +1,107 @@ -use super::{layout, AlignedLayout}; +use super::{AlignedLayout, layout}; use allocator_api2::alloc::Allocator; use core::cell::UnsafeCell; use core::mem::MaybeUninit; use core::ptr::NonNull; unsafe extern "C" fn malloc(size: usize) -> *mut core::ffi::c_void { - let Some(layout) = layout(size) else { - return core::ptr::null_mut(); - }; - let allocator = ALLOCATOR.get(); - let Ok(ptr) = allocator.allocate(layout) else { - return core::ptr::null_mut(); - }; - let size_ptr = ptr.cast::(); - size_ptr.write(size); - size_ptr.add(1).cast().as_ptr() + unsafe { + let Some(layout) = layout(size) else { + return core::ptr::null_mut(); + }; + let allocator = ALLOCATOR.get(); + let Ok(ptr) = allocator.allocate(layout) else { + return core::ptr::null_mut(); + }; + let size_ptr = ptr.cast::(); + size_ptr.write(size); + size_ptr.add(1).cast().as_ptr() + } } unsafe extern "C" fn calloc(nmemb: usize, size: usize) -> *mut core::ffi::c_void { - let Some(total_size) = nmemb.checked_mul(size) else { - return core::ptr::null_mut(); - }; - let Some(layout) = layout(total_size) else { - return core::ptr::null_mut(); - }; - let allocator = ALLOCATOR.get(); - let Ok(ptr) = allocator.allocate_zeroed(layout) else { - return core::ptr::null_mut(); - }; - let size_ptr = ptr.cast::(); - size_ptr.write(total_size); - size_ptr.add(1).cast().as_ptr() + unsafe { + let Some(total_size) = nmemb.checked_mul(size) else { + return core::ptr::null_mut(); + }; + let Some(layout) = layout(total_size) else { + return core::ptr::null_mut(); + }; + let allocator = ALLOCATOR.get(); + let Ok(ptr) = allocator.allocate_zeroed(layout) else { + return core::ptr::null_mut(); + }; + let size_ptr = ptr.cast::(); + size_ptr.write(total_size); + size_ptr.add(1).cast().as_ptr() + } } unsafe extern "C" fn realloc(ptr: *mut core::ffi::c_void, size: usize) -> *mut core::ffi::c_void { - let Some(ptr) = NonNull::new(ptr) else { - return malloc(size); - }; - let ptr = ptr.cast::(); - let size_ptr = ptr.cast::().sub(1); - let old_size = size_ptr.read(); - let old_layout = layout(old_size).unwrap(); - let allocator = ALLOCATOR.get(); - if size == 0 { - allocator.deallocate(ptr, old_layout); - return core::ptr::null_mut(); + unsafe { + let Some(ptr) = NonNull::new(ptr) else { + return malloc(size); + }; + let ptr = ptr.cast::(); + let size_ptr = ptr.cast::().sub(1); + let old_size = size_ptr.read(); + let old_layout = layout(old_size).unwrap(); + let allocator = ALLOCATOR.get(); + if size == 0 { + allocator.deallocate(ptr, old_layout); + return core::ptr::null_mut(); + } + let Some(new_layout) = layout(size) else { + return core::ptr::null_mut(); + }; + let Ok(new_ptr) = allocator.grow(ptr, old_layout, new_layout) else { + return core::ptr::null_mut(); + }; + let new_size_ptr = new_ptr.cast::(); + new_size_ptr.write(size); + new_size_ptr.add(1).cast().as_ptr() } - let Some(new_layout) = layout(size) else { - return core::ptr::null_mut(); - }; - let Ok(new_ptr) = allocator.grow(ptr, old_layout, new_layout) else { - return core::ptr::null_mut(); - }; - let new_size_ptr = new_ptr.cast::(); - new_size_ptr.write(size); - new_size_ptr.add(1).cast().as_ptr() } unsafe extern "C" fn free(ptr: *mut core::ffi::c_void) { - let Some(ptr) = NonNull::new(ptr) else { - return; - }; - let size_ptr = ptr.cast::().sub(1); - let size = size_ptr.read(); - // If the size would overflow, it would have failed to be allocated in the first place. - let layout = layout(size).unwrap(); - let allocator = ALLOCATOR.get(); - allocator.deallocate(size_ptr.cast(), layout); + unsafe { + let Some(ptr) = NonNull::new(ptr) else { + return; + }; + let size_ptr = ptr.cast::().sub(1); + let size = size_ptr.read(); + // If the size would overflow, it would have failed to be allocated in the first place. + let layout = layout(size).unwrap(); + let allocator = ALLOCATOR.get(); + allocator.deallocate(size_ptr.cast(), layout); + } } unsafe extern "C" fn aligned_malloc(align: usize, size: usize) -> *mut core::ffi::c_void { - let Some(layout) = AlignedLayout::new(size, align) else { - return core::ptr::null_mut(); - }; - let allocator = ALLOCATOR.get(); - let Ok(allocated_ptr) = allocator.allocate(layout.0) else { - return core::ptr::null_mut(); - }; - layout - .store_and_return(allocated_ptr.cast().as_ptr()) - .cast() + unsafe { + let Some(layout) = AlignedLayout::new(size, align) else { + return core::ptr::null_mut(); + }; + let allocator = ALLOCATOR.get(); + let Ok(allocated_ptr) = allocator.allocate(layout.0) else { + return core::ptr::null_mut(); + }; + layout + .store_and_return(allocated_ptr.cast().as_ptr()) + .cast() + } } unsafe extern "C" fn aligned_free(ptr: *mut core::ffi::c_void) { - let Some(ptr) = NonNull::new(ptr) else { - return; - }; - let (allocated_ptr, layout) = AlignedLayout::from_raw(ptr.cast().as_ptr()); - let allocated_ptr = NonNull::new_unchecked(allocated_ptr); - let allocator = ALLOCATOR.get(); - allocator.deallocate(allocated_ptr.cast(), layout.0); + unsafe { + let Some(ptr) = NonNull::new(ptr) else { + return; + }; + let (allocated_ptr, layout) = AlignedLayout::from_raw(ptr.cast().as_ptr()); + let allocated_ptr = NonNull::new_unchecked(allocated_ptr); + let allocator = ALLOCATOR.get(); + allocator.deallocate(allocated_ptr.cast(), layout.0); + } } const MEMORY_HOOKS: ffi::roaring_memory_t = ffi::roaring_memory_t { @@ -109,11 +121,13 @@ impl AllocatorSlot { } pub unsafe fn get(&self) -> &'static dyn Allocator { - (*self.0.get()).assume_init() + unsafe { (*self.0.get()).assume_init() } } pub unsafe fn set(&self, allocator: &'static dyn Allocator) { - (*self.0.get()).write(allocator); + unsafe { + (*self.0.get()).write(allocator); + } } } @@ -132,6 +146,8 @@ static ALLOCATOR: AllocatorSlot = AllocatorSlot::new(); /// Ideally, this function should be called early in the program's execution, before any other /// `CRoaring` functions are called. pub unsafe fn configure_custom_alloc(allocator: &'static dyn Allocator) { - ALLOCATOR.set(allocator); - ffi::roaring_init_memory_hook(MEMORY_HOOKS); + unsafe { + ALLOCATOR.set(allocator); + ffi::roaring_init_memory_hook(MEMORY_HOOKS); + } } diff --git a/croaring/src/rust_alloc/global_alloc.rs b/croaring/src/rust_alloc/global_alloc.rs index 5fc92833..1cf35168 100644 --- a/croaring/src/rust_alloc/global_alloc.rs +++ b/croaring/src/rust_alloc/global_alloc.rs @@ -1,82 +1,94 @@ -use super::{layout, AlignedLayout}; +use super::{AlignedLayout, layout}; unsafe extern "C" fn malloc(size: usize) -> *mut core::ffi::c_void { - let Some(layout) = layout(size) else { - return core::ptr::null_mut(); - }; - let ptr = alloc::alloc::alloc(layout); - if ptr.is_null() { - return ptr.cast(); + unsafe { + let Some(layout) = layout(size) else { + return core::ptr::null_mut(); + }; + let ptr = alloc::alloc::alloc(layout); + if ptr.is_null() { + return ptr.cast(); + } + let size_ptr = ptr.cast::(); + size_ptr.write(size); + size_ptr.add(1).cast() } - let size_ptr = ptr.cast::(); - size_ptr.write(size); - size_ptr.add(1).cast() } unsafe extern "C" fn calloc(nmemb: usize, size: usize) -> *mut core::ffi::c_void { - let Some(total_size) = nmemb.checked_mul(size) else { - return core::ptr::null_mut(); - }; - let Some(layout) = layout(total_size) else { - return core::ptr::null_mut(); - }; - let ptr = alloc::alloc::alloc_zeroed(layout); - if ptr.is_null() { - return core::ptr::null_mut(); + unsafe { + let Some(total_size) = nmemb.checked_mul(size) else { + return core::ptr::null_mut(); + }; + let Some(layout) = layout(total_size) else { + return core::ptr::null_mut(); + }; + let ptr = alloc::alloc::alloc_zeroed(layout); + if ptr.is_null() { + return core::ptr::null_mut(); + } + let size_ptr = ptr.cast::(); + size_ptr.write(total_size); + size_ptr.add(1).cast() } - let size_ptr = ptr.cast::(); - size_ptr.write(total_size); - size_ptr.add(1).cast() } unsafe extern "C" fn realloc(ptr: *mut core::ffi::c_void, size: usize) -> *mut core::ffi::c_void { - if ptr.is_null() { - return malloc(size); - } - let size_ptr = ptr.cast::().sub(1); - let old_size = size_ptr.read(); - let old_layout = layout(old_size).unwrap(); - if size == 0 { - alloc::alloc::dealloc(size_ptr.cast::(), old_layout); - return core::ptr::null_mut(); - } - let new_ptr = alloc::alloc::realloc(size_ptr.cast(), old_layout, size + size_of::()); - if new_ptr.is_null() { - return core::ptr::null_mut(); + unsafe { + if ptr.is_null() { + return malloc(size); + } + let size_ptr = ptr.cast::().sub(1); + let old_size = size_ptr.read(); + let old_layout = layout(old_size).unwrap(); + if size == 0 { + alloc::alloc::dealloc(size_ptr.cast::(), old_layout); + return core::ptr::null_mut(); + } + let new_ptr = alloc::alloc::realloc(size_ptr.cast(), old_layout, size + size_of::()); + if new_ptr.is_null() { + return core::ptr::null_mut(); + } + let new_size_ptr = new_ptr.cast::(); + new_size_ptr.write(size); + new_size_ptr.add(1).cast() } - let new_size_ptr = new_ptr.cast::(); - new_size_ptr.write(size); - new_size_ptr.add(1).cast() } unsafe extern "C" fn free(ptr: *mut core::ffi::c_void) { - if ptr.is_null() { - return; + unsafe { + if ptr.is_null() { + return; + } + let size_ptr = ptr.cast::().sub(1); + let size = size_ptr.read(); + // If the size would overflow, it would have failed to be allocated in the first place. + let layout = layout(size).unwrap(); + alloc::alloc::dealloc(size_ptr.cast(), layout); } - let size_ptr = ptr.cast::().sub(1); - let size = size_ptr.read(); - // If the size would overflow, it would have failed to be allocated in the first place. - let layout = layout(size).unwrap(); - alloc::alloc::dealloc(size_ptr.cast(), layout); } unsafe extern "C" fn aligned_malloc(align: usize, size: usize) -> *mut core::ffi::c_void { - let Some(layout) = AlignedLayout::new(size, align) else { - return core::ptr::null_mut(); - }; - let allocated_ptr = alloc::alloc::alloc(layout.0); - if allocated_ptr.is_null() { - return core::ptr::null_mut(); + unsafe { + let Some(layout) = AlignedLayout::new(size, align) else { + return core::ptr::null_mut(); + }; + let allocated_ptr = alloc::alloc::alloc(layout.0); + if allocated_ptr.is_null() { + return core::ptr::null_mut(); + } + layout.store_and_return(allocated_ptr).cast() } - layout.store_and_return(allocated_ptr).cast() } unsafe extern "C" fn aligned_free(ptr: *mut core::ffi::c_void) { - if ptr.is_null() { - return; + unsafe { + if ptr.is_null() { + return; + } + let (allocated_ptr, layout) = AlignedLayout::from_raw(ptr); + alloc::alloc::dealloc(allocated_ptr.cast(), layout.0); } - let (allocated_ptr, layout) = AlignedLayout::from_raw(ptr); - alloc::alloc::dealloc(allocated_ptr.cast(), layout.0); } const MEMORY_HOOKS: ffi::roaring_memory_t = ffi::roaring_memory_t { @@ -98,7 +110,9 @@ const MEMORY_HOOKS: ffi::roaring_memory_t = ffi::roaring_memory_t { /// Ideally, this function should be called early in the program's execution, before any other /// `CRoaring` functions are called. pub unsafe fn configure_rust_alloc() { - ffi::roaring_init_memory_hook(MEMORY_HOOKS); + unsafe { + ffi::roaring_init_memory_hook(MEMORY_HOOKS); + } } #[test] diff --git a/croaring/src/rust_alloc/mod.rs b/croaring/src/rust_alloc/mod.rs index c6d12b46..ac333714 100644 --- a/croaring/src/rust_alloc/mod.rs +++ b/croaring/src/rust_alloc/mod.rs @@ -57,21 +57,25 @@ impl AlignedLayout { } unsafe fn store_and_return(&self, allocated_ptr: *mut u8) -> *mut u8 { - let size_ptr = allocated_ptr.add(self.padding()).cast::(); - size_ptr.write(SizeAlign { - size: self.0.size(), - align: self.0.align(), - }); - size_ptr.add(1).cast() + unsafe { + let size_ptr = allocated_ptr.add(self.padding()).cast::(); + size_ptr.write(SizeAlign { + size: self.0.size(), + align: self.0.align(), + }); + size_ptr.add(1).cast() + } } unsafe fn from_raw(raw_ptr: *mut core::ffi::c_void) -> (*mut core::ffi::c_void, Self) { - let size_ptr = raw_ptr.cast::().sub(1); - let SizeAlign { size, align } = size_ptr.read(); - let padding = padding_for_align(align); - let orig_ptr = size_ptr.cast::().sub(padding); - let layout = Layout::from_size_align_unchecked(size, align); - (orig_ptr.cast(), Self(layout)) + unsafe { + let size_ptr = raw_ptr.cast::().sub(1); + let SizeAlign { size, align } = size_ptr.read(); + let padding = padding_for_align(align); + let orig_ptr = size_ptr.cast::().sub(padding); + let layout = Layout::from_size_align_unchecked(size, align); + (orig_ptr.cast(), Self(layout)) + } } } diff --git a/croaring/src/treemap/imp.rs b/croaring/src/treemap/imp.rs index a2fa9fab..5dc29c6f 100644 --- a/croaring/src/treemap/imp.rs +++ b/croaring/src/treemap/imp.rs @@ -3,8 +3,8 @@ use crate::Treemap; use super::util; use crate::treemap::{Deserializer, Serializer}; -use alloc::collections::btree_map::Entry; use alloc::collections::BTreeMap; +use alloc::collections::btree_map::Entry; use alloc::vec::Vec; use core::cmp::Ordering; use core::ops::{Bound, RangeBounds}; @@ -553,7 +553,7 @@ impl Treemap { let mut index = u64::from( range .next_back() - .filter(|(&key, _)| key == hi) + .filter(|&(&key, _)| key == hi) .and_then(|(_, bitmap)| bitmap.position(lo))?, ); for (_, bitmap) in range { diff --git a/croaring/src/treemap/serialization.rs b/croaring/src/treemap/serialization.rs index 3c101538..3b2c89f4 100644 --- a/croaring/src/treemap/serialization.rs +++ b/croaring/src/treemap/serialization.rs @@ -1,6 +1,6 @@ use crate::serialization::{Frozen, Native, Portable}; -use crate::{bitmap, Treemap}; use crate::{Bitmap, JvmLegacy}; +use crate::{Treemap, bitmap}; use alloc::collections::BTreeMap; use alloc::vec::Vec; use core::prelude::v1::*; diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 00000000..35011368 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1 @@ +style_edition = "2024"