From ee4e17bcfcd62f60d98ef23d8d1d92350cc43f27 Mon Sep 17 00:00:00 2001 From: danielhenrymantilla Date: Mon, 24 Jun 2019 17:34:57 +0200 Subject: [PATCH 1/2] Replaced *mut T by Option> in box.rs Normalised formatting on src/box.rs --- src/boxed.rs | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/boxed.rs b/src/boxed.rs index 05b53f6..e3f3daa 100644 --- a/src/boxed.rs +++ b/src/boxed.rs @@ -1,17 +1,27 @@ -use std::{alloc, mem, ptr}; +use std::{ + alloc, mem, + ptr::{self, NonNull}, +}; /// A typesafe helper that stores the allocated pointer without the data initialized. -pub struct BoxAllocation(*mut T); +pub struct BoxAllocation( + // ptr cannot be null since it would mean the allocation failed. + // Note: covariance is acceptable since this eventually becomes a `Box`, + // which is covariant too. + NonNull, +); impl BoxAllocation { /// Consumes self and writes the given value into the allocation. - pub fn init(mut self, value: T) -> Box { + #[inline(always)] // if this does not get inlined then copying happens + pub fn init(self, value: T) -> Box { if mem::size_of::() == 0 { return Box::new(value); } - let ptr = mem::replace(&mut self.0, ptr::null_mut()); unsafe { + let ptr = self.0.as_ptr(); + mem::forget(self); ptr::write(ptr, value); Box::from_raw(ptr) } @@ -20,16 +30,17 @@ impl BoxAllocation { impl Drop for BoxAllocation { fn drop(&mut self) { - if !self.0.is_null() { - let layout = alloc::Layout::new::(); - unsafe { - alloc::dealloc(self.0 as *mut u8, layout); - } + if mem::size_of::() == 0 { + return; + } + + let layout = alloc::Layout::new::(); + unsafe { + alloc::dealloc(self.0.as_ptr() as *mut u8, layout); } } } - /// Helper trait for a `Box` type that allocates up-front. pub trait BoxHelper { /// Allocates the storage without providing any data. @@ -39,12 +50,13 @@ pub trait BoxHelper { impl BoxHelper for Box { fn alloc() -> BoxAllocation { if mem::size_of::() == 0 { - return BoxAllocation(ptr::null_mut()); + return BoxAllocation(NonNull::dangling()); } let layout = alloc::Layout::new::(); - BoxAllocation(unsafe { - alloc::alloc(layout) as *mut T - }) + BoxAllocation( + NonNull::new(unsafe { alloc::alloc(layout) as *mut T }) + .unwrap_or_else(|| alloc::handle_alloc_error(layout)), // oom + ) } } From 5872f04b1f8b83e173bcd7c2863966fb2b10d7e5 Mon Sep 17 00:00:00 2001 From: danielhenrymantilla Date: Mon, 24 Jun 2019 17:51:29 +0200 Subject: [PATCH 2/2] Bumped version --- CHANGELOG.md | 3 +++ Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5980ad6..c13ffa4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Change Log +## v0.1.4 (24-06-2019) + - `BoxHelper`: replaced nullable pointer with NonNull + ## v0.1.3 (31-05-2019) - fixed zero-sized box allocations - fixed file permissions in the package diff --git a/Cargo.toml b/Cargo.toml index fe13032..82ba1b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "copyless" description = "Ways to eliminate memcpy calls when using the standard library." -version = "0.1.3" +version = "0.1.4" authors = ["Dzmitry Malyshau "] license = "MPL-2.0" edition = "2018"