On 26.09.24 15:24, Danilo Krummrich wrote: > On Thu, Sep 26, 2024 at 01:00:58PM +0000, Benno Lossin wrote: >> On 12.09.24 00:52, Danilo Krummrich wrote: >>> +/// # Invariants >>> +/// >>> +/// One of the following `krealloc`, `vrealloc`, `kvrealloc`. >>> +struct ReallocFunc( >>> + unsafe extern "C" fn(*const core::ffi::c_void, usize, u32) -> *mut core::ffi::c_void, >>> +); >>> + >>> +impl ReallocFunc { >>> + // INVARIANT: `krealloc` satisfies the type invariants. >>> + const KREALLOC: Self = Self(bindings::krealloc); >>> + >>> + /// # Safety >>> + /// >>> + /// This method has the same safety requirements as [`Allocator::realloc`]. >>> + /// >>> + /// # Guarantees >>> + /// >>> + /// This method has the same guarantees as `Allocator::realloc`. Additionally >>> + /// - it accepts any pointer to a valid memory allocation allocated by this function. >>> + /// - memory allocated by this function remains valid until it is passed to this function. >>> + unsafe fn call( >>> + &self, >>> + ptr: Option<NonNull<u8>>, >>> + layout: Layout, >>> + flags: Flags, >>> + ) -> Result<NonNull<[u8]>, AllocError> { >>> + let size = aligned_size(layout); >>> + let ptr = match ptr { >>> + Some(ptr) => ptr.as_ptr(), >>> + None => ptr::null(), >>> + }; >>> + >>> + // SAFETY: >>> + // - `self.0` is one of `krealloc`, `vrealloc`, `kvrealloc` and thus only requires that >>> + // `ptr` is NULL or valid. >>> + // - `ptr` is either NULL or valid by the safety requirements of this function. >>> + // >>> + // GUARANTEE: >>> + // - `self.0` is one of `krealloc`, `vrealloc`, `kvrealloc`. >>> + // - Those functions provide the guarantees of this function. >>> + let raw_ptr = unsafe { >>> + // If `size == 0` and `ptr != NULL` the memory behind the pointer is freed. >>> + self.0(ptr.cast(), size, flags.0).cast() >>> + }; >>> + >>> + let ptr = if size == 0 { >>> + NonNull::dangling() >>> + } else { >>> + NonNull::new(raw_ptr).ok_or(AllocError)? >>> + }; >>> + >>> + Ok(NonNull::slice_from_raw_parts(ptr, size)) >>> + } >>> +} >> >> I remember asking you to split this into a different commit. I think you >> argued that it would be better to keep it in the same commit when >> bisecting. I don't think that applies in this case, are there any other >> disadvantages? > > I don't really like the intermediate `#[expect(dead_code)]`, plus it's > additional work you didn't really give me a motivation for, i.e. you did not > mention what would be the advantage. The advantage would be that it's easier to review (granted it probably is a bit late for that). I got confused a couple of times (but that's probably on me). > But sure, I will change it for the next version. Thanks --- Cheers, Benno