Skip to content

Commit 627c5de

Browse files
committed
Fix all build errors
1 parent f937b96 commit 627c5de

File tree

8 files changed

+142
-86
lines changed

8 files changed

+142
-86
lines changed

Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,8 @@ serde = { version = "1.0", optional = true }
2121

2222
[workspace]
2323
members = ["tests"]
24+
25+
[lints.rust]
26+
unexpected_cfgs = { level = "warn", check-cfg = [
27+
'cfg(no_global_oom_handling)',
28+
] }

src/stable/boxed.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ use core::task::{Context, Poll};
165165

166166
use super::alloc::{AllocError, Allocator, Global, Layout};
167167
use super::raw_vec::RawVec;
168+
use super::unique::Unique;
168169
#[cfg(not(no_global_oom_handling))]
169170
use super::vec::Vec;
170171
#[cfg(not(no_global_oom_handling))]
@@ -173,7 +174,7 @@ use alloc_crate::alloc::handle_alloc_error;
173174
/// A pointer type for heap allocation.
174175
///
175176
/// See the [module-level documentation](../../std/boxed/index.html) for more.
176-
pub struct Box<T: ?Sized, A: Allocator = Global>(NonNull<T>, A);
177+
pub struct Box<T: ?Sized, A: Allocator = Global>(Unique<T>, A);
177178

178179
// Safety: Box owns both T and A, so sending is safe if
179180
// sending is safe for T and A.
@@ -585,7 +586,11 @@ impl<T, A: Allocator> Box<T, A> {
585586
pub fn into_inner(boxed: Self) -> T {
586587
let ptr = boxed.0;
587588
let unboxed = unsafe { ptr.as_ptr().read() };
588-
unsafe { boxed.1.deallocate(ptr.cast(), Layout::new::<T>()) };
589+
unsafe {
590+
boxed
591+
.1
592+
.deallocate(ptr.as_non_null_ptr().cast(), Layout::new::<T>())
593+
};
589594
unboxed
590595
}
591596
}
@@ -885,8 +890,8 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
885890
/// ```
886891
#[inline(always)]
887892
pub unsafe fn assume_init(self) -> Box<T, A> {
888-
let (raw, alloc) = Box::into_raw_with_allocator(self);
889-
unsafe { Box::from_raw_in(raw as *mut T, alloc) }
893+
let (raw, alloc) = Self::into_raw_with_allocator(self);
894+
unsafe { Box::<T, A>::from_raw_in(raw as *mut T, alloc) }
890895
}
891896

892897
/// Writes the value and converts to `Box<T, A>`.
@@ -958,8 +963,8 @@ impl<T, A: Allocator> Box<[mem::MaybeUninit<T>], A> {
958963
/// ```
959964
#[inline(always)]
960965
pub unsafe fn assume_init(self) -> Box<[T], A> {
961-
let (raw, alloc) = Box::into_raw_with_allocator(self);
962-
unsafe { Box::from_raw_in(raw as *mut [T], alloc) }
966+
let (raw, alloc) = Self::into_raw_with_allocator(self);
967+
unsafe { Box::<[T], A>::from_raw_in(raw as *mut [T], alloc) }
963968
}
964969
}
965970

@@ -1060,7 +1065,7 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
10601065
/// [`Layout`]: crate::Layout
10611066
#[inline(always)]
10621067
pub const unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self {
1063-
Box(unsafe { NonNull::new_unchecked(raw) }, alloc)
1068+
Box(unsafe { Unique::new_unchecked(raw) }, alloc)
10641069
}
10651070

10661071
/// Consumes the `Box`, returning a wrapped raw pointer.
@@ -1271,7 +1276,7 @@ impl<T: ?Sized, A: Allocator> Drop for Box<T, A> {
12711276
let layout = Layout::for_value::<T>(&**self);
12721277
unsafe {
12731278
ptr::drop_in_place(self.0.as_mut());
1274-
self.1.deallocate(self.0.cast(), layout);
1279+
self.1.deallocate(self.0.as_non_null_ptr().cast(), layout);
12751280
}
12761281
}
12771282
}
@@ -1289,17 +1294,17 @@ impl<T, A: Allocator + Default> Default for Box<[T], A> {
12891294
#[inline(always)]
12901295
fn default() -> Self {
12911296
let ptr: NonNull<[T]> = NonNull::<[T; 0]>::dangling();
1292-
Box(ptr, A::default())
1297+
Box(unsafe { Unique::new_unchecked(ptr.as_ptr()) }, A::default())
12931298
}
12941299
}
12951300

12961301
impl<A: Allocator + Default> Default for Box<str, A> {
12971302
#[inline(always)]
12981303
fn default() -> Self {
12991304
// SAFETY: This is the same as `Unique::cast<U>` but with an unsized `U = str`.
1300-
let ptr: NonNull<str> = unsafe {
1305+
let ptr: Unique<str> = unsafe {
13011306
let bytes: NonNull<[u8]> = NonNull::<[u8; 0]>::dangling();
1302-
NonNull::new_unchecked(bytes.as_ptr() as *mut str)
1307+
Unique::new_unchecked(bytes.as_ptr() as *mut str)
13031308
};
13041309
Box(ptr, A::default())
13051310
}

src/stable/mod.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,25 +21,29 @@ mod macros;
2121
#[cfg(feature = "alloc")]
2222
mod slice;
2323

24+
#[cfg(feature = "alloc")]
25+
mod unique;
26+
2427
/// Allows turning a [`Box<T: Sized, A>`][boxed::Box] into a [`Box<U: ?Sized, A>`][boxed::Box] where `T` can be unsizing-coerced into a `U`.
25-
///
28+
///
2629
/// This is the only way to create an `allocator_api2::boxed::Box` of an unsized type on stable.
27-
///
30+
///
2831
/// With the standard library's `alloc::boxed::Box`, this is done automatically using the unstable unsize traits, but this crate's Box
2932
/// can't take advantage of that machinery on stable. So, we need to use type inference and the fact that you *can*
3033
/// still coerce the inner pointer of a box to get the compiler to help us unsize it using this macro.
31-
///
34+
///
3235
/// # Example
33-
///
36+
///
3437
/// ```
3538
/// use allocator_api2::unsize_box;
3639
/// use allocator_api2::boxed::Box;
3740
/// use core::any::Any;
38-
///
41+
///
3942
/// let sized_box: Box<u64> = Box::new(0);
4043
/// let unsized_box: Box<dyn Any> = unsize_box!(sized_box);
4144
/// ```
4245
#[macro_export]
46+
#[cfg(feature = "alloc")]
4347
macro_rules! unsize_box {( $boxed:expr $(,)? ) => ({
4448
let (ptr, allocator) = ::allocator_api2::boxed::Box::into_raw_with_allocator($boxed);
4549
// we don't want to allow casting to arbitrary type U, but we do want to allow unsize coercion to happen.
@@ -49,7 +53,7 @@ macro_rules! unsize_box {( $boxed:expr $(,)? ) => ({
4953
// assign its result to.
5054
let ptr: *mut _ = ptr;
5155
// SAFETY: see above for why ptr's type can only be something that can be safely coerced.
52-
// also, ptr just came from a properly allocated box in the same allocator.
56+
// also, ptr just came from a properly allocated box in the same allocator.
5357
unsafe {
5458
::allocator_api2::boxed::Box::from_raw_in(ptr, allocator)
5559
}

src/stable/raw_vec.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ impl<T, A: Allocator> RawVec<T, A> {
242242
let me = ManuallyDrop::new(self);
243243
unsafe {
244244
let slice = slice::from_raw_parts_mut(me.ptr() as *mut MaybeUninit<T>, len);
245-
Box::from_raw_in(slice, ptr::read(&me.alloc))
245+
Box::<[MaybeUninit<T>], A>::from_raw_in(slice, ptr::read(&me.alloc))
246246
}
247247
}
248248

src/stable/unique.rs

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/// A wrapper around a raw non-null `*mut T` that indicates that the possessor
2+
/// of this wrapper owns the referent. Useful for building abstractions like
3+
/// `Box<T>`, `Vec<T>`, `String`, and `HashMap<K, V>`.
4+
///
5+
/// Unlike `*mut T`, `Unique<T>` behaves "as if" it were an instance of `T`.
6+
/// It implements `Send`/`Sync` if `T` is `Send`/`Sync`. It also implies
7+
/// the kind of strong aliasing guarantees an instance of `T` can expect:
8+
/// the referent of the pointer should not be modified without a unique path to
9+
/// its owning Unique.
10+
///
11+
/// If you're uncertain of whether it's correct to use `Unique` for your purposes,
12+
/// consider using `NonNull`, which has weaker semantics.
13+
///
14+
/// Unlike `*mut T`, the pointer must always be non-null, even if the pointer
15+
/// is never dereferenced. This is so that enums may use this forbidden value
16+
/// as a discriminant -- `Option<Unique<T>>` has the same size as `Unique<T>`.
17+
/// However the pointer may still dangle if it isn't dereferenced.
18+
///
19+
/// Unlike `*mut T`, `Unique<T>` is covariant over `T`. This should always be correct
20+
/// for any type which upholds Unique's aliasing requirements.
21+
#[repr(transparent)]
22+
pub(crate) struct Unique<T: ?Sized> {
23+
pointer: NonNull<T>,
24+
_marker: PhantomData<T>,
25+
}
26+
27+
/// `Unique` pointers are `Send` if `T` is `Send` because the data they
28+
/// reference is unaliased. Note that this aliasing invariant is
29+
/// unenforced by the type system; the abstraction using the
30+
/// `Unique` must enforce it.
31+
unsafe impl<T: Send + ?Sized> Send for Unique<T> {}
32+
33+
/// `Unique` pointers are `Sync` if `T` is `Sync` because the data they
34+
/// reference is unaliased. Note that this aliasing invariant is
35+
/// unenforced by the type system; the abstraction using the
36+
/// `Unique` must enforce it.
37+
unsafe impl<T: Sync + ?Sized> Sync for Unique<T> {}
38+
39+
impl<T: ?Sized> Unique<T> {
40+
/// Creates a new `Unique`.
41+
///
42+
/// # Safety
43+
///
44+
/// `ptr` must be non-null.
45+
#[inline]
46+
pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
47+
// SAFETY: the caller must guarantee that `ptr` is non-null.
48+
unsafe {
49+
Unique {
50+
pointer: NonNull::new_unchecked(ptr),
51+
_marker: PhantomData,
52+
}
53+
}
54+
}
55+
56+
/// Acquires the underlying `*mut` pointer.
57+
#[must_use = "`self` will be dropped if the result is not used"]
58+
#[inline]
59+
pub const fn as_ptr(self) -> *mut T {
60+
self.pointer.as_ptr()
61+
}
62+
63+
/// Acquires the underlying `*mut` pointer.
64+
#[must_use = "`self` will be dropped if the result is not used"]
65+
#[inline]
66+
pub const fn as_non_null_ptr(self) -> NonNull<T> {
67+
self.pointer
68+
}
69+
70+
/// Dereferences the content.
71+
///
72+
/// The resulting lifetime is bound to self so this behaves "as if"
73+
/// it were actually an instance of T that is getting borrowed. If a longer
74+
/// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`.
75+
#[must_use]
76+
#[inline]
77+
pub const unsafe fn as_ref(&self) -> &T {
78+
// SAFETY: the caller must guarantee that `self` meets all the
79+
// requirements for a reference.
80+
unsafe { self.pointer.as_ref() }
81+
}
82+
83+
/// Mutably dereferences the content.
84+
///
85+
/// The resulting lifetime is bound to self so this behaves "as if"
86+
/// it were actually an instance of T that is getting borrowed. If a longer
87+
/// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`.
88+
#[must_use]
89+
#[inline]
90+
pub unsafe fn as_mut(&mut self) -> &mut T {
91+
// SAFETY: the caller must guarantee that `self` meets all the
92+
// requirements for a mutable reference.
93+
unsafe { self.pointer.as_mut() }
94+
}
95+
}
96+
97+
impl<T: ?Sized> Clone for Unique<T> {
98+
#[inline]
99+
fn clone(&self) -> Self {
100+
*self
101+
}
102+
}
103+
104+
impl<T: ?Sized> Copy for Unique<T> {}
105+
106+
use core::{marker::PhantomData, ptr::NonNull};

src/stable/vec/into_iter.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,13 +157,6 @@ impl<T, A: Allocator> ExactSizeIterator for IntoIter<T, A> {}
157157

158158
impl<T, A: Allocator> FusedIterator for IntoIter<T, A> {}
159159

160-
#[doc(hidden)]
161-
pub trait NonDrop {}
162-
163-
// T: Copy as approximation for !Drop since get_unchecked does not advance self.ptr
164-
// and thus we can't implement drop-handling
165-
impl<T: Copy> NonDrop for T {}
166-
167160
#[cfg(not(no_global_oom_handling))]
168161
impl<T: Clone, A: Allocator + Clone> Clone for IntoIter<T, A> {
169162
fn clone(&self) -> Self {

src/stable/vec/mod.rs

Lines changed: 4 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ use core::iter;
6363
use core::iter::FromIterator;
6464
use core::marker::PhantomData;
6565
use core::mem::{self, size_of, ManuallyDrop, MaybeUninit};
66-
use core::ops::{self, Bound, Index, IndexMut, Range, RangeBounds};
66+
use core::ops::{self, Bound, Index, IndexMut, RangeBounds};
6767
use core::ptr::{self, NonNull};
6868
use core::slice::{self, SliceIndex};
6969

@@ -900,7 +900,7 @@ impl<T, A: Allocator> Vec<T, A> {
900900
/// # Examples
901901
///
902902
/// ```
903-
/// use std::collections::TryReserveError;
903+
/// use allocator_api2::collections::TryReserveError;
904904
///
905905
/// fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
906906
/// let mut output = Vec::new();
@@ -943,7 +943,7 @@ impl<T, A: Allocator> Vec<T, A> {
943943
/// # Examples
944944
///
945945
/// ```
946-
/// use std::collections::TryReserveError;
946+
/// use allocator_api2::collections::TryReserveError;
947947
///
948948
/// fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
949949
/// let mut output = Vec::new();
@@ -1049,7 +1049,7 @@ impl<T, A: Allocator> Vec<T, A> {
10491049
let me = ManuallyDrop::new(self);
10501050
let buf = ptr::read(&me.buf);
10511051
let len = me.len();
1052-
buf.into_box(len).assume_init()
1052+
Box::<[mem::MaybeUninit<T>], A>::assume_init(buf.into_box(len))
10531053
}
10541054
}
10551055

@@ -2545,62 +2545,6 @@ impl<T: PartialEq, A: Allocator> Vec<T, A> {
25452545
}
25462546
}
25472547

2548-
trait ExtendFromWithinSpec {
2549-
/// # Safety
2550-
///
2551-
/// - `src` needs to be valid index
2552-
/// - `self.capacity() - self.len()` must be `>= src.len()`
2553-
unsafe fn spec_extend_from_within(&mut self, src: Range<usize>);
2554-
}
2555-
2556-
// impl<T: Clone, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
2557-
// default unsafe fn spec_extend_from_within(&mut self, src: Range<usize>) {
2558-
// // SAFETY:
2559-
// // - len is increased only after initializing elements
2560-
// let (this, spare, len) = unsafe { self.split_at_spare_mut_with_len() };
2561-
2562-
// // SAFETY:
2563-
// // - caller guarantees that src is a valid index
2564-
// let to_clone = unsafe { this.get_unchecked(src) };
2565-
2566-
// iter::zip(to_clone, spare)
2567-
// .map(|(src, dst)| dst.write(src.clone()))
2568-
// // Note:
2569-
// // - Element was just initialized with `MaybeUninit::write`, so it's ok to increase len
2570-
// // - len is increased after each element to prevent leaks (see issue #82533)
2571-
// .for_each(|_| *len += 1);
2572-
// }
2573-
// }
2574-
2575-
impl<T: Copy, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
2576-
#[inline(always)]
2577-
unsafe fn spec_extend_from_within(&mut self, src: Range<usize>) {
2578-
let count = src.len();
2579-
{
2580-
let (init, spare) = self.split_at_spare_mut();
2581-
2582-
// SAFETY:
2583-
// - caller guarantees that `src` is a valid index
2584-
let source = unsafe { init.get_unchecked(src) };
2585-
2586-
// SAFETY:
2587-
// - Both pointers are created from unique slice references (`&mut [_]`)
2588-
// so they are valid and do not overlap.
2589-
// - Elements are :Copy so it's OK to copy them, without doing
2590-
// anything with the original values
2591-
// - `count` is equal to the len of `source`, so source is valid for
2592-
// `count` reads
2593-
// - `.reserve(count)` guarantees that `spare.len() >= count` so spare
2594-
// is valid for `count` writes
2595-
unsafe { ptr::copy_nonoverlapping(source.as_ptr(), spare.as_mut_ptr() as _, count) };
2596-
}
2597-
2598-
// SAFETY:
2599-
// - The elements were just initialized by `copy_nonoverlapping`
2600-
self.len += count;
2601-
}
2602-
}
2603-
26042548
////////////////////////////////////////////////////////////////////////////////
26052549
// Common trait implementations for Vec
26062550
////////////////////////////////////////////////////////////////////////////////

tests/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#![cfg_attr(feature = "nightly", feature(allocator_api))]
2-
#![cfg(not(no_global_oom_handling))]
32

43
use std::alloc::Layout;
54

0 commit comments

Comments
 (0)