From d595e8a92bf3edec5d4833ebff8523e9395f5d8a Mon Sep 17 00:00:00 2001 From: "A. Molzer" <5550310+197g@users.noreply.github.com> Date: Tue, 10 Nov 2026 21:16:51 +0100 Subject: [PATCH 1/6] Change allocator_api2 to ::alloc, MSRV 1.100 :tada: As a related consequence of this change, we want to get rid of the proprietary alloc-traits crate in the dependency tree. That means or now preparing the API such that it is no longer a public dependency in all configurations and need only disable the trait impls. --- exit-stack/Cargo.toml | 2 +- static-alloc/Cargo.toml | 8 +++----- static-alloc/Changes.md | 9 +++++++++ static-alloc/src/allocator_api2.rs | 2 +- static-alloc/src/bump.rs | 4 ++-- static-alloc/src/lib.rs | 8 +++++++- static-alloc/src/unsync/bump.rs | 9 +++++---- static-alloc/tests/allocator-api2.rs | 2 +- 8 files changed, 29 insertions(+), 15 deletions(-) diff --git a/exit-stack/Cargo.toml b/exit-stack/Cargo.toml index 760ec8a..b88887a 100644 --- a/exit-stack/Cargo.toml +++ b/exit-stack/Cargo.toml @@ -11,7 +11,7 @@ readme = "Readme.md" categories = ["embedded", "memory-management", "no-std"] [dependencies] -static-alloc = { path = "../static-alloc", version = "0.3.0-prerelease" } +static-alloc = { path = "../static-alloc", version = "0.4.0" } [dev-dependencies] pin-utils = "0.1" diff --git a/static-alloc/Cargo.toml b/static-alloc/Cargo.toml index 74b7d3d..0961367 100644 --- a/static-alloc/Cargo.toml +++ b/static-alloc/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "static-alloc" -version = "0.3.3" +version = "0.4.0" description = "A bump allocator on static memory for the alloc-traits crate" edition = "2024" documentation = "https://docs.rs/static-alloc" categories = ["embedded", "memory-management", "no-std"] -rust-version = "1.85" +rust-version = "1.100" authors.workspace = true license.workspace = true @@ -16,12 +16,10 @@ repository.workspace = true all-features = true [dependencies] -alloc-traits = { path = "../alloc-traits", version = "0.1.0" } +alloc-traits = { path = "../alloc-traits", version = "0.1.0", optional = true } portable-atomic = { version = "1", optional = true, default-features = false } -allocator-api2 = { version = "0.4", optional = true, default-features = false } [dev-dependencies] -allocator-api2 = { version = "0.4", features = ["std"] } [features] alloc = [] diff --git a/static-alloc/Changes.md b/static-alloc/Changes.md index 759f567..2281530 100644 --- a/static-alloc/Changes.md +++ b/static-alloc/Changes.md @@ -1,3 +1,12 @@ +# v0.4.0 + +Structural: +- The `allocator_api2` feature is removed as its functionality is now part of `alloc`. +- The `alloc-traits` dependency is now marked as optional, but still required + for successful compilation. The crate is partly superseded by Rust 1.100 and + its functionality will be brought into this crate in a way that is not + exposed in the public API. + # v0.3.3 Expect this to be the last version before requiring rust-version 1.100 (the diff --git a/static-alloc/src/allocator_api2.rs b/static-alloc/src/allocator_api2.rs index 23f2eec..3ca83a3 100644 --- a/static-alloc/src/allocator_api2.rs +++ b/static-alloc/src/allocator_api2.rs @@ -3,7 +3,7 @@ use crate::{ unsync, }; -use allocator_api2::alloc::{AllocError, Allocator, Layout}; +use alloc::alloc::{AllocError, Allocator, Layout}; use core::{cell, ptr::NonNull}; unsafe impl Allocator for Bump { diff --git a/static-alloc/src/bump.rs b/static-alloc/src/bump.rs index 951fa1f..94b9964 100644 --- a/static-alloc/src/bump.rs +++ b/static-alloc/src/bump.rs @@ -15,8 +15,8 @@ use core::sync::atomic::{AtomicUsize, Ordering}; #[cfg(feature = "polyfill")] use portable_atomic::{AtomicUsize, Ordering}; -use crate::leaked::LeakBox; -use alloc_traits::{AllocTime, LocalAlloc, NonZeroLayout}; +use crate::{AllocTime, leaked::LeakBox}; +use alloc_traits::{LocalAlloc, NonZeroLayout}; /// Allocator drawing from an inner, statically sized memory resource. /// diff --git a/static-alloc/src/lib.rs b/static-alloc/src/lib.rs index 469fb63..afb3efd 100644 --- a/static-alloc/src/lib.rs +++ b/static-alloc/src/lib.rs @@ -44,11 +44,14 @@ #![no_std] #![deny(missing_docs)] +#[cfg(not(feature = "alloc-traits"))] +compile_error!("The `alloc-traits` feature is required for this crate to work"); + #[cfg(feature = "alloc")] extern crate alloc; /// Specialized types for `allocator-api2` (the planned std allocator). -#[cfg(feature = "allocator-api2")] +#[cfg(feature = "alloc")] pub mod allocator_api2; pub mod bump; @@ -74,6 +77,9 @@ macro_rules! insert_as_doc { } } +#[derive(Clone, Copy, Default)] +pub struct AllocTime<'lt>(alloc_traits::AllocTime<'lt>); + /// A module containing extended documentation and examples. #[cfg(doc)] pub mod doc { diff --git a/static-alloc/src/unsync/bump.rs b/static-alloc/src/unsync/bump.rs index ee3765d..e3fc903 100644 --- a/static-alloc/src/unsync/bump.rs +++ b/static-alloc/src/unsync/bump.rs @@ -6,10 +6,11 @@ use core::{ ptr::{self, NonNull}, }; -use alloc_traits::AllocTime; - -use crate::bump::{Allocation, Failure, Level}; -use crate::leaked::LeakBox; +use crate::{ + AllocTime, + bump::{Allocation, Failure, Level}, + leaked::LeakBox, +}; /// A bump allocator whose storage capacity and alignment is given by `T`. /// diff --git a/static-alloc/tests/allocator-api2.rs b/static-alloc/tests/allocator-api2.rs index 6802bb7..38f297f 100644 --- a/static-alloc/tests/allocator-api2.rs +++ b/static-alloc/tests/allocator-api2.rs @@ -1,4 +1,4 @@ -use allocator_api2 as astd; +use alloc as astd; use static_alloc::{Bump, unsync}; #[test] From d62a38f606e52ac9471eeddf9805cf3bedfe4425 Mon Sep 17 00:00:00 2001 From: "A. Molzer" <5550310+197g@users.noreply.github.com> Date: Wed, 11 Nov 2026 11:16:01 +0100 Subject: [PATCH 2/6] Update tests for compat with `alloc` --- static-alloc/Cargo.toml | 2 +- static-alloc/src/allocator_api2.rs | 3 --- static-alloc/src/bump.rs | 13 +++++++++---- static-alloc/src/leaked.rs | 6 +++--- static-alloc/src/lib.rs | 12 +++++++++++- static-alloc/tests/allocator-api2.rs | 4 ++-- 6 files changed, 26 insertions(+), 14 deletions(-) diff --git a/static-alloc/Cargo.toml b/static-alloc/Cargo.toml index 0961367..79c14de 100644 --- a/static-alloc/Cargo.toml +++ b/static-alloc/Cargo.toml @@ -58,4 +58,4 @@ required-features = ["nightly_chain"] [[test]] name = "allocator-api2" path = "tests/allocator-api2.rs" -required-features = ["allocator-api2"] +required-features = ["alloc"] diff --git a/static-alloc/src/allocator_api2.rs b/static-alloc/src/allocator_api2.rs index 3ca83a3..e311b1e 100644 --- a/static-alloc/src/allocator_api2.rs +++ b/static-alloc/src/allocator_api2.rs @@ -213,7 +213,6 @@ impl WithAllocationInfo { /// ``` /// use static_alloc::allocator_api2::WithAllocationInfo; /// use static_alloc::bump::Bump; - /// use allocator_api2::vec::Vec; /// /// let arena = Bump::<[usize; 4]>::uninit(); /// let hdl = WithAllocationInfo::new(&arena); @@ -236,7 +235,6 @@ impl WithAllocationInfo { /// ``` /// use static_alloc::allocator_api2::WithAllocationInfo; /// use static_alloc::bump::Bump; - /// use allocator_api2::vec::Vec; /// /// let arena = Bump::<[usize; 4]>::uninit(); /// let hdl = WithAllocationInfo::new(&arena); @@ -261,7 +259,6 @@ impl WithAllocationInfo { /// ``` /// use static_alloc::allocator_api2::WithAllocationInfo; /// use static_alloc::bump::Bump; - /// use allocator_api2::vec::Vec; /// /// let arena = Bump::<[usize; 4]>::uninit(); /// let hdl = WithAllocationInfo::new(&arena); diff --git a/static-alloc/src/bump.rs b/static-alloc/src/bump.rs index 94b9964..b22b8bd 100644 --- a/static-alloc/src/bump.rs +++ b/static-alloc/src/bump.rs @@ -763,7 +763,12 @@ impl Bump { /// Move a value into an owned allocation. /// - /// For safely initializing a value _after_ a successful allocation, see [`LeakBox::write`]. + /// For safely initializing a value _after_ a successful allocation, allocate `MaybeUninit` + /// instead and see [`LeakBox::write`]. This method only works with sized values as unsized type + /// can not be encapsulated into `MaybeUninit`. Instead, allocate an appropriately sized region + /// with [`Self::get_layout`], cast the pointer to imbue it with the correct metadata and + /// manually initialize the allocation. Then call [`LeakBox::from_raw`] once its safety + /// requirements are fulfilled. /// /// [`LeakBox::write`]: ../leaked/struct.LeakBox.html#method.write /// @@ -1882,7 +1887,7 @@ unsafe impl GlobalAlloc for BumpView<'_> { // Safety: `ptr` is currently allocated via this allocator, i.e. non-null. ptr: unsafe { NonNull::new_unchecked(ptr) }, layout: current, - lifetime: AllocTime::default(), + lifetime: alloc_traits::AllocTime::default(), }; // Safety: satisfies our own invariants. @@ -1912,7 +1917,7 @@ unsafe impl<'alloc, T> LocalAlloc<'alloc> for Bump { Some(alloc_traits::Allocation { ptr: raw_alloc.ptr, layout, - lifetime: AllocTime::default(), + lifetime: alloc_traits::AllocTime::default(), }) } @@ -1965,7 +1970,7 @@ unsafe impl<'alloc> LocalAlloc<'alloc> for BumpView<'alloc> { Some(alloc_traits::Allocation { ptr: raw_alloc.ptr, layout, - lifetime: AllocTime::default(), + lifetime: alloc_traits::AllocTime::default(), }) } diff --git a/static-alloc/src/leaked.rs b/static-alloc/src/leaked.rs index ee29172..2ef9994 100644 --- a/static-alloc/src/leaked.rs +++ b/static-alloc/src/leaked.rs @@ -2,7 +2,7 @@ //! //! FIXME(breaking): Naming. `leaking` implies the `Drop` of the value as well but we do the //! precise opposite. -use alloc_traits::AllocTime; +use crate::AllocTime; use core::pin::Pin; use core::{ @@ -107,13 +107,13 @@ impl Alloca { /// This is an owning pointer comparable to `Box`. It drops the contained value when it is dropped /// itself. The difference is that no deallocation logic is ever executed. /// -/// FIXME(non-breaking): the name is rather confusing. Maybe it should be `BumpBox` or `RefBox`? +/// FIXME(non-breaking): the name can be rather confusing. Maybe it should be `BumpBox` or `RefBox`? /// Not `StackBox` because the value's location in memory is not the defining feature. /// /// # Usage /// /// This box can be used to manage one valid instance constructed within the memory provided by a -/// `MaybeUninit` instance. +/// `MaybeUninit` instance. This only works with values of sized types. /// /// ``` /// use core::mem::MaybeUninit; diff --git a/static-alloc/src/lib.rs b/static-alloc/src/lib.rs index afb3efd..5d0f229 100644 --- a/static-alloc/src/lib.rs +++ b/static-alloc/src/lib.rs @@ -77,7 +77,17 @@ macro_rules! insert_as_doc { } } -#[derive(Clone, Copy, Default)] +/// Denotes the borrow of an allocator, the maximum validity of an [`Allocation`](`bump::Allocation`). +/// +/// This is a zero-sized type with no runtime semantics. It exists so that the borrow relationship +/// can be denoted in the type system (where we otherwise have raw pointers with no lifetime) and +/// you can consequently enforce it to be verified by the borrow checker. When your use of the +/// allocation does not maintain a borrow from the allocator in the same scope, you need to maintain +/// the correctness yourself. You can use [`AllocTime::default()`] to recreate that assertion to +/// APIs that require it. +/// +/// See also [`Allocation`](`bump::Allocation`) and [`LeakBox`](`leaked::LeakBox`). +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)] pub struct AllocTime<'lt>(alloc_traits::AllocTime<'lt>); /// A module containing extended documentation and examples. diff --git a/static-alloc/tests/allocator-api2.rs b/static-alloc/tests/allocator-api2.rs index 38f297f..8419a75 100644 --- a/static-alloc/tests/allocator-api2.rs +++ b/static-alloc/tests/allocator-api2.rs @@ -15,7 +15,7 @@ fn local_vector() { "Reserved more space than available" ); - let _ = v.push_within_capacity(0); + let _ = v.as_mut_slice(); assert!(v.capacity() <= 128); } @@ -33,6 +33,6 @@ fn unsync_vector() { "Reserved more space than available" ); - let _ = v.push_within_capacity(0); + let _ = v.as_mut_slice(); assert!(v.capacity() <= 128); } From d76aa0b72481a5d9edecfe3e5792253197ec2af0 Mon Sep 17 00:00:00 2001 From: "A. Molzer" <5550310+197g@users.noreply.github.com> Date: Wed, 11 Nov 2026 11:16:30 +0100 Subject: [PATCH 3/6] Add conversions for Box<->LeakBox This fits very neatly into a Box with Allocator generic since we can control where the handle matter (or rather; does not matter anymore). --- static-alloc/src/leaked.rs | 34 +++++++++++++++++++++++++++- static-alloc/tests/allocator-api2.rs | 15 +++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/static-alloc/src/leaked.rs b/static-alloc/src/leaked.rs index 2ef9994..e8e7c05 100644 --- a/static-alloc/src/leaked.rs +++ b/static-alloc/src/leaked.rs @@ -105,7 +105,9 @@ impl Alloca { /// Represents an allocation within a Bump. /// /// This is an owning pointer comparable to `Box`. It drops the contained value when it is dropped -/// itself. The difference is that no deallocation logic is ever executed. +/// itself. The difference is that no deallocation logic is ever executed. This is very similar to +/// `alloc::boxed::Box` but the allocator type can be completely erased. It can +/// be converted from such boxes when the `alloc` feature is enabled. /// /// FIXME(non-breaking): the name can be rather confusing. Maybe it should be `BumpBox` or `RefBox`? /// Not `StackBox` because the value's location in memory is not the defining feature. @@ -545,6 +547,36 @@ impl<'ctx, T> From<&'ctx mut [MaybeUninit]> for LeakBox<'ctx, [MaybeUninit } } +#[cfg(feature = "alloc")] +impl<'ctx, T: ?Sized> From> for LeakBox<'ctx, T> { + fn from(boxed: alloc::boxed::Box) -> Self { + // SAFETY: + // * The Box type guarantees this is initialized and not aliased. + let (ptr, _allocator) = alloc::boxed::Box::into_raw_with_allocator(boxed); + unsafe { LeakBox::from_raw(ptr) } + } +} + +#[cfg(feature = "alloc")] +impl<'ctx, T: ?Sized, U> From>> for LeakBox<'ctx, T> { + fn from(boxed: alloc::boxed::Box>) -> Self { + // SAFETY: + // * The Box type guarantees this is initialized and not aliased. + let (ptr, _allocator) = alloc::boxed::Box::into_raw_with_allocator(boxed); + unsafe { LeakBox::from_raw(ptr) } + } +} + +#[cfg(feature = "alloc")] +impl<'ctx, T: ?Sized> From> for LeakBox<'ctx, T> { + fn from(boxed: alloc::boxed::Box) -> Self { + // SAFETY: + // * The Box type guarantees this is initialized and not aliased. + let (ptr, _allocator) = alloc::boxed::Box::into_raw_with_allocator(boxed); + unsafe { LeakBox::from_raw(ptr) } + } +} + impl AsRef for LeakBox<'_, T> { fn as_ref(&self) -> &T { self diff --git a/static-alloc/tests/allocator-api2.rs b/static-alloc/tests/allocator-api2.rs index 8419a75..f0f5ce6 100644 --- a/static-alloc/tests/allocator-api2.rs +++ b/static-alloc/tests/allocator-api2.rs @@ -1,5 +1,6 @@ +extern crate alloc; use alloc as astd; -use static_alloc::{Bump, unsync}; +use static_alloc::{Bump, leaked::LeakBox, unsync}; #[test] fn local_vector() { @@ -36,3 +37,15 @@ fn unsync_vector() { let _ = v.as_mut_slice(); assert!(v.capacity() <= 128); } + +#[test] +fn unsized_leak_box() { + let storage = Bump::<[u8; 128]>::uninit(); + let boxed = astd::boxed::Box::new_in("look, a &str", &storage); + // `std`'s box is `Unsize` so we can coerce it to a `Box` while retaining the + // allocator. Then that box can be readily converted into our own `LeakBox` to erase the + // allocator handle and type. This leaves us with a pure dyn-trait object pointer and its + // lifetime. + let _decay: LeakBox<'_, dyn core::fmt::Display> = + LeakBox::from(boxed as astd::boxed::Box); +} From f16735abf04cbbee82fa1f102dd620114dc89658 Mon Sep 17 00:00:00 2001 From: "A. Molzer" <5550310+197g@users.noreply.github.com> Date: Wed, 11 Nov 2026 17:31:28 +0100 Subject: [PATCH 4/6] Add LeakBox::from(Vec) for bump allocators --- static-alloc/src/leaked.rs | 74 ++++++++++++++++++++++++++-- static-alloc/tests/allocator-api2.rs | 37 ++++++++++++++ 2 files changed, 108 insertions(+), 3 deletions(-) diff --git a/static-alloc/src/leaked.rs b/static-alloc/src/leaked.rs index e8e7c05..ea1b6ae 100644 --- a/static-alloc/src/leaked.rs +++ b/static-alloc/src/leaked.rs @@ -548,7 +548,9 @@ impl<'ctx, T> From<&'ctx mut [MaybeUninit]> for LeakBox<'ctx, [MaybeUninit } #[cfg(feature = "alloc")] -impl<'ctx, T: ?Sized> From> for LeakBox<'ctx, T> { +impl<'ctx, T: ?Sized> From> + for LeakBox<'ctx, T> +{ fn from(boxed: alloc::boxed::Box) -> Self { // SAFETY: // * The Box type guarantees this is initialized and not aliased. @@ -558,7 +560,9 @@ impl<'ctx, T: ?Sized> From> f } #[cfg(feature = "alloc")] -impl<'ctx, T: ?Sized, U> From>> for LeakBox<'ctx, T> { +impl<'ctx, T: ?Sized, U> From>> + for LeakBox<'ctx, T> +{ fn from(boxed: alloc::boxed::Box>) -> Self { // SAFETY: // * The Box type guarantees this is initialized and not aliased. @@ -568,7 +572,9 @@ impl<'ctx, T: ?Sized, U> From>> } #[cfg(feature = "alloc")] -impl<'ctx, T: ?Sized> From> for LeakBox<'ctx, T> { +impl<'ctx, T: ?Sized> From> + for LeakBox<'ctx, T> +{ fn from(boxed: alloc::boxed::Box) -> Self { // SAFETY: // * The Box type guarantees this is initialized and not aliased. @@ -577,6 +583,68 @@ impl<'ctx, T: ?Sized> From> } } +#[cfg(feature = "alloc")] +impl<'ctx, T: ?Sized, U> From>> + for LeakBox<'ctx, T> +{ + fn from(boxed: alloc::boxed::Box>) -> Self { + // SAFETY: + // * The Box type guarantees this is initialized and not aliased. + let (ptr, _allocator) = alloc::boxed::Box::into_raw_with_allocator(boxed); + unsafe { LeakBox::from_raw(ptr) } + } +} + +#[cfg(feature = "alloc")] +impl<'ctx, T> From> for LeakBox<'ctx, [T]> { + fn from(boxed: alloc::vec::Vec) -> Self { + let (ptr, len, _cap, _allocator) = alloc::vec::Vec::into_raw_parts_with_allocator(boxed); + let slice = core::ptr::slice_from_raw_parts_mut(ptr, len); + // SAFETY: + // * The Vec guarantees that all elements within its length are initialized and not aliased. + unsafe { LeakBox::from_raw(slice) } + } +} + +#[cfg(feature = "alloc")] +impl<'ctx, T, U> From>> + for LeakBox<'ctx, [T]> +{ + fn from(boxed: alloc::vec::Vec>) -> Self { + let (ptr, len, _cap, _allocator) = alloc::vec::Vec::into_raw_parts_with_allocator(boxed); + let slice = core::ptr::slice_from_raw_parts_mut(ptr, len); + // SAFETY: + // * The Vec guarantees that all elements within its length are initialized and not aliased. + unsafe { LeakBox::from_raw(slice) } + } +} + +#[cfg(feature = "alloc")] +impl<'ctx, T> From> + for LeakBox<'ctx, [T]> +{ + fn from(boxed: alloc::vec::Vec) -> Self { + let (ptr, len, _cap, _allocator) = alloc::vec::Vec::into_raw_parts_with_allocator(boxed); + let slice = core::ptr::slice_from_raw_parts_mut(ptr, len); + // SAFETY: + // * The Vec guarantees that all elements within its length are initialized and not aliased. + unsafe { LeakBox::from_raw(slice) } + } +} + +#[cfg(feature = "alloc")] +impl<'ctx, T, U> From>> + for LeakBox<'ctx, [T]> +{ + fn from(boxed: alloc::vec::Vec>) -> Self { + let (ptr, len, _cap, _allocator) = alloc::vec::Vec::into_raw_parts_with_allocator(boxed); + let slice = core::ptr::slice_from_raw_parts_mut(ptr, len); + // SAFETY: + // * The Vec guarantees that all elements within its length are initialized and not aliased. + unsafe { LeakBox::from_raw(slice) } + } +} + impl AsRef for LeakBox<'_, T> { fn as_ref(&self) -> &T { self diff --git a/static-alloc/tests/allocator-api2.rs b/static-alloc/tests/allocator-api2.rs index f0f5ce6..9435274 100644 --- a/static-alloc/tests/allocator-api2.rs +++ b/static-alloc/tests/allocator-api2.rs @@ -49,3 +49,40 @@ fn unsized_leak_box() { let _decay: LeakBox<'_, dyn core::fmt::Display> = LeakBox::from(boxed as astd::boxed::Box); } + +#[test] +fn convert_leaked_vec() { + let storage = unsync::Bump::<[u8; 128]>::uninit(); + + let mut v = astd::vec::Vec::::with_capacity_in(64, &storage); + v.extend(0u8..32); + assert_eq!(v.len(), 32); + assert_eq!(v.capacity(), 64); + + let leaked: LeakBox<'_, [u8]> = LeakBox::from(v); + + assert_eq!( + leaked.len(), + 32, + "Leak box only references initialized elements" + ); + + assert!( + leaked + .iter() + .enumerate() + .all(|(idx, &v)| idx == usize::from(v)) + ); +} + +#[test] +fn convert_empty_vec() { + let storage = unsync::Bump::<[u8; 128]>::uninit(); + // This non-allocating vector won't necessarily use the pointer by the allocator. That's fine, + // let's just verify that this still works and that miri can catch soundness problems (e.g + // provenance being incorrect despite this being a zero-length region). + let v = astd::vec::Vec::::with_capacity_in(0, &storage); + assert_eq!(v.capacity(), 0); + let leaked: LeakBox<'_, [u8]> = LeakBox::from(v); + assert_eq!(leaked.len(), 0); +} From c59b2529dcf0698c1f139f7e1fe309c6edb0a9c3 Mon Sep 17 00:00:00 2001 From: "A. Molzer" <5550310+197g@users.noreply.github.com> Date: Wed, 11 Nov 2026 17:38:02 +0100 Subject: [PATCH 5/6] Changelog for 0.4.0 --- static-alloc/Changes.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/static-alloc/Changes.md b/static-alloc/Changes.md index 2281530..ad81ae7 100644 --- a/static-alloc/Changes.md +++ b/static-alloc/Changes.md @@ -7,6 +7,16 @@ Structural: its functionality will be brought into this crate in a way that is not exposed in the public API. +Feature changes: +- Added `From` impls for `LeakBox` to convert an `Box` from the standard + `alloc` crate when they are allocated via handles from this crate. +- Added `From` impls for `LeakBox` to convert a `Vec` from the standard `alloc` + crate when they are allocated via handles from this crate into a boxed slice. + This will never reallocate and forget about the extraneous capacity. Only the + length is captured. +- Added `AllocTime` as a wrapper around the `alloc-traits` type of the same + name to disentangle this public dependency surface. + # v0.3.3 Expect this to be the last version before requiring rust-version 1.100 (the From a48002184211796459e6b780bf664658c99e4474 Mon Sep 17 00:00:00 2001 From: "A. Molzer" <5550310+197g@users.noreply.github.com> Date: Thu, 12 Nov 2026 20:35:39 +0100 Subject: [PATCH 6/6] Make alloc-traits a default feature --- static-alloc/Cargo.toml | 8 ++++++++ static-alloc/Changes.md | 5 ++++- static-alloc/src/allocator_api2.rs | 7 +++++-- static-alloc/src/lib.rs | 1 - 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/static-alloc/Cargo.toml b/static-alloc/Cargo.toml index 79c14de..05bb310 100644 --- a/static-alloc/Cargo.toml +++ b/static-alloc/Cargo.toml @@ -16,12 +16,20 @@ repository.workspace = true all-features = true [dependencies] +# Soft deprecated: currently some functionality is built on top of abstractions +# in this crate but we're no longer recommending the main surface since the +# `Allocator` trait was stabilized in `core` in Rust 1.100. alloc-traits = { path = "../alloc-traits", version = "0.1.0", optional = true } portable-atomic = { version = "1", optional = true, default-features = false } [dev-dependencies] [features] +# Required to build for now but intent to deprecate. Once we remove the hard +# dependency on this we will recommend using no-default-features and remove +# this from the default list in the next major release. +default = ["alloc-traits"] +# Provides interop for `alloc::{boxed::Box, vec::Vec}`. alloc = [] # Enables the `unsync::Chain` module. Note that this is explicitly outside the # SemVer stability guarantees! diff --git a/static-alloc/Changes.md b/static-alloc/Changes.md index ad81ae7..1c33e8d 100644 --- a/static-alloc/Changes.md +++ b/static-alloc/Changes.md @@ -1,7 +1,10 @@ # v0.4.0 Structural: -- The `allocator_api2` feature is removed as its functionality is now part of `alloc`. +- The `allocator_api2` feature is removed as its functionality is now part of + `core`. We implement the `core::alloc::Allocator` trait as part of the + unconditional public API. For historical reasons the module with adapters + will still be named `allocator_api2` for a while. - The `alloc-traits` dependency is now marked as optional, but still required for successful compilation. The crate is partly superseded by Rust 1.100 and its functionality will be brought into this crate in a way that is not diff --git a/static-alloc/src/allocator_api2.rs b/static-alloc/src/allocator_api2.rs index e311b1e..9d466fd 100644 --- a/static-alloc/src/allocator_api2.rs +++ b/static-alloc/src/allocator_api2.rs @@ -3,8 +3,11 @@ use crate::{ unsync, }; -use alloc::alloc::{AllocError, Allocator, Layout}; -use core::{cell, ptr::NonNull}; +use core::{ + alloc::{AllocError, Allocator, Layout}, + cell, + ptr::NonNull, +}; unsafe impl Allocator for Bump { fn allocate(&self, layout: Layout) -> Result, AllocError> { diff --git a/static-alloc/src/lib.rs b/static-alloc/src/lib.rs index 5d0f229..13c573c 100644 --- a/static-alloc/src/lib.rs +++ b/static-alloc/src/lib.rs @@ -51,7 +51,6 @@ compile_error!("The `alloc-traits` feature is required for this crate to work"); extern crate alloc; /// Specialized types for `allocator-api2` (the planned std allocator). -#[cfg(feature = "alloc")] pub mod allocator_api2; pub mod bump;