diff --git a/src/bytes_mut.rs b/src/bytes_mut.rs index 61c0460ca..0e0299e62 100644 --- a/src/bytes_mut.rs +++ b/src/bytes_mut.rs @@ -162,8 +162,15 @@ impl BytesMut { /// assert_eq!(&b"xy"[..], &bytes[..]); /// ``` #[inline] + #[cfg(not(all(loom, test)))] + pub const fn new() -> BytesMut { + // original_capacity_to_repr(0) == 0; it can't be const in Rust 1.39 due to the min operation + Self::from_vec_inner(NonNull::dangling(), 0, 0, 0) + } + + #[cfg(all(loom, test))] pub fn new() -> BytesMut { - BytesMut::with_capacity(0) + Self::from_vec_inner(NonNull::dangling(), 0, 0, 0) } /// Returns the number of bytes contained in this `BytesMut`. @@ -739,13 +746,24 @@ impl BytesMut { // internal change could make a simple pattern (`BytesMut::from(vec)`) // suddenly a lot more expensive. #[inline] - pub(crate) fn from_vec(mut vec: Vec) -> BytesMut { + pub(crate) fn from_vec(vec: Vec) -> BytesMut { + let mut vec = ManuallyDrop::new(vec); let ptr = vptr(vec.as_mut_ptr()); let len = vec.len(); let cap = vec.capacity(); - mem::forget(vec); let original_capacity_repr = original_capacity_to_repr(cap); + + Self::from_vec_inner(ptr, len, cap, original_capacity_repr) + } + + #[inline(always)] + const fn from_vec_inner( + ptr: NonNull, + len: usize, + cap: usize, + original_capacity_repr: usize, + ) -> BytesMut { let data = (original_capacity_repr << ORIGINAL_CAPACITY_OFFSET) | KIND_VEC; BytesMut { @@ -1250,6 +1268,7 @@ impl Shared { } } +#[inline] fn original_capacity_to_repr(cap: usize) -> usize { let width = PTR_WIDTH - ((cap >> MIN_ORIGINAL_CAPACITY_WIDTH).leading_zeros() as usize); cmp::min( @@ -1258,6 +1277,7 @@ fn original_capacity_to_repr(cap: usize) -> usize { ) } +#[inline] fn original_capacity_from_repr(repr: usize) -> usize { if repr == 0 { return 0; @@ -1476,6 +1496,7 @@ impl PartialEq for BytesMut { } } +#[inline] fn vptr(ptr: *mut u8) -> NonNull { if cfg!(debug_assertions) { NonNull::new(ptr).expect("Vec pointer should be non-null")