Skip to content

Commit

Permalink
lib: make "std" independent of allocator_api
Browse files Browse the repository at this point in the history
When compiling without allocator_api, assume that allocations cannot fail.
This way, nightly Rust features are not absolutely needed for pinned_init,
and it can be used with stable Rust; right now the minimum supported Rust
version is 1.82.0, where the new_uninit version was stabilized.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
bonzini authored and y86-dev committed Nov 29, 2024
1 parent d286b7e commit 1a823d1
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 20 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ paste = "1.0"
pinned-init-macro = { path = "./pinned-init-macro", version = "=0.0.5" }

[features]
default = ["std"]
std = ["alloc"]
default = ["std", "alloc"]
std = []
alloc = []

[dev-dependencies]
Expand Down
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,17 @@ it into it's final memory location.

This library allows you to do in-place initialization safely.

### Nightly Needed for `alloc` and `std` features
### Nightly Needed for `alloc` feature

This library requires the `allocator_api` unstable feature when the `alloc` or `std` features
are enabled and thus can only be used with a nightly compiler.
This library requires the `allocator_api` unstable feature when the `alloc` feature
is enabled and thus this feature can only be used with a nightly compiler.
When enabling the `alloc` feature, the user will be required to activate
`allocator_api` as well.

When enabling the `alloc` or `std` feature, the user will be required to activate `allocator_api`
as well.
The feature is enabled by default, thus by default `pinned-init` will require a
nightly compiler. However, using the crate on stable compilers is possible by
disabling `alloc`. In practice this will require the `std` feature, because
stable compilers have neither `Box` nor `Arc` in no-std mode.

## Overview

Expand Down
43 changes: 30 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@
//!
//! This library allows you to do in-place initialization safely.
//!
//! ## Nightly Needed for `alloc` and `std` features
//! ## Nightly Needed for `alloc` feature
//!
//! This library requires the `allocator_api` unstable feature when the `alloc` or `std` features
//! are enabled and thus can only be used with a nightly compiler.
//! This library requires the `allocator_api` unstable feature when the `alloc` feature
//! is enabled and thus this feature can only be used with a nightly compiler.
//! When enabling the `alloc` feature, the user will be required to activate
//! `allocator_api` as well.
//!
//! When enabling the `alloc` or `std` feature, the user will be required to activate `allocator_api`
//! as well.
//! The feature is enabled by default, thus by default `pinned-init` will require a
//! nightly compiler. However, using the crate on stable compilers is possible by
//! disabling `alloc`. In practice this will require the `std` feature, because
//! stable compilers have neither `Box` nor `Arc` in no-std mode.
//!
//! # Overview
//!
Expand Down Expand Up @@ -239,9 +243,9 @@
extern crate alloc;

#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::boxed::Box;
#[cfg(feature = "alloc")]
use alloc::sync::Arc;
use alloc::{boxed::Box, sync::Arc};
#[cfg(feature = "std")]
use std::sync::Arc;

use core::{
cell::UnsafeCell,
Expand Down Expand Up @@ -1201,32 +1205,45 @@ pub trait InPlaceInit<T>: Sized {
}

#[cfg(feature = "alloc")]
macro_rules! try_new_uninit {
($type:ident) => {
$type::try_new_uninit()?
};
}
#[cfg(all(feature = "std", not(feature = "alloc")))]
macro_rules! try_new_uninit {
($type:ident) => {
$type::new_uninit()
};
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl<T> InPlaceInit<T> for Box<T> {
#[inline]
fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E>
where
E: From<AllocError>,
{
Box::try_new_uninit()?.write_pin_init(init)
try_new_uninit!(Box).write_pin_init(init)
}

#[inline]
fn try_init<E>(init: impl Init<T, E>) -> Result<Self, E>
where
E: From<AllocError>,
{
Box::try_new_uninit()?.write_init(init)
try_new_uninit!(Box).write_init(init)
}
}

#[cfg(feature = "alloc")]
#[cfg(any(feature = "std", feature = "alloc"))]
impl<T> InPlaceInit<T> for Arc<T> {
#[inline]
fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E>
where
E: From<AllocError>,
{
let mut this = Arc::try_new_uninit()?;
let mut this = try_new_uninit!(Arc);
let Some(slot) = Arc::get_mut(&mut this) else {
// SAFETY: the Arc has just been created and has no external referecnes
unsafe { core::hint::unreachable_unchecked() }
Expand All @@ -1244,7 +1261,7 @@ impl<T> InPlaceInit<T> for Arc<T> {
where
E: From<AllocError>,
{
let mut this = Arc::try_new_uninit()?;
let mut this = try_new_uninit!(Arc);
let Some(slot) = Arc::get_mut(&mut this) else {
// SAFETY: the Arc has just been created and has no external referecnes
unsafe { core::hint::unreachable_unchecked() }
Expand Down

0 comments on commit 1a823d1

Please sign in to comment.