Skip to content

Commit b3ca625

Browse files
committed
Support 3 allocator schemes
nightly - unstable allocator_api allocator-api2 - stable version of allocator_api neither - custom trait implemented only for default allocator parameter
1 parent a1ed2f9 commit b3ca625

File tree

9 files changed

+97
-39
lines changed

9 files changed

+97
-39
lines changed

Cargo.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,13 @@ doc-comment = "0.3.1"
3939
[features]
4040
default = ["ahash", "inline-more", "allocator-api2"]
4141

42-
nightly = []
42+
nightly-base = [] # non-public feature to use nightly features without depending on `allocator-api2`
43+
44+
nightly = ["allocator-api2/nightly", "nightly-base"]
45+
4346
rustc-internal-api = []
4447
rustc-dep-of-std = [
45-
"nightly",
48+
"nightly-base",
4649
"core",
4750
"compiler_builtins",
4851
"alloc",

ci/tools.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ if retry rustup component add rustfmt ; then
3030
fi
3131

3232
if retry rustup component add clippy ; then
33-
cargo clippy --all --tests --features serde,rayon,bumpalo -- -D clippy::all
33+
cargo clippy --all --tests --features serde,rayon -- -D clippy::all
3434
cargo clippy --all --tests --features raw -- -D clippy::all
3535
fi
3636

src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
1212
#![no_std]
1313
#![cfg_attr(
14-
feature = "nightly",
14+
feature = "nightly-base",
1515
feature(
1616
test,
1717
core_intrinsics,
@@ -37,7 +37,7 @@
3737
)]
3838
#![warn(missing_docs)]
3939
#![warn(rust_2018_idioms)]
40-
#![cfg_attr(feature = "nightly", warn(fuzzy_provenance_casts))]
40+
#![cfg_attr(feature = "nightly-base", warn(fuzzy_provenance_casts))]
4141

4242
#[cfg(test)]
4343
#[macro_use]
@@ -46,7 +46,7 @@ extern crate std;
4646
#[cfg_attr(test, macro_use)]
4747
extern crate alloc;
4848

49-
#[cfg(feature = "nightly")]
49+
#[cfg(feature = "nightly-base")]
5050
#[cfg(doctest)]
5151
doc_comment::doctest!("../README.md");
5252

src/macros.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,13 @@ macro_rules! cfg_if {
5656

5757
// Helper macro for specialization. This also helps avoid parse errors if the
5858
// default fn syntax for specialization changes in the future.
59-
#[cfg(feature = "nightly")]
59+
#[cfg(feature = "nightly-base")]
6060
macro_rules! default_fn {
6161
(#[$($a:tt)*] $($tt:tt)*) => {
6262
#[$($a)*] default $($tt)*
6363
}
6464
}
65-
#[cfg(not(feature = "nightly"))]
65+
#[cfg(not(feature = "nightly-base"))]
6666
macro_rules! default_fn {
6767
($($tt:tt)*) => {
6868
$($tt)*

src/map.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ where
237237
move |x| k.equivalent(x)
238238
}
239239

240-
#[cfg(not(feature = "nightly"))]
240+
#[cfg(not(feature = "nightly-base"))]
241241
#[cfg_attr(feature = "inline-more", inline)]
242242
pub(crate) fn make_hash<Q, S>(hash_builder: &S, val: &Q) -> u64
243243
where
@@ -250,7 +250,7 @@ where
250250
state.finish()
251251
}
252252

253-
#[cfg(feature = "nightly")]
253+
#[cfg(feature = "nightly-base")]
254254
#[cfg_attr(feature = "inline-more", inline)]
255255
pub(crate) fn make_hash<Q, S>(hash_builder: &S, val: &Q) -> u64
256256
where
@@ -260,7 +260,7 @@ where
260260
hash_builder.hash_one(val)
261261
}
262262

263-
#[cfg(not(feature = "nightly"))]
263+
#[cfg(not(feature = "nightly-base"))]
264264
#[cfg_attr(feature = "inline-more", inline)]
265265
pub(crate) fn make_insert_hash<K, S>(hash_builder: &S, val: &K) -> u64
266266
where
@@ -273,7 +273,7 @@ where
273273
state.finish()
274274
}
275275

276-
#[cfg(feature = "nightly")]
276+
#[cfg(feature = "nightly-base")]
277277
#[cfg_attr(feature = "inline-more", inline)]
278278
pub(crate) fn make_insert_hash<K, S>(hash_builder: &S, val: &K) -> u64
279279
where
@@ -6498,13 +6498,13 @@ where
64986498
}
64996499

65006500
#[inline]
6501-
#[cfg(feature = "nightly")]
6501+
#[cfg(feature = "nightly-base")]
65026502
fn extend_one(&mut self, (k, v): (K, V)) {
65036503
self.insert(k, v);
65046504
}
65056505

65066506
#[inline]
6507-
#[cfg(feature = "nightly")]
6507+
#[cfg(feature = "nightly-base")]
65086508
fn extend_reserve(&mut self, additional: usize) {
65096509
// Keys may be already present or show multiple times in the iterator.
65106510
// Reserve the entire hint lower bound if the map is empty.
@@ -6572,13 +6572,13 @@ where
65726572
}
65736573

65746574
#[inline]
6575-
#[cfg(feature = "nightly")]
6575+
#[cfg(feature = "nightly-base")]
65766576
fn extend_one(&mut self, (k, v): (&'a K, &'a V)) {
65776577
self.insert(*k, *v);
65786578
}
65796579

65806580
#[inline]
6581-
#[cfg(feature = "nightly")]
6581+
#[cfg(feature = "nightly-base")]
65826582
fn extend_reserve(&mut self, additional: usize) {
65836583
Extend::<(K, V)>::extend_reserve(self, additional);
65846584
}
@@ -6632,13 +6632,13 @@ where
66326632
}
66336633

66346634
#[inline]
6635-
#[cfg(feature = "nightly")]
6635+
#[cfg(feature = "nightly-base")]
66366636
fn extend_one(&mut self, &(k, v): &'a (K, V)) {
66376637
self.insert(k, v);
66386638
}
66396639

66406640
#[inline]
6641-
#[cfg(feature = "nightly")]
6641+
#[cfg(feature = "nightly-base")]
66426642
fn extend_reserve(&mut self, additional: usize) {
66436643
Extend::<(K, V)>::extend_reserve(self, additional);
66446644
}

src/raw/alloc.rs

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
pub(crate) use self::inner::{do_alloc, Allocator, Global};
22

3-
#[cfg(feature = "nightly")]
3+
// Nightly-case.
4+
// Use unstable `allocator_api` feature.
5+
// This is compatible with `allocator-api2` which can be enabled or not.
6+
// This is used when building for `std`.
7+
#[cfg(feature = "nightly-base")]
48
mod inner {
59
use crate::alloc::alloc::Layout;
610
pub use crate::alloc::alloc::{Allocator, Global};
@@ -15,7 +19,13 @@ mod inner {
1519
}
1620
}
1721

18-
#[cfg(not(feature = "nightly"))]
22+
// Basic non-nightly case.
23+
// This uses `allocator-api2` enabled by default.
24+
// If any crate enables "nightly" in `allocator-api2`,
25+
// this will be equivalent to the nightly case,
26+
// since `allocator_api2::alloc::Allocator` would be re-export of
27+
// `core::alloc::Allocator`.
28+
#[cfg(all(not(feature = "nightly-base"), feature = "allocator-api2"))]
1929
mod inner {
2030
use crate::alloc::alloc::Layout;
2131
pub use allocator_api2::alloc::{Allocator, Global};
@@ -29,3 +39,48 @@ mod inner {
2939
}
3040
}
3141
}
42+
43+
// No-defaults case.
44+
// When building with default-features turned off and
45+
// neither `nightly` nor `allocator-api2` is enabled,
46+
// this will be used.
47+
// Making it impossible to use any custom allocator with collections defined
48+
// in this crate.
49+
// Any crate in build-tree can enable `allocator-api2`,
50+
// or `nightly` without disturbing users that don't want to use it.
51+
#[cfg(not(any(feature = "nightly-base", feature = "allocator-api2")))]
52+
mod inner {
53+
use crate::alloc::alloc::{alloc, dealloc, Layout};
54+
use core::ptr::NonNull;
55+
56+
#[allow(clippy::missing_safety_doc)] // not exposed outside of this crate
57+
pub unsafe trait Allocator {
58+
fn allocate(&self, layout: Layout) -> Result<NonNull<u8>, ()>;
59+
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout);
60+
}
61+
62+
#[derive(Copy, Clone)]
63+
pub struct Global;
64+
65+
unsafe impl Allocator for Global {
66+
#[inline]
67+
fn allocate(&self, layout: Layout) -> Result<NonNull<u8>, ()> {
68+
unsafe { NonNull::new(alloc(layout)).ok_or(()) }
69+
}
70+
#[inline]
71+
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
72+
dealloc(ptr.as_ptr(), layout);
73+
}
74+
}
75+
76+
impl Default for Global {
77+
#[inline]
78+
fn default() -> Self {
79+
Global
80+
}
81+
}
82+
83+
pub(crate) fn do_alloc<A: Allocator>(alloc: &A, layout: Layout) -> Result<NonNull<u8>, ()> {
84+
alloc.allocate(layout)
85+
}
86+
}

src/raw/bitmask.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::imp::{BitMaskWord, BITMASK_MASK, BITMASK_STRIDE};
2-
#[cfg(feature = "nightly")]
2+
#[cfg(feature = "nightly-base")]
33
use core::intrinsics;
44

55
/// A bit mask which contains the result of a `Match` operation on a `Group` and
@@ -64,12 +64,12 @@ impl BitMask {
6464
/// Returns the first set bit in the `BitMask`, if there is one. The
6565
/// bitmask must not be empty.
6666
#[inline]
67-
#[cfg(feature = "nightly")]
67+
#[cfg(feature = "nightly-base")]
6868
pub(crate) unsafe fn lowest_set_bit_nonzero(self) -> usize {
6969
intrinsics::cttz_nonzero(self.0) as usize / BITMASK_STRIDE
7070
}
7171
#[inline]
72-
#[cfg(not(feature = "nightly"))]
72+
#[cfg(not(feature = "nightly-base"))]
7373
pub(crate) unsafe fn lowest_set_bit_nonzero(self) -> usize {
7474
self.trailing_zeros()
7575
}

src/raw/mod.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,25 +42,25 @@ use self::imp::Group;
4242

4343
// Branch prediction hint. This is currently only available on nightly but it
4444
// consistently improves performance by 10-15%.
45-
#[cfg(feature = "nightly")]
45+
#[cfg(feature = "nightly-base")]
4646
use core::intrinsics::{likely, unlikely};
4747

4848
// On stable we can use #[cold] to get a equivalent effect: this attributes
4949
// suggests that the function is unlikely to be called
50-
#[cfg(not(feature = "nightly"))]
50+
#[cfg(not(feature = "nightly-base"))]
5151
#[inline]
5252
#[cold]
5353
fn cold() {}
5454

55-
#[cfg(not(feature = "nightly"))]
55+
#[cfg(not(feature = "nightly-base"))]
5656
#[inline]
5757
fn likely(b: bool) -> bool {
5858
if !b {
5959
cold();
6060
}
6161
b
6262
}
63-
#[cfg(not(feature = "nightly"))]
63+
#[cfg(not(feature = "nightly-base"))]
6464
#[inline]
6565
fn unlikely(b: bool) -> bool {
6666
if b {
@@ -70,10 +70,10 @@ fn unlikely(b: bool) -> bool {
7070
}
7171

7272
// Use strict provenance functions if available.
73-
#[cfg(feature = "nightly")]
73+
#[cfg(feature = "nightly-base")]
7474
use core::ptr::invalid_mut;
7575
// Implement it with a cast otherwise.
76-
#[cfg(not(feature = "nightly"))]
76+
#[cfg(not(feature = "nightly-base"))]
7777
#[inline(always)]
7878
fn invalid_mut<T>(addr: usize) -> *mut T {
7979
addr as *mut T
@@ -936,7 +936,7 @@ impl<T, A: Allocator + Clone> RawTable<T, A> {
936936

937937
/// Returns pointer to start of data table.
938938
#[inline]
939-
#[cfg(any(feature = "raw", feature = "nightly"))]
939+
#[cfg(any(feature = "raw", feature = "nightly-base"))]
940940
pub unsafe fn data_start(&self) -> NonNull<T> {
941941
NonNull::new_unchecked(self.data_end().as_ptr().wrapping_sub(self.buckets()))
942942
}
@@ -2562,7 +2562,7 @@ impl<T: Clone, A: Allocator + Clone> RawTableClone for RawTable<T, A> {
25622562
}
25632563
}
25642564
}
2565-
#[cfg(feature = "nightly")]
2565+
#[cfg(feature = "nightly-base")]
25662566
impl<T: Copy, A: Allocator + Clone> RawTableClone for RawTable<T, A> {
25672567
#[cfg_attr(feature = "inline-more", inline)]
25682568
unsafe fn clone_from_spec(&mut self, source: &Self) {
@@ -2674,7 +2674,7 @@ impl<T, A: Allocator + Clone + Default> Default for RawTable<T, A> {
26742674
}
26752675
}
26762676

2677-
#[cfg(feature = "nightly")]
2677+
#[cfg(feature = "nightly-base")]
26782678
unsafe impl<#[may_dangle] T, A: Allocator + Clone> Drop for RawTable<T, A> {
26792679
#[cfg_attr(feature = "inline-more", inline)]
26802680
fn drop(&mut self) {
@@ -2686,7 +2686,7 @@ unsafe impl<#[may_dangle] T, A: Allocator + Clone> Drop for RawTable<T, A> {
26862686
}
26872687
}
26882688
}
2689-
#[cfg(not(feature = "nightly"))]
2689+
#[cfg(not(feature = "nightly-base"))]
26902690
impl<T, A: Allocator + Clone> Drop for RawTable<T, A> {
26912691
#[cfg_attr(feature = "inline-more", inline)]
26922692
fn drop(&mut self) {
@@ -3081,7 +3081,7 @@ where
30813081
{
30823082
}
30833083

3084-
#[cfg(feature = "nightly")]
3084+
#[cfg(feature = "nightly-base")]
30853085
unsafe impl<#[may_dangle] T, A: Allocator + Clone> Drop for RawIntoIter<T, A> {
30863086
#[cfg_attr(feature = "inline-more", inline)]
30873087
fn drop(&mut self) {
@@ -3096,7 +3096,7 @@ unsafe impl<#[may_dangle] T, A: Allocator + Clone> Drop for RawIntoIter<T, A> {
30963096
}
30973097
}
30983098
}
3099-
#[cfg(not(feature = "nightly"))]
3099+
#[cfg(not(feature = "nightly-base"))]
31003100
impl<T, A: Allocator + Clone> Drop for RawIntoIter<T, A> {
31013101
#[cfg_attr(feature = "inline-more", inline)]
31023102
fn drop(&mut self) {

src/set.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,13 +1354,13 @@ where
13541354
}
13551355

13561356
#[inline]
1357-
#[cfg(feature = "nightly")]
1357+
#[cfg(feature = "nightly-base")]
13581358
fn extend_one(&mut self, k: T) {
13591359
self.map.insert(k, ());
13601360
}
13611361

13621362
#[inline]
1363-
#[cfg(feature = "nightly")]
1363+
#[cfg(feature = "nightly-base")]
13641364
fn extend_reserve(&mut self, additional: usize) {
13651365
Extend::<(T, ())>::extend_reserve(&mut self.map, additional);
13661366
}
@@ -1378,13 +1378,13 @@ where
13781378
}
13791379

13801380
#[inline]
1381-
#[cfg(feature = "nightly")]
1381+
#[cfg(feature = "nightly-base")]
13821382
fn extend_one(&mut self, k: &'a T) {
13831383
self.map.insert(*k, ());
13841384
}
13851385

13861386
#[inline]
1387-
#[cfg(feature = "nightly")]
1387+
#[cfg(feature = "nightly-base")]
13881388
fn extend_reserve(&mut self, additional: usize) {
13891389
Extend::<(T, ())>::extend_reserve(&mut self.map, additional);
13901390
}

0 commit comments

Comments
 (0)