From 3a7a32b76d4b76fac46f6f44e228e8682e15af17 Mon Sep 17 00:00:00 2001 From: Nicholas Gildenhuys Date: Wed, 24 Sep 2025 12:20:25 -0700 Subject: [PATCH 1/5] feat: making the crate no_std and alloc compatible --- Cargo.toml | 16 ++++++++------ fuzz/fuzz_targets/int_in_range.rs | 2 +- src/error.rs | 6 +++--- src/foreign/alloc/borrow.rs | 2 +- src/foreign/alloc/boxed.rs | 2 +- src/foreign/alloc/collections/binary_heap.rs | 2 +- src/foreign/alloc/collections/btree_map.rs | 2 +- src/foreign/alloc/collections/btree_set.rs | 2 +- src/foreign/alloc/collections/linked_list.rs | 2 +- src/foreign/alloc/collections/vec_deque.rs | 2 +- src/foreign/alloc/ffi/c_str.rs | 2 +- src/foreign/alloc/rc.rs | 2 +- src/foreign/alloc/string.rs | 2 +- src/foreign/alloc/sync.rs | 2 +- src/foreign/alloc/vec.rs | 2 +- src/foreign/mod.rs | 2 ++ src/foreign/std/collections/hash_map.rs | 6 ++---- src/foreign/std/collections/hash_set.rs | 6 ++---- src/lib.rs | 14 ++++++++----- src/size_hint.rs | 4 ++-- src/tests.rs | 4 +++- src/unstructured.rs | 22 ++++++++++---------- 22 files changed, 57 insertions(+), 49 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 20aa826..f06f516 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,12 +2,12 @@ name = "arbitrary" version = "1.4.2" # Make sure this matches the derive crate version (not including the patch version) authors = [ - "The Rust-Fuzz Project Developers", - "Nick Fitzgerald ", - "Manish Goregaokar ", - "Simonas Kazlauskas ", - "Brian L. Troutwine ", - "Corey Farwell ", + "The Rust-Fuzz Project Developers", + "Nick Fitzgerald ", + "Manish Goregaokar ", + "Simonas Kazlauskas ", + "Brian L. Troutwine ", + "Corey Farwell ", ] categories = ["development-tools::testing"] edition = "2021" @@ -24,8 +24,12 @@ include = ["Cargo.toml", "CHANGELOG.md", "LICENSE-MIT", "LICENSE-APACHE", "READM derive_arbitrary = { version = "~1.4.0", path = "./derive", optional = true } [features] +default = ["std"] + +alloc = [] # Turn this feature on to enable support for `#[derive(Arbitrary)]`. derive = ["derive_arbitrary"] +std = ["alloc"] [[example]] name = "derive_enum" diff --git a/fuzz/fuzz_targets/int_in_range.rs b/fuzz/fuzz_targets/int_in_range.rs index 14c07f0..6bedddf 100755 --- a/fuzz/fuzz_targets/int_in_range.rs +++ b/fuzz/fuzz_targets/int_in_range.rs @@ -1,8 +1,8 @@ #![no_main] use arbitrary::{unstructured::Int, Arbitrary, Result, Unstructured}; +use core::{fmt::Display, ops::RangeInclusive}; use libfuzzer_sys::fuzz_target; -use std::{fmt::Display, ops::RangeInclusive}; fuzz_target!(|data: &[u8]| { fuzz(data).expect("`int_in_range` should never return an error"); diff --git a/src/error.rs b/src/error.rs index 8cdf39b..71698a5 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,4 +1,4 @@ -use std::{error, fmt}; +use core::{error, fmt}; /// An enumeration of buffer creation errors #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -41,14 +41,14 @@ impl error::Error for Error {} /// A `Result` with the error type fixed as `arbitrary::Error`. /// /// Either an `Ok(T)` or `Err(arbitrary::Error)`. -pub type Result = std::result::Result; +pub type Result = core::result::Result; #[cfg(test)] mod tests { // Often people will import our custom `Result` type because 99.9% of // results in a file will be `arbitrary::Result` but then have that one last // 0.1% that want to have a custom error type. Don't make them prefix that - // 0.1% as `std::result::Result`; instead, let `arbitrary::Result` have an + // 0.1% as `core::result::Result`; instead, let `arbitrary::Result` have an // overridable error type. #[test] fn can_use_custom_error_types_with_result() -> super::Result<(), String> { diff --git a/src/foreign/alloc/borrow.rs b/src/foreign/alloc/borrow.rs index b5b1e22..617afcb 100644 --- a/src/foreign/alloc/borrow.rs +++ b/src/foreign/alloc/borrow.rs @@ -1,6 +1,6 @@ use { crate::{size_hint, Arbitrary, Result, Unstructured}, - std::borrow::{Cow, ToOwned}, + alloc::borrow::{Cow, ToOwned}, }; impl<'a, A> Arbitrary<'a> for Cow<'a, A> diff --git a/src/foreign/alloc/boxed.rs b/src/foreign/alloc/boxed.rs index c3014a3..1409e0f 100644 --- a/src/foreign/alloc/boxed.rs +++ b/src/foreign/alloc/boxed.rs @@ -1,6 +1,6 @@ use { crate::{size_hint, Arbitrary, Result, Unstructured}, - std::boxed::Box, + alloc::boxed::Box, }; impl<'a, A> Arbitrary<'a> for Box diff --git a/src/foreign/alloc/collections/binary_heap.rs b/src/foreign/alloc/collections/binary_heap.rs index 25a0384..02ef3fc 100644 --- a/src/foreign/alloc/collections/binary_heap.rs +++ b/src/foreign/alloc/collections/binary_heap.rs @@ -1,6 +1,6 @@ use { crate::{Arbitrary, Result, Unstructured}, - std::collections::binary_heap::BinaryHeap, + alloc::collections::binary_heap::BinaryHeap, }; impl<'a, A> Arbitrary<'a> for BinaryHeap diff --git a/src/foreign/alloc/collections/btree_map.rs b/src/foreign/alloc/collections/btree_map.rs index 21b93a4..65790c1 100644 --- a/src/foreign/alloc/collections/btree_map.rs +++ b/src/foreign/alloc/collections/btree_map.rs @@ -1,6 +1,6 @@ use { crate::{Arbitrary, Result, Unstructured}, - std::collections::btree_map::BTreeMap, + alloc::collections::btree_map::BTreeMap, }; impl<'a, K, V> Arbitrary<'a> for BTreeMap diff --git a/src/foreign/alloc/collections/btree_set.rs b/src/foreign/alloc/collections/btree_set.rs index 8c6e92f..b862a0f 100644 --- a/src/foreign/alloc/collections/btree_set.rs +++ b/src/foreign/alloc/collections/btree_set.rs @@ -1,6 +1,6 @@ use { crate::{Arbitrary, Result, Unstructured}, - std::collections::btree_set::BTreeSet, + alloc::collections::btree_set::BTreeSet, }; impl<'a, A> Arbitrary<'a> for BTreeSet diff --git a/src/foreign/alloc/collections/linked_list.rs b/src/foreign/alloc/collections/linked_list.rs index 6bf2e98..7bb6425 100644 --- a/src/foreign/alloc/collections/linked_list.rs +++ b/src/foreign/alloc/collections/linked_list.rs @@ -1,6 +1,6 @@ use { crate::{Arbitrary, Result, Unstructured}, - std::collections::linked_list::LinkedList, + alloc::collections::linked_list::LinkedList, }; impl<'a, A> Arbitrary<'a> for LinkedList diff --git a/src/foreign/alloc/collections/vec_deque.rs b/src/foreign/alloc/collections/vec_deque.rs index 40e0413..44a37b6 100644 --- a/src/foreign/alloc/collections/vec_deque.rs +++ b/src/foreign/alloc/collections/vec_deque.rs @@ -1,6 +1,6 @@ use { crate::{Arbitrary, Result, Unstructured}, - std::collections::vec_deque::VecDeque, + alloc::collections::vec_deque::VecDeque, }; impl<'a, A> Arbitrary<'a> for VecDeque diff --git a/src/foreign/alloc/ffi/c_str.rs b/src/foreign/alloc/ffi/c_str.rs index a1b2383..53fa3da 100644 --- a/src/foreign/alloc/ffi/c_str.rs +++ b/src/foreign/alloc/ffi/c_str.rs @@ -1,6 +1,6 @@ use { crate::{Arbitrary, Result, Unstructured}, - std::ffi::CString, + alloc::ffi::CString, }; impl<'a> Arbitrary<'a> for CString { diff --git a/src/foreign/alloc/rc.rs b/src/foreign/alloc/rc.rs index 6d58167..2243be4 100644 --- a/src/foreign/alloc/rc.rs +++ b/src/foreign/alloc/rc.rs @@ -1,6 +1,6 @@ use { crate::{size_hint, Arbitrary, Result, Unstructured}, - std::rc::Rc, + alloc::rc::Rc, }; impl<'a, A> Arbitrary<'a> for Rc diff --git a/src/foreign/alloc/string.rs b/src/foreign/alloc/string.rs index a579784..47ea9eb 100644 --- a/src/foreign/alloc/string.rs +++ b/src/foreign/alloc/string.rs @@ -1,6 +1,6 @@ use { crate::{Arbitrary, Result, Unstructured}, - std::string::String, + alloc::string::String, }; impl<'a> Arbitrary<'a> for String { diff --git a/src/foreign/alloc/sync.rs b/src/foreign/alloc/sync.rs index c8ca1db..64d2dcd 100644 --- a/src/foreign/alloc/sync.rs +++ b/src/foreign/alloc/sync.rs @@ -1,6 +1,6 @@ use { crate::{size_hint, Arbitrary, Result, Unstructured}, - std::sync::Arc, + alloc::sync::Arc, }; impl<'a, A> Arbitrary<'a> for Arc diff --git a/src/foreign/alloc/vec.rs b/src/foreign/alloc/vec.rs index 63313ba..2985712 100644 --- a/src/foreign/alloc/vec.rs +++ b/src/foreign/alloc/vec.rs @@ -1,6 +1,6 @@ use { crate::{Arbitrary, Result, Unstructured}, - std::vec::Vec, + alloc::vec::Vec, }; impl<'a, A> Arbitrary<'a> for Vec diff --git a/src/foreign/mod.rs b/src/foreign/mod.rs index b1c42be..3868936 100644 --- a/src/foreign/mod.rs +++ b/src/foreign/mod.rs @@ -2,6 +2,8 @@ //! //! [`Arbitrary`]: crate::Arbitrary +#[cfg(feature = "alloc")] mod alloc; mod core; +#[cfg(feature = "std")] mod std; diff --git a/src/foreign/std/collections/hash_map.rs b/src/foreign/std/collections/hash_map.rs index d2e77af..85afe3a 100644 --- a/src/foreign/std/collections/hash_map.rs +++ b/src/foreign/std/collections/hash_map.rs @@ -1,9 +1,7 @@ use { crate::{Arbitrary, Result, Unstructured}, - std::{ - collections::hash_map::HashMap, - hash::{BuildHasher, Hash}, - }, + core::hash::{BuildHasher, Hash}, + std::collections::hash_map::HashMap, }; impl<'a, K, V, S> Arbitrary<'a> for HashMap diff --git a/src/foreign/std/collections/hash_set.rs b/src/foreign/std/collections/hash_set.rs index 5cb63d2..07c4c8a 100644 --- a/src/foreign/std/collections/hash_set.rs +++ b/src/foreign/std/collections/hash_set.rs @@ -1,9 +1,7 @@ use { crate::{Arbitrary, Result, Unstructured}, - std::{ - collections::hash_set::HashSet, - hash::{BuildHasher, Hash}, - }, + core::hash::{BuildHasher, Hash}, + std::collections::hash_set::HashSet, }; impl<'a, A, S> Arbitrary<'a> for HashSet diff --git a/src/lib.rs b/src/lib.rs index 8b28c69..fdedef1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,6 +14,7 @@ //! [`Arbitrary`] trait's documentation for details on //! automatically deriving, implementing, and/or using the trait. +#![cfg_attr(not(any(feature = "std", test)), no_std)] #![deny(bad_style)] #![deny(missing_docs)] #![deny(future_incompatible)] @@ -22,6 +23,9 @@ #![deny(rust_2018_idioms)] #![deny(unused)] +#[cfg(any(feature = "alloc", test))] +extern crate alloc; + mod error; mod foreign; pub mod size_hint; @@ -49,7 +53,7 @@ impl core::fmt::Display for MaxRecursionReached { } } -impl std::error::Error for MaxRecursionReached {} +impl core::error::Error for MaxRecursionReached {} /// Generate arbitrary structured values from raw, unstructured data. /// @@ -76,7 +80,7 @@ impl std::error::Error for MaxRecursionReached {} /// ``` /// # #[cfg(feature = "derive")] mod foo { /// use arbitrary::Arbitrary; -/// use std::collections::HashSet; +/// use alloc::collections::HashSet; /// /// #[derive(Arbitrary)] /// pub struct AddressBook { @@ -122,9 +126,9 @@ impl std::error::Error for MaxRecursionReached {} /// /// ``` /// # #[cfg(feature = "derive")] mod foo { -/// # pub struct MyCollection { _t: std::marker::PhantomData } +/// # pub struct MyCollection { _t: core::marker::PhantomData } /// # impl MyCollection { -/// # pub fn new() -> Self { MyCollection { _t: std::marker::PhantomData } } +/// # pub fn new() -> Self { MyCollection { _t: core::marker::PhantomData } } /// # pub fn insert(&mut self, element: T) {} /// # } /// use arbitrary::{Arbitrary, Result, Unstructured}; @@ -554,7 +558,7 @@ pub struct CompileFailTests; // Support for `#[derive(Arbitrary)]`. #[doc(hidden)] -#[cfg(feature = "derive")] +#[cfg(all(feature = "derive", feature = "std"))] pub mod details { use super::*; diff --git a/src/size_hint.rs b/src/size_hint.rs index 95707ee..9f73346 100644 --- a/src/size_hint.rs +++ b/src/size_hint.rs @@ -67,10 +67,10 @@ pub fn and_all(hints: &[(usize, Option)]) -> (usize, Option) { /// `lhs` and `rhs` size hints. #[inline] pub fn or(lhs: (usize, Option), rhs: (usize, Option)) -> (usize, Option) { - let lower = std::cmp::min(lhs.0, rhs.0); + let lower = core::cmp::min(lhs.0, rhs.0); let upper = lhs .1 - .and_then(|lhs| rhs.1.map(|rhs| std::cmp::max(lhs, rhs))); + .and_then(|lhs| rhs.1.map(|rhs| core::cmp::max(lhs, rhs))); (lower, upper) } diff --git a/src/tests.rs b/src/tests.rs index 7746715..4d1fea7 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,6 +1,8 @@ use { super::{Arbitrary, Result, Unstructured}, - std::{collections::HashSet, fmt::Debug, hash::Hash, rc::Rc, sync::Arc}, + alloc::{rc::Rc, sync::Arc}, + core::{fmt::Debug, hash::Hash}, + std::collections::HashSet, }; /// Assert that the given expected values are all generated. diff --git a/src/unstructured.rs b/src/unstructured.rs index 2b5e043..edccef2 100644 --- a/src/unstructured.rs +++ b/src/unstructured.rs @@ -9,9 +9,9 @@ //! Wrappers around raw, unstructured bytes. use crate::{Arbitrary, Error, Result}; -use std::marker::PhantomData; -use std::ops::ControlFlow; -use std::{mem, ops}; +use core::marker::PhantomData; +use core::ops::ControlFlow; +use core::{mem, ops}; /// A source of unstructured data. /// @@ -186,9 +186,9 @@ impl<'a> Unstructured<'a> { /// /// ``` /// use arbitrary::{Arbitrary, Result, Unstructured}; - /// # pub struct MyCollection { _t: std::marker::PhantomData } + /// # pub struct MyCollection { _t: core::marker::PhantomData } /// # impl MyCollection { - /// # pub fn with_capacity(capacity: usize) -> Self { MyCollection { _t: std::marker::PhantomData } } + /// # pub fn with_capacity(capacity: usize) -> Self { MyCollection { _t: core::marker::PhantomData } } /// # pub fn insert(&mut self, element: T) {} /// # } /// @@ -218,7 +218,7 @@ impl<'a> Unstructured<'a> { let byte_size = self.arbitrary_byte_size()?; let (lower, upper) = ::size_hint(0); let elem_size = upper.unwrap_or(lower * 2); - let elem_size = std::cmp::max(1, elem_size); + let elem_size = core::cmp::max(1, elem_size); Ok(byte_size / elem_size) } @@ -575,7 +575,7 @@ impl<'a> Unstructured<'a> { /// assert_eq!(buf, [0, 0]); /// ``` pub fn fill_buffer(&mut self, buffer: &mut [u8]) -> Result<()> { - let n = std::cmp::min(buffer.len(), self.data.len()); + let n = core::cmp::min(buffer.len(), self.data.len()); buffer[..n].copy_from_slice(&self.data[..n]); for byte in buffer[n..].iter_mut() { *byte = 0; @@ -691,8 +691,8 @@ impl<'a> Unstructured<'a> { /// times the function is called. /// /// You may break out of the loop early by returning - /// `Ok(std::ops::ControlFlow::Break)`. To continue the loop, return - /// `Ok(std::ops::ControlFlow::Continue)`. + /// `Ok(core::ops::ControlFlow::Break)`. To continue the loop, return + /// `Ok(core::ops::ControlFlow::Continue)`. /// /// # Panics /// @@ -705,7 +705,7 @@ impl<'a> Unstructured<'a> { /// /// ``` /// use arbitrary::{Result, Unstructured}; - /// use std::ops::ControlFlow; + /// use core::ops::ControlFlow; /// /// enum Type { /// /// A boolean type. @@ -819,7 +819,7 @@ impl<'a, ElementType: Arbitrary<'a>> Iterator for ArbitraryTakeRestIter<'a, Elem /// Don't implement this trait yourself. pub trait Int: Copy - + std::fmt::Debug + + core::fmt::Debug + PartialOrd + Ord + ops::Sub From 78c3b392a1dbc46f673469144a676f63dd488836 Mon Sep 17 00:00:00 2001 From: Nicholas Gildenhuys Date: Wed, 24 Sep 2025 13:26:21 -0700 Subject: [PATCH 2/5] fix: adding imports for string and vec uses in foreign alloc implementation --- src/foreign/alloc/boxed.rs | 2 +- src/foreign/alloc/ffi/c_str.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/foreign/alloc/boxed.rs b/src/foreign/alloc/boxed.rs index 1409e0f..f397557 100644 --- a/src/foreign/alloc/boxed.rs +++ b/src/foreign/alloc/boxed.rs @@ -1,6 +1,6 @@ use { crate::{size_hint, Arbitrary, Result, Unstructured}, - alloc::boxed::Box, + alloc::{boxed::Box, string::String}, }; impl<'a, A> Arbitrary<'a> for Box diff --git a/src/foreign/alloc/ffi/c_str.rs b/src/foreign/alloc/ffi/c_str.rs index 53fa3da..e95bbed 100644 --- a/src/foreign/alloc/ffi/c_str.rs +++ b/src/foreign/alloc/ffi/c_str.rs @@ -1,6 +1,6 @@ use { crate::{Arbitrary, Result, Unstructured}, - alloc::ffi::CString, + alloc::{ffi::CString, vec::Vec}, }; impl<'a> Arbitrary<'a> for CString { From ea3ee0ab1544117ac4f14c1bdea3e9ec64d72a14 Mon Sep 17 00:00:00 2001 From: Nicholas Gildenhuys Date: Tue, 7 Oct 2025 12:15:49 -0700 Subject: [PATCH 3/5] ci: adding ci check for the no srtd and alloc builds/test --- .github/workflows/rust.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 1dbac58..55c1573 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -61,3 +61,13 @@ jobs: run: cargo install cargo-fuzz - name: "Fuzz for 3 minutes" run: cargo fuzz run int_in_range -- -max_total_time=$((3 * 60)) + no_std_build: + name: no_std Build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: rustup update + - run: cargo build --verbose --no-default-features + - run: cargo test --verbose --no-default-features + - run: cargo build --verbose --no-default-features --features=alloc + - run: cargo test --verbose --no-default-features --features=alloc From 6a38ae6be992f8f3b002f06dda3ca818d31144cf Mon Sep 17 00:00:00 2001 From: Nicholas Gildenhuys Date: Tue, 7 Oct 2025 14:12:43 -0700 Subject: [PATCH 4/5] fix: cfg-ing out tests that require test alloc guarded features --- src/lib.rs | 4 ++-- src/tests.rs | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index fdedef1..50804f2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,7 +23,7 @@ #![deny(rust_2018_idioms)] #![deny(unused)] -#[cfg(any(feature = "alloc", test))] +#[cfg(feature = "alloc")] extern crate alloc; mod error; @@ -80,7 +80,7 @@ impl core::error::Error for MaxRecursionReached {} /// ``` /// # #[cfg(feature = "derive")] mod foo { /// use arbitrary::Arbitrary; -/// use alloc::collections::HashSet; +/// use std::collections::HashSet; /// /// #[derive(Arbitrary)] /// pub struct AddressBook { diff --git a/src/tests.rs b/src/tests.rs index 4d1fea7..69c5c0e 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,6 +1,7 @@ +#[cfg(feature = "alloc")] +use alloc::{rc::Rc, string::String, sync::Arc, vec::Vec}; use { super::{Arbitrary, Result, Unstructured}, - alloc::{rc::Rc, sync::Arc}, core::{fmt::Debug, hash::Hash}, std::collections::HashSet, }; @@ -156,6 +157,7 @@ fn arbitrary_take_rest_for_bytes() { } #[test] +#[cfg(feature = "alloc")] fn arbitrary_for_vec_u8() { assert_generates::>([ vec![], @@ -177,6 +179,7 @@ fn arbitrary_for_vec_u8() { } #[test] +#[cfg(feature = "alloc")] fn arbitrary_for_vec_vec_u8() { assert_generates::>>([ vec![], @@ -195,6 +198,7 @@ fn arbitrary_for_vec_vec_u8() { } #[test] +#[cfg(feature = "alloc")] fn arbitrary_for_vec_vec_vec_u8() { assert_generates::>>>([ vec![], @@ -219,11 +223,13 @@ fn arbitrary_for_vec_vec_vec_u8() { } #[test] +#[cfg(feature = "alloc")] fn arbitrary_for_string() { assert_generates::(["".into(), "a".into(), "aa".into(), "aaa".into()]); } #[test] +#[cfg(feature = "alloc")] fn arbitrary_collection() { let x = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 12, @@ -259,6 +265,7 @@ fn arbitrary_collection() { } #[test] +#[cfg(feature = "alloc")] fn arbitrary_take_rest() { // Basic examples let x = [1, 2, 3, 4]; @@ -309,6 +316,7 @@ fn arbitrary_take_rest() { } #[test] +#[cfg(feature = "alloc")] fn size_hint_for_tuples() { assert_eq!( (7, Some(7)), From cf3a5624aaa03dd22b135486d59ebe0d9849bea9 Mon Sep 17 00:00:00 2001 From: Nicholas Gildenhuys Date: Fri, 13 Mar 2026 11:01:02 -0700 Subject: [PATCH 5/5] fix: fixing msrv ci test by making the library use std for components that don't exist on older versions of rust core --- Cargo.toml | 1 + README.md | 6 ++++++ src/error.rs | 8 +++++++- src/foreign/alloc/ffi/c_str.rs | 6 +++++- src/lib.rs | 4 ++++ 5 files changed, 23 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f06f516..02209ab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ include = ["Cargo.toml", "CHANGELOG.md", "LICENSE-MIT", "LICENSE-APACHE", "READM [dependencies] derive_arbitrary = { version = "~1.4.0", path = "./derive", optional = true } +rustversion = "1" [features] default = ["std"] diff --git a/README.md b/README.md index 5d75f31..5f28c9a 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,12 @@ compile with older versions but that may change in any new patch release. We reserve the right to increment the MSRV on minor releases, however we will strive to only do it deliberately and for good reasons. +### Notes on no_std compatability: + +- When compiling for versions older than **1.81.0** the `std` feature must be enabled. +- When compiling for versions older than **1.64.0** the `impl` for `CString` is not available + with the `no_std` feature. And + ## License Licensed under dual MIT or Apache-2.0 at your choice. diff --git a/src/error.rs b/src/error.rs index 71698a5..1dc2d5a 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,4 +1,10 @@ -use core::{error, fmt}; +use core::fmt; + +#[rustversion::before(1.81)] +use std::error; + +#[rustversion::since(1.81)] +use core::error; /// An enumeration of buffer creation errors #[derive(Debug, Clone, Copy, PartialEq, Eq)] diff --git a/src/foreign/alloc/ffi/c_str.rs b/src/foreign/alloc/ffi/c_str.rs index e95bbed..ec213ec 100644 --- a/src/foreign/alloc/ffi/c_str.rs +++ b/src/foreign/alloc/ffi/c_str.rs @@ -1,6 +1,10 @@ +#[rustversion::since(1.64)] +use alloc::ffi::CString; +#[rustversion::before(1.64)] +use std::ffi::CString; use { crate::{Arbitrary, Result, Unstructured}, - alloc::{ffi::CString, vec::Vec}, + alloc::vec::Vec, }; impl<'a> Arbitrary<'a> for CString { diff --git a/src/lib.rs b/src/lib.rs index 50804f2..4192335 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,6 +53,10 @@ impl core::fmt::Display for MaxRecursionReached { } } +#[rustversion::before(1.81)] +impl std::error::Error for MaxRecursionReached {} + +#[rustversion::since(1.81)] impl core::error::Error for MaxRecursionReached {} /// Generate arbitrary structured values from raw, unstructured data.