From 079453961882d8ccaa763e3c83601b43a69209ea Mon Sep 17 00:00:00 2001 From: Wodann Date: Wed, 27 Nov 2019 15:51:55 +0100 Subject: [PATCH 1/3] Make trait functions immutable This allows the traits to be implemented on immutable references. Internal mutability can still be achieved through Cell or RefCell --- src/alloc/mod.rs | 40 ++++++++++++++++++++-------------------- src/boxed.rs | 12 ++++++------ src/raw_vec.rs | 14 +++++++------- src/vec.rs | 4 ++-- tests/heap.rs | 2 +- 5 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/alloc/mod.rs b/src/alloc/mod.rs index 0502890..fbde2ca 100644 --- a/src/alloc/mod.rs +++ b/src/alloc/mod.rs @@ -149,7 +149,7 @@ pub trait BuildAllocRef: Sized { /// * the alignment of the `layout` must match the alignment used to allocate that block of /// memory unsafe fn build_alloc_ref( - &mut self, + &self, ptr: NonNull, layout: Option, ) -> Self::Ref; @@ -158,7 +158,7 @@ pub trait BuildAllocRef: Sized { pub trait DeallocRef: Sized { type BuildAlloc: BuildAllocRef; - fn get_build_alloc(&mut self) -> Self::BuildAlloc; + fn get_build_alloc(&self) -> Self::BuildAlloc; /// # Safety /// @@ -166,15 +166,15 @@ pub trait DeallocRef: Sized { /// * `layout` must *fit* that block of memory /// * the alignment of the `layout` must match the alignment used to allocate that block of /// memory - unsafe fn dealloc(&mut self, ptr: NonNull, layout: NonZeroLayout); + unsafe fn dealloc(&self, ptr: NonNull, layout: NonZeroLayout); } pub trait AllocRef: DeallocRef { type Error; - fn alloc(&mut self, layout: NonZeroLayout) -> Result, Self::Error>; + fn alloc(&self, layout: NonZeroLayout) -> Result, Self::Error>; - fn alloc_zeroed(&mut self, layout: NonZeroLayout) -> Result, Self::Error> { + fn alloc_zeroed(&self, layout: NonZeroLayout) -> Result, Self::Error> { let size = layout.size(); let p = self.alloc(layout)?; unsafe { @@ -193,7 +193,7 @@ pub trait AllocRef: DeallocRef { /// * `layout` must *fit* the `ptr` (see above); note the `new_size` argument need not fit it /// * `new_size` must not be less than `layout.size()` unsafe fn grow_in_place( - &mut self, + &self, ptr: NonNull, layout: NonZeroLayout, new_size: NonZeroUsize, @@ -212,7 +212,7 @@ pub trait AllocRef: DeallocRef { /// * `layout` must *fit* the `ptr` (see above); note the `new_size` argument need not fit it /// * `new_size` must not be greater than `layout.size()` (and must be greater than zero) unsafe fn shrink_in_place( - &mut self, + &self, ptr: NonNull, layout: NonZeroLayout, new_size: NonZeroUsize, @@ -251,7 +251,7 @@ pub trait ReallocRef: AllocRef { /// implement this trait atop an underlying native allocation /// library that aborts on memory exhaustion.) unsafe fn realloc( - &mut self, + &self, ptr: NonNull, old_layout: NonZeroLayout, new_layout: NonZeroLayout, @@ -297,7 +297,7 @@ macro_rules! impl_buildalloc_alloc_zst { type Ref = Self; unsafe fn build_alloc_ref( - &mut self, + &self, _ptr: NonNull, _layout: Option, ) -> Self::Ref { @@ -314,11 +314,11 @@ impl_buildalloc_alloc_zst!(System); impl DeallocRef for Global { type BuildAlloc = Self; - fn get_build_alloc(&mut self) -> Self::BuildAlloc { + fn get_build_alloc(&self) -> Self::BuildAlloc { Self } - unsafe fn dealloc(&mut self, ptr: NonNull, layout: NonZeroLayout) { + unsafe fn dealloc(&self, ptr: NonNull, layout: NonZeroLayout) { #[allow(deprecated)] dealloc(ptr.as_ptr(), layout.into()) } @@ -327,14 +327,14 @@ impl DeallocRef for Global { impl AllocRef for Global { type Error = AllocErr; - fn alloc(&mut self, layout: NonZeroLayout) -> Result, Self::Error> { + fn alloc(&self, layout: NonZeroLayout) -> Result, Self::Error> { #[allow(deprecated)] unsafe { NonNull::new(alloc(layout.into())).ok_or(AllocErr) } } - fn alloc_zeroed(&mut self, layout: NonZeroLayout) -> Result, Self::Error> { + fn alloc_zeroed(&self, layout: NonZeroLayout) -> Result, Self::Error> { #[allow(deprecated)] unsafe { NonNull::new(alloc_zeroed(layout.into())).ok_or(AllocErr) @@ -345,7 +345,7 @@ impl AllocRef for Global { impl ReallocRef for Global { // FIXME: Remove `else` branch. This is needed, as std provides old method. unsafe fn realloc( - &mut self, + &self, ptr: NonNull, old_layout: NonZeroLayout, new_layout: NonZeroLayout, @@ -369,11 +369,11 @@ impl ReallocRef for Global { impl DeallocRef for System { type BuildAlloc = Self; - fn get_build_alloc(&mut self) -> Self::BuildAlloc { + fn get_build_alloc(&self) -> Self::BuildAlloc { Self } - unsafe fn dealloc(&mut self, ptr: NonNull, layout: NonZeroLayout) { + unsafe fn dealloc(&self, ptr: NonNull, layout: NonZeroLayout) { GlobalAlloc::dealloc(self, ptr.as_ptr(), layout.into()) } } @@ -382,11 +382,11 @@ impl DeallocRef for System { impl AllocRef for System { type Error = AllocErr; - fn alloc(&mut self, layout: NonZeroLayout) -> Result, Self::Error> { + fn alloc(&self, layout: NonZeroLayout) -> Result, Self::Error> { unsafe { NonNull::new(GlobalAlloc::alloc(self, layout.into())).ok_or(AllocErr) } } - fn alloc_zeroed(&mut self, layout: NonZeroLayout) -> Result, Self::Error> { + fn alloc_zeroed(&self, layout: NonZeroLayout) -> Result, Self::Error> { unsafe { NonNull::new(GlobalAlloc::alloc_zeroed(self, layout.into())).ok_or(AllocErr) } } } @@ -395,7 +395,7 @@ impl AllocRef for System { impl ReallocRef for System { // FIXME: Remove `else` branch. This is needed, as std provides old method. unsafe fn realloc( - &mut self, + &self, ptr: NonNull, old_layout: NonZeroLayout, new_layout: NonZeroLayout, @@ -417,7 +417,7 @@ impl ReallocRef for System { #[inline] unsafe fn alloc_copy_dealloc( - alloc: &mut A, + alloc: &A, ptr: NonNull, old_layout: NonZeroLayout, new_layout: NonZeroLayout, diff --git a/src/boxed.rs b/src/boxed.rs index 074c91d..062f041 100644 --- a/src/boxed.rs +++ b/src/boxed.rs @@ -201,7 +201,7 @@ impl Box { /// let five = Box::try_new_in(5, Global)?; /// # Ok::<_, alloc_wg::alloc::AllocErr>(()) /// ``` - pub fn try_new_in(x: T, mut a: A) -> Result { + pub fn try_new_in(x: T, a: A) -> Result { let ptr = if let Ok(layout) = NonZeroLayout::new::() { let ptr = a.alloc(layout)?.cast::(); unsafe { @@ -257,7 +257,7 @@ impl Box { /// assert_eq!(*five, 5); /// # Ok::<_, alloc_wg::alloc::AllocErr>(()) /// ``` - pub fn try_new_uninit_in(mut a: A) -> Result, A>, A::Error> { + pub fn try_new_uninit_in(a: A) -> Result, A>, A::Error> { let ptr = if let Ok(layout) = NonZeroLayout::new::() { let ptr: NonNull> = a.alloc(layout)?.cast(); ptr @@ -365,7 +365,7 @@ impl Box<[T], A> { /// ``` pub fn try_new_uninit_slice_in( len: usize, - mut a: A, + a: A, ) -> Result], A>, CollectionAllocErr> { let ptr = if mem::size_of::() == 0 || len == 0 { NonNull::dangling() @@ -732,7 +732,7 @@ fn drop_box(boxed: &mut Box) { unsafe { let ptr = boxed.ptr; ptr::drop_in_place(ptr.as_ptr()); - if let (mut alloc, Some(layout)) = boxed.alloc_ref() { + if let (alloc, Some(layout)) = boxed.alloc_ref() { alloc.dealloc(ptr.cast().into(), layout) } } @@ -807,7 +807,7 @@ where /// ``` #[inline] fn clone(&self) -> Self { - let mut b = self.build_alloc().clone(); + let b = self.build_alloc().clone(); let old_ptr = self.ptr.cast(); let old_layout = NonZeroLayout::for_value(self.as_ref()); @@ -1276,7 +1276,7 @@ where A::BuildAlloc: Clone, { fn clone(&self) -> Self { - let mut b = self.build_alloc().clone(); + let b = self.build_alloc().clone(); let old_ptr = self.ptr.cast(); let old_layout = NonZeroLayout::for_value(self.as_ref()); let a = unsafe { b.build_alloc_ref(old_ptr.into(), old_layout) }; diff --git a/src/raw_vec.rs b/src/raw_vec.rs index 3cc236c..11bc8c1 100644 --- a/src/raw_vec.rs +++ b/src/raw_vec.rs @@ -144,7 +144,7 @@ impl RawVec { impl RawVec { /// Like `new` but parameterized over the choice of allocator for the returned `RawVec`. - pub fn new_in(mut a: A) -> Self { + pub fn new_in(a: A) -> Self { let capacity = if mem::size_of::() == 0 { !0 } else { 0 }; Self { ptr: Unique::empty(), @@ -226,7 +226,7 @@ impl RawVec { fn allocate_in( capacity: usize, zeroed: bool, - mut alloc: A, + alloc: A, ) -> Result> where A: AllocRef, @@ -443,7 +443,7 @@ impl RawVec { return Err(CollectionAllocErr::CapacityOverflow); } - let (mut alloc, old_layout) = self.alloc_ref(); + let (alloc, old_layout) = self.alloc_ref(); let (new_cap, ptr) = if let Some(old_layout) = old_layout { // Since we guarantee that we never allocate more than // `isize::MAX` bytes, `elem_size * self.cap <= isize::MAX` as @@ -524,7 +524,7 @@ impl RawVec { return Err(CapacityOverflow); } - let (mut alloc, old_layout) = if let (alloc, Some(layout)) = self.alloc_ref() { + let (alloc, old_layout) = if let (alloc, Some(layout)) = self.alloc_ref() { (alloc, layout) } else { return Ok(false); // nothing to double @@ -701,7 +701,7 @@ impl RawVec { return Ok(false); } - let (mut alloc, old_layout) = if let (alloc, Some(layout)) = self.alloc_ref() { + let (alloc, old_layout) = if let (alloc, Some(layout)) = self.alloc_ref() { (alloc, layout) } else { return Ok(false); // nothing to double @@ -846,7 +846,7 @@ impl RawVec { let _ = alloc_guard(new_layout.size().get(), new_layout.align().get())?; - let (mut alloc, old_layout) = self.alloc_ref(); + let (alloc, old_layout) = self.alloc_ref(); let result = if let Some(layout) = old_layout { unsafe { alloc.realloc(self.ptr.cast().into(), layout, new_layout) } } else { @@ -888,7 +888,7 @@ enum ReserveStrategy { impl RawVec { /// Frees the memory owned by the `RawVec` *without* trying to Drop its contents. pub fn dealloc_buffer(&mut self) { - if let (mut alloc, Some(layout)) = self.alloc_ref() { + if let (alloc, Some(layout)) = self.alloc_ref() { unsafe { alloc.dealloc(self.ptr.cast().into(), layout) } } } diff --git a/src/vec.rs b/src/vec.rs index 50b7b45..de2c0e9 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -2185,7 +2185,7 @@ where #[must_use] #[inline] fn clone(&self) -> Self { - let mut b = self.buf.build_alloc().clone(); + let b = self.buf.build_alloc().clone(); let old_layout = self.buf.current_layout(); unsafe { @@ -2463,7 +2463,7 @@ where } impl SpecExtend, A> for Vec { - fn try_from_iter_in(iter: IntoIter, mut a: A) -> Result> { + fn try_from_iter_in(iter: IntoIter, a: A) -> Result> { // A common case is passing a vector into a function which immediately // re-collects into a vector. We can short circuit this if the IntoIter // has not been advanced at all. diff --git a/tests/heap.rs b/tests/heap.rs index 5dd17f3..4f2c08c 100644 --- a/tests/heap.rs +++ b/tests/heap.rs @@ -13,7 +13,7 @@ fn std_heap_overaligned_request() { check_overalign_requests(Global) } -fn check_overalign_requests(mut allocator: T) +fn check_overalign_requests(allocator: T) where T::Error: Debug, { From a3fa9171aeffc344f088218cdd4481a9be0d8d0d Mon Sep 17 00:00:00 2001 From: Wodann Date: Wed, 27 Nov 2019 16:41:10 +0100 Subject: [PATCH 2/3] Fix formatting --- src/alloc/mod.rs | 6 +----- src/raw_vec.rs | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/alloc/mod.rs b/src/alloc/mod.rs index fbde2ca..dfddacc 100644 --- a/src/alloc/mod.rs +++ b/src/alloc/mod.rs @@ -148,11 +148,7 @@ pub trait BuildAllocRef: Sized { /// * `layout` must *fit* that block of memory /// * the alignment of the `layout` must match the alignment used to allocate that block of /// memory - unsafe fn build_alloc_ref( - &self, - ptr: NonNull, - layout: Option, - ) -> Self::Ref; + unsafe fn build_alloc_ref(&self, ptr: NonNull, layout: Option) -> Self::Ref; } pub trait DeallocRef: Sized { diff --git a/src/raw_vec.rs b/src/raw_vec.rs index 11bc8c1..56b348a 100644 --- a/src/raw_vec.rs +++ b/src/raw_vec.rs @@ -223,11 +223,7 @@ impl RawVec { Self::allocate_in(capacity, true, a) } - fn allocate_in( - capacity: usize, - zeroed: bool, - alloc: A, - ) -> Result> + fn allocate_in(capacity: usize, zeroed: bool, alloc: A) -> Result> where A: AllocRef, { From bcc633ed908595caf921c7ddc1665b52d2b7fddd Mon Sep 17 00:00:00 2001 From: Wodann Date: Wed, 27 Nov 2019 23:04:00 +0100 Subject: [PATCH 3/3] Allow clippy warnings --- src/boxed.rs | 12 ++++++++---- src/raw_vec.rs | 6 ++++++ src/string.rs | 8 ++++++++ src/vec.rs | 3 +++ 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/boxed.rs b/src/boxed.rs index 062f041..39b99d7 100644 --- a/src/boxed.rs +++ b/src/boxed.rs @@ -182,7 +182,7 @@ impl Box { /// # #[allow(unused_variables)] /// let five = Box::new_in(5, Global); /// ``` - #[allow(clippy::inline_always)] + #[allow(clippy::inline_always, clippy::needless_pass_by_value)] #[inline(always)] pub fn new_in(x: T, a: A) -> Self { unsafe { Self::try_new_in(x, a).unwrap_unchecked() } @@ -201,6 +201,7 @@ impl Box { /// let five = Box::try_new_in(5, Global)?; /// # Ok::<_, alloc_wg::alloc::AllocErr>(()) /// ``` + #[allow(clippy::needless_pass_by_value)] pub fn try_new_in(x: T, a: A) -> Result { let ptr = if let Ok(layout) = NonZeroLayout::new::() { let ptr = a.alloc(layout)?.cast::(); @@ -232,7 +233,7 @@ impl Box { /// /// assert_eq!(*five, 5) /// ``` - #[allow(clippy::inline_always)] + #[allow(clippy::inline_always, clippy::needless_pass_by_value)] #[inline(always)] pub fn new_uninit_in(a: A) -> Box, A> { unsafe { Self::try_new_uninit_in(a).unwrap_unchecked() } @@ -257,6 +258,7 @@ impl Box { /// assert_eq!(*five, 5); /// # Ok::<_, alloc_wg::alloc::AllocErr>(()) /// ``` + #[allow(clippy::needless_pass_by_value)] pub fn try_new_uninit_in(a: A) -> Result, A>, A::Error> { let ptr = if let Ok(layout) = NonZeroLayout::new::() { let ptr: NonNull> = a.alloc(layout)?.cast(); @@ -269,7 +271,7 @@ impl Box { /// Constructs a new `Pin>` with the specified allocator. If `T` does not implement /// `Unpin`, then `x` will be pinned in memory and unable to be moved. - #[allow(clippy::inline_always)] + #[allow(clippy::inline_always, clippy::needless_pass_by_value)] #[inline(always)] pub fn pin_in(x: T, a: A) -> Pin { unsafe { Self::try_pin_in(x, a).unwrap_unchecked() } @@ -277,6 +279,7 @@ impl Box { /// Constructs a new `Pin>` with the specified allocator. If `T` does not implement /// `Unpin`, then `x` will be pinned in memory and unable to be moved. + #[allow(clippy::needless_pass_by_value)] #[inline] pub fn try_pin_in(x: T, a: A) -> Result, A::Error> { Self::try_new_in(x, a).map(Pin::from) @@ -335,7 +338,7 @@ impl Box<[T], A> { /// /// assert_eq!(*values, [1, 2, 3]); /// ``` - #[allow(clippy::inline_always)] + #[allow(clippy::inline_always, clippy::needless_pass_by_value)] #[inline(always)] pub fn new_uninit_slice_in(len: usize, a: A) -> Box<[mem::MaybeUninit], A> { unsafe { Self::try_new_uninit_slice_in(len, a).unwrap_unchecked() } @@ -363,6 +366,7 @@ impl Box<[T], A> { /// assert_eq!(*values, [1, 2, 3]); /// # Ok::<_, alloc_wg::collections::CollectionAllocErr>(()) /// ``` + #[allow(clippy::needless_pass_by_value)] pub fn try_new_uninit_slice_in( len: usize, a: A, diff --git a/src/raw_vec.rs b/src/raw_vec.rs index 56b348a..d1067e8 100644 --- a/src/raw_vec.rs +++ b/src/raw_vec.rs @@ -144,6 +144,7 @@ impl RawVec { impl RawVec { /// Like `new` but parameterized over the choice of allocator for the returned `RawVec`. + #[allow(clippy::needless_pass_by_value)] pub fn new_in(a: A) -> Self { let capacity = if mem::size_of::() == 0 { !0 } else { 0 }; Self { @@ -161,6 +162,7 @@ impl RawVec { /// /// * if the requested capacity exceeds `usize::MAX` bytes. /// * on 32-bit platforms if the requested capacity exceeds `isize::MAX` bytes. + #[allow(clippy::needless_pass_by_value)] pub fn with_capacity_in(capacity: usize, a: A) -> Self where A: AllocRef, @@ -181,6 +183,7 @@ impl RawVec { /// * `CapacityOverflow` if the requested capacity exceeds `usize::MAX` bytes. /// * `CapacityOverflow` on 32-bit platforms if the requested capacity exceeds `isize::MAX` bytes. /// * `AllocError` on OOM + #[allow(clippy::needless_pass_by_value)] pub fn try_with_capacity_in(capacity: usize, a: A) -> Result> where A: AllocRef, @@ -196,6 +199,7 @@ impl RawVec { /// /// * if the requested capacity exceeds `usize::MAX` bytes. /// * on 32-bit platforms if the requested capacity exceeds `isize::MAX` bytes. + #[allow(clippy::needless_pass_by_value)] pub fn with_capacity_zeroed_in(capacity: usize, a: A) -> Self where A: AllocRef, @@ -216,6 +220,7 @@ impl RawVec { /// * `CapacityOverflow` if the requested capacity exceeds `usize::MAX` bytes. /// * `CapacityOverflow` on 32-bit platforms if the requested capacity exceeds `isize::MAX` bytes. /// * `AllocError` on OOM + #[allow(clippy::needless_pass_by_value)] pub fn try_with_capacity_zeroed_in(capacity: usize, a: A) -> Result> where A: AllocRef, @@ -223,6 +228,7 @@ impl RawVec { Self::allocate_in(capacity, true, a) } + #[allow(clippy::needless_pass_by_value)] fn allocate_in(capacity: usize, zeroed: bool, alloc: A) -> Result> where A: AllocRef, diff --git a/src/string.rs b/src/string.rs index 980f798..b15b855 100644 --- a/src/string.rs +++ b/src/string.rs @@ -566,6 +566,7 @@ impl String { impl String { /// Like `new` but parameterized over the choice of allocator for the returned `String`. + #[allow(clippy::needless_pass_by_value)] #[inline] pub fn new_in(a: A) -> Self { Self { @@ -577,6 +578,7 @@ impl String { /// /// # Panics /// Panics if the allocation fails. + #[allow(clippy::needless_pass_by_value)] #[inline] pub fn with_capacity_in(capacity: usize, a: A) -> Self where @@ -588,6 +590,7 @@ impl String { } /// Like `with_capacity_in` but returns errors instead of panicking. + #[allow(clippy::needless_pass_by_value)] #[inline] pub fn try_with_capacity_in(capacity: usize, a: A) -> Result> where @@ -602,6 +605,7 @@ impl String { /// /// # Panics /// Panics if the allocation fails. + #[allow(clippy::needless_pass_by_value)] #[inline] pub fn from_str_in(s: &str, a: A) -> Self where @@ -613,6 +617,7 @@ impl String { } /// Like `from_str_in` but returns errors instead of panicking. + #[allow(clippy::needless_pass_by_value)] #[inline] pub fn try_from_str_in(s: &str, a: A) -> Result> where @@ -703,6 +708,7 @@ impl String { /// # Panics /// /// Panics if allocation fails. + #[allow(clippy::needless_pass_by_value)] pub fn from_utf8_lossy_in(v: &[u8], a: A) -> Self where A: ReallocRef, @@ -715,6 +721,7 @@ impl String { } /// Like `from_utf8_lossy_in` but returns errors instead of panicking. + #[allow(clippy::needless_pass_by_value)] pub fn try_from_utf8_lossy_in(v: &[u8], a: A) -> Result> where A: ReallocRef, @@ -751,6 +758,7 @@ impl String { } /// Like `from_utf16` but parameterized over the choice of allocator for the returned `String`. + #[allow(clippy::needless_pass_by_value)] pub fn from_utf16_in(v: &[u16], a: A) -> Result where A: ReallocRef, diff --git a/src/vec.rs b/src/vec.rs index de2c0e9..eee3c72 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -472,6 +472,7 @@ impl Vec { impl Vec { /// Like `new` but parameterized over the choice of allocator for the returned `Vec`. + #[allow(clippy::needless_pass_by_value)] #[inline] pub fn new_in(a: A) -> Self { Self { @@ -487,6 +488,7 @@ impl Vec { /// /// * if the requested capacity exceeds `usize::MAX` bytes. /// * on 32-bit platforms if the requested capacity exceeds `isize::MAX` bytes. + #[allow(clippy::needless_pass_by_value)] #[inline] pub fn with_capacity_in(capacity: usize, a: A) -> Self where @@ -506,6 +508,7 @@ impl Vec { /// * `CapacityOverflow` if the requested capacity exceeds `usize::MAX` bytes. /// * `CapacityOverflow` on 32-bit platforms if the requested capacity exceeds `isize::MAX` bytes. /// * `AllocError` on OOM + #[allow(clippy::needless_pass_by_value)] #[inline] pub fn try_with_capacity_in(capacity: usize, a: A) -> Result> where