diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 72f3d12..d191218 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -25,6 +25,20 @@ jobs: run: cargo test --verbose --all-features --all - name: Build Examples run: cargo build --examples --all-features --all + no_std_build: + name: no_std Build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: rustup update + - name: Build + run: cargo build --verbose --no-default-features + - name: Build + run: cargo build --verbose --no-default-features --features=alloc + - name: Run tests + run: cargo test --verbose --no-default-features + - name: Run tests as no_std with alloc + run: cargo test --verbose --no-default-features --features=alloc clippy: name: Clippy runs-on: ubuntu-latest diff --git a/Cargo.toml b/Cargo.toml index 4f7b725..c1e24f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,8 +23,15 @@ rust-version = "1.63.0" derive_arbitrary = { version = "1.3.2", path = "./derive", optional = true } [features] +# Provide support for std types by default. +default = ["std"] # Turn this feature on to enable support for `#[derive(Arbitrary)]`. derive = ["derive_arbitrary"] +# Whether or not to require the standard library. Turning off this feature +# makes Arbitrary work with no_std crates. +std = ["alloc"] +# Provide support for alloc types. +alloc = [] [[example]] name = "derive_enum" diff --git a/src/error.rs b/src/error.rs index 6ca8f19..67163b9 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,4 +1,4 @@ -use std::{error, fmt}; +use core::fmt; /// An enumeration of buffer creation errors #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -32,12 +32,13 @@ impl fmt::Display for Error { } } -impl error::Error for Error {} +#[cfg(feature = "std")] +impl std::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 { diff --git a/src/lib.rs b/src/lib.rs index 7270364..8f0b842 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,6 +14,7 @@ //! [`Arbitrary`](./trait.Arbitrary.html) 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)] @@ -43,16 +44,42 @@ use core::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZ use core::ops::{Range, RangeBounds, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive}; use core::str; use core::time::Duration; -use std::borrow::{Cow, ToOwned}; -use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque}; -use std::ffi::{CString, OsString}; + +#[cfg(feature = "alloc")] +extern crate alloc; + +#[cfg(feature = "alloc")] +use alloc::borrow::Cow; +#[cfg(all(not(feature = "std"), feature = "alloc"))] +use alloc::borrow::ToOwned; +#[cfg(all(not(feature = "std"), feature = "alloc"))] +use alloc::boxed::Box; +#[cfg(feature = "alloc")] +use alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque}; +#[cfg(feature = "alloc")] +use alloc::ffi::CString; +#[cfg(feature = "alloc")] +use alloc::rc::Rc; +#[cfg(all(not(feature = "std"), feature = "alloc"))] +use alloc::string::String; +#[cfg(feature = "alloc")] +use alloc::sync::Arc; +#[cfg(all(not(feature = "std"), feature = "alloc"))] +use alloc::vec::Vec; +use core::ops::Bound; +use core::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize}; +#[cfg(feature = "std")] +use std::collections::{HashMap, HashSet}; +#[cfg(feature = "std")] +use std::ffi::OsString; +#[cfg(feature = "std")] use std::hash::BuildHasher; +#[cfg(feature = "std")] use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; -use std::ops::Bound; +#[cfg(feature = "std")] use std::path::PathBuf; -use std::rc::Rc; -use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize}; -use std::sync::{Arc, Mutex}; +#[cfg(feature = "std")] +use std::sync::Mutex; /// Generate arbitrary structured values from raw, unstructured data. /// @@ -81,11 +108,13 @@ use std::sync::{Arc, Mutex}; /// use arbitrary::Arbitrary; /// use std::collections::HashSet; /// +/// # #[cfg(feature = "std")] /// #[derive(Arbitrary)] /// pub struct AddressBook { /// friends: HashSet, /// } /// +/// # #[cfg(feature = "alloc")] /// #[derive(Arbitrary, Hash, Eq, PartialEq)] /// pub enum Friend { /// Buddy { name: String }, @@ -381,7 +410,7 @@ impl_arbitrary_for_floats! { impl<'a> Arbitrary<'a> for char { fn arbitrary(u: &mut Unstructured<'a>) -> Result { - use std::char; + use core::char; // The highest unicode code point is 0x11_FFFF const CHAR_END: u32 = 0x11_0000; // The size of the surrogate blocks @@ -560,7 +589,7 @@ impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Option { } } -impl<'a, A: Arbitrary<'a>, B: Arbitrary<'a>> Arbitrary<'a> for std::result::Result { +impl<'a, A: Arbitrary<'a>, B: Arbitrary<'a>> Arbitrary<'a> for core::result::Result { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Ok(if >::arbitrary(u)? { Ok(::arbitrary(u)?) @@ -690,6 +719,7 @@ impl<'a> Arbitrary<'a> for &'a [u8] { } } +#[cfg(feature = "alloc")] impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Vec { fn arbitrary(u: &mut Unstructured<'a>) -> Result { u.arbitrary_iter()?.collect() @@ -705,6 +735,7 @@ impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Vec { } } +#[cfg(feature = "alloc")] impl<'a, K: Arbitrary<'a> + Ord, V: Arbitrary<'a>> Arbitrary<'a> for BTreeMap { fn arbitrary(u: &mut Unstructured<'a>) -> Result { u.arbitrary_iter()?.collect() @@ -720,6 +751,7 @@ impl<'a, K: Arbitrary<'a> + Ord, V: Arbitrary<'a>> Arbitrary<'a> for BTreeMap + Ord> Arbitrary<'a> for BTreeSet { fn arbitrary(u: &mut Unstructured<'a>) -> Result { u.arbitrary_iter()?.collect() @@ -754,6 +786,7 @@ impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Bound { } } +#[cfg(feature = "alloc")] impl<'a, A: Arbitrary<'a> + Ord> Arbitrary<'a> for BinaryHeap { fn arbitrary(u: &mut Unstructured<'a>) -> Result { u.arbitrary_iter()?.collect() @@ -769,7 +802,8 @@ impl<'a, A: Arbitrary<'a> + Ord> Arbitrary<'a> for BinaryHeap { } } -impl<'a, K: Arbitrary<'a> + Eq + ::std::hash::Hash, V: Arbitrary<'a>, S: BuildHasher + Default> +#[cfg(feature = "std")] +impl<'a, K: Arbitrary<'a> + Eq + core::hash::Hash, V: Arbitrary<'a>, S: BuildHasher + Default> Arbitrary<'a> for HashMap { fn arbitrary(u: &mut Unstructured<'a>) -> Result { @@ -786,7 +820,8 @@ impl<'a, K: Arbitrary<'a> + Eq + ::std::hash::Hash, V: Arbitrary<'a>, S: BuildHa } } -impl<'a, A: Arbitrary<'a> + Eq + ::std::hash::Hash, S: BuildHasher + Default> Arbitrary<'a> +#[cfg(feature = "std")] +impl<'a, A: Arbitrary<'a> + Eq + core::hash::Hash, S: BuildHasher + Default> Arbitrary<'a> for HashSet { fn arbitrary(u: &mut Unstructured<'a>) -> Result { @@ -803,6 +838,7 @@ impl<'a, A: Arbitrary<'a> + Eq + ::std::hash::Hash, S: BuildHasher + Default> Ar } } +#[cfg(feature = "alloc")] impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for LinkedList { fn arbitrary(u: &mut Unstructured<'a>) -> Result { u.arbitrary_iter()?.collect() @@ -818,6 +854,7 @@ impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for LinkedList { } } +#[cfg(feature = "alloc")] impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for VecDeque { fn arbitrary(u: &mut Unstructured<'a>) -> Result { u.arbitrary_iter()?.collect() @@ -833,6 +870,7 @@ impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for VecDeque { } } +#[cfg(feature = "alloc")] impl<'a, A> Arbitrary<'a> for Cow<'a, A> where A: ToOwned + ?Sized, @@ -885,6 +923,7 @@ impl<'a> Arbitrary<'a> for &'a str { } } +#[cfg(feature = "alloc")] impl<'a> Arbitrary<'a> for String { fn arbitrary(u: &mut Unstructured<'a>) -> Result { <&str as Arbitrary>::arbitrary(u).map(Into::into) @@ -900,6 +939,7 @@ impl<'a> Arbitrary<'a> for String { } } +#[cfg(feature = "alloc")] impl<'a> Arbitrary<'a> for CString { fn arbitrary(u: &mut Unstructured<'a>) -> Result { as Arbitrary>::arbitrary(u).map(|mut x| { @@ -915,6 +955,7 @@ impl<'a> Arbitrary<'a> for CString { } } +#[cfg(feature = "std")] impl<'a> Arbitrary<'a> for OsString { fn arbitrary(u: &mut Unstructured<'a>) -> Result { ::arbitrary(u).map(From::from) @@ -926,6 +967,7 @@ impl<'a> Arbitrary<'a> for OsString { } } +#[cfg(feature = "std")] impl<'a> Arbitrary<'a> for PathBuf { fn arbitrary(u: &mut Unstructured<'a>) -> Result { ::arbitrary(u).map(From::from) @@ -937,6 +979,7 @@ impl<'a> Arbitrary<'a> for PathBuf { } } +#[cfg(feature = "alloc")] impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Box { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Arbitrary::arbitrary(u).map(Self::new) @@ -948,6 +991,7 @@ impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Box { } } +#[cfg(feature = "alloc")] impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Box<[A]> { fn arbitrary(u: &mut Unstructured<'a>) -> Result { u.arbitrary_iter()?.collect() @@ -963,6 +1007,7 @@ impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Box<[A]> { } } +#[cfg(feature = "alloc")] impl<'a> Arbitrary<'a> for Box { fn arbitrary(u: &mut Unstructured<'a>) -> Result { ::arbitrary(u).map(|x| x.into_boxed_str()) @@ -987,6 +1032,7 @@ impl<'a> Arbitrary<'a> for Box { // } // } +#[cfg(feature = "alloc")] impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Arc { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Arbitrary::arbitrary(u).map(Self::new) @@ -998,6 +1044,7 @@ impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Arc { } } +#[cfg(feature = "alloc")] impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Arc<[A]> { fn arbitrary(u: &mut Unstructured<'a>) -> Result { u.arbitrary_iter()?.collect() @@ -1013,6 +1060,7 @@ impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Arc<[A]> { } } +#[cfg(feature = "alloc")] impl<'a> Arbitrary<'a> for Arc { fn arbitrary(u: &mut Unstructured<'a>) -> Result { <&str as Arbitrary>::arbitrary(u).map(Into::into) @@ -1024,6 +1072,7 @@ impl<'a> Arbitrary<'a> for Arc { } } +#[cfg(feature = "alloc")] impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Rc { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Arbitrary::arbitrary(u).map(Self::new) @@ -1035,6 +1084,7 @@ impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Rc { } } +#[cfg(feature = "alloc")] impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Rc<[A]> { fn arbitrary(u: &mut Unstructured<'a>) -> Result { u.arbitrary_iter()?.collect() @@ -1050,6 +1100,7 @@ impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Rc<[A]> { } } +#[cfg(feature = "alloc")] impl<'a> Arbitrary<'a> for Rc { fn arbitrary(u: &mut Unstructured<'a>) -> Result { <&str as Arbitrary>::arbitrary(u).map(Into::into) @@ -1094,6 +1145,7 @@ impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for UnsafeCell { } } +#[cfg(feature = "std")] impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Mutex { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Arbitrary::arbitrary(u).map(Self::new) @@ -1116,9 +1168,9 @@ impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for iter::Empty { } } -impl<'a, A: ?Sized> Arbitrary<'a> for ::std::marker::PhantomData { +impl<'a, A: ?Sized> Arbitrary<'a> for core::marker::PhantomData { fn arbitrary(_: &mut Unstructured<'a>) -> Result { - Ok(::std::marker::PhantomData) + Ok(core::marker::PhantomData) } #[inline] @@ -1127,9 +1179,9 @@ impl<'a, A: ?Sized> Arbitrary<'a> for ::std::marker::PhantomData { } } -impl<'a> Arbitrary<'a> for ::std::marker::PhantomPinned { +impl<'a> Arbitrary<'a> for core::marker::PhantomPinned { fn arbitrary(_: &mut Unstructured<'a>) -> Result { - Ok(::std::marker::PhantomPinned) + Ok(core::marker::PhantomPinned) } #[inline] @@ -1138,9 +1190,9 @@ impl<'a> Arbitrary<'a> for ::std::marker::PhantomPinned { } } -impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for ::std::num::Wrapping { +impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for core::num::Wrapping { fn arbitrary(u: &mut Unstructured<'a>) -> Result { - Arbitrary::arbitrary(u).map(::std::num::Wrapping) + Arbitrary::arbitrary(u).map(core::num::Wrapping) } #[inline] @@ -1180,6 +1232,7 @@ implement_nonzero_int! { NonZeroU64, u64 } implement_nonzero_int! { NonZeroU128, u128 } implement_nonzero_int! { NonZeroUsize, usize } +#[cfg(feature = "std")] impl<'a> Arbitrary<'a> for Ipv4Addr { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Ok(Ipv4Addr::from(u32::arbitrary(u)?)) @@ -1191,6 +1244,7 @@ impl<'a> Arbitrary<'a> for Ipv4Addr { } } +#[cfg(feature = "std")] impl<'a> Arbitrary<'a> for Ipv6Addr { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Ok(Ipv6Addr::from(u128::arbitrary(u)?)) @@ -1202,6 +1256,7 @@ impl<'a> Arbitrary<'a> for Ipv6Addr { } } +#[cfg(feature = "std")] impl<'a> Arbitrary<'a> for IpAddr { fn arbitrary(u: &mut Unstructured<'a>) -> Result { if u.arbitrary()? { @@ -1219,6 +1274,7 @@ impl<'a> Arbitrary<'a> for IpAddr { } } +#[cfg(feature = "std")] impl<'a> Arbitrary<'a> for SocketAddrV4 { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Ok(SocketAddrV4::new(u.arbitrary()?, u.arbitrary()?)) @@ -1230,6 +1286,7 @@ impl<'a> Arbitrary<'a> for SocketAddrV4 { } } +#[cfg(feature = "std")] impl<'a> Arbitrary<'a> for SocketAddrV6 { fn arbitrary(u: &mut Unstructured<'a>) -> Result { Ok(SocketAddrV6::new( @@ -1252,6 +1309,7 @@ impl<'a> Arbitrary<'a> for SocketAddrV6 { } } +#[cfg(feature = "std")] impl<'a> Arbitrary<'a> for SocketAddr { fn arbitrary(u: &mut Unstructured<'a>) -> Result { if u.arbitrary()? { @@ -1275,6 +1333,7 @@ impl<'a> Arbitrary<'a> for SocketAddr { #[cfg(test)] mod test { use super::*; + use std::collections::HashSet; /// Assert that the given expected values are all generated. /// @@ -1427,6 +1486,7 @@ mod test { } #[test] + #[cfg(feature = "alloc")] fn arbitrary_for_vec_u8() { assert_generates::>([ vec![], @@ -1448,6 +1508,7 @@ mod test { } #[test] + #[cfg(feature = "alloc")] fn arbitrary_for_vec_vec_u8() { assert_generates::>>([ vec![], @@ -1466,6 +1527,7 @@ mod test { } #[test] + #[cfg(feature = "alloc")] fn arbitrary_for_vec_vec_vec_u8() { assert_generates::>>>([ vec![], @@ -1490,11 +1552,13 @@ mod test { } #[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, @@ -1530,6 +1594,7 @@ mod test { } #[test] + #[cfg(feature = "alloc")] fn arbitrary_take_rest() { // Basic examples let x = [1, 2, 3, 4]; @@ -1580,6 +1645,7 @@ mod test { } #[test] + #[cfg(feature = "alloc")] fn size_hint_for_tuples() { assert_eq!( (7, Some(7)), diff --git a/src/size_hint.rs b/src/size_hint.rs index 045c148..2d32a5e 100644 --- a/src/size_hint.rs +++ b/src/size_hint.rs @@ -42,10 +42,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/unstructured.rs b/src/unstructured.rs index b8f6038..34460f1 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) } @@ -238,19 +238,19 @@ impl<'a> Unstructured<'a> { // We only consume as many bytes as necessary to cover the entire // range of the byte string. // Note: We cast to u64 so we don't overflow when checking std::u32::MAX + 4 on 32-bit archs - let len = if self.data.len() as u64 <= std::u8::MAX as u64 + 1 { + let len = if self.data.len() as u64 <= core::u8::MAX as u64 + 1 { let bytes = 1; let max_size = self.data.len() - bytes; let (rest, for_size) = self.data.split_at(max_size); self.data = rest; Self::int_in_range_impl(0..=max_size as u8, for_size.iter().copied())?.0 as usize - } else if self.data.len() as u64 <= std::u16::MAX as u64 + 2 { + } else if self.data.len() as u64 <= core::u16::MAX as u64 + 2 { let bytes = 2; let max_size = self.data.len() - bytes; let (rest, for_size) = self.data.split_at(max_size); self.data = rest; Self::int_in_range_impl(0..=max_size as u16, for_size.iter().copied())?.0 as usize - } else if self.data.len() as u64 <= std::u32::MAX as u64 + 4 { + } else if self.data.len() as u64 <= core::u32::MAX as u64 + 4 { let bytes = 4; let max_size = self.data.len() - bytes; let (rest, for_size) = self.data.split_at(max_size); @@ -520,7 +520,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; @@ -764,7 +764,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 diff --git a/tests/derive.rs b/tests/derive.rs index a84e4dc..4c157cc 100644 --- a/tests/derive.rs +++ b/tests/derive.rs @@ -43,12 +43,15 @@ fn tuple_struct() { assert_eq!((2, Some(2)), ::size_hint(0)); } +#[cfg(feature = "alloc")] #[derive(Clone, Debug, Arbitrary)] struct EndingInVec(u8, bool, u32, Vec); +#[cfg(feature = "alloc")] #[derive(Clone, Debug, Arbitrary)] struct EndingInString(u8, bool, u32, String); #[test] +#[cfg(feature = "alloc")] fn test_take_rest() { let bytes = [1, 1, 1, 2, 3, 4, 5, 6, 7, 8]; let s1 = EndingInVec::arbitrary_take_rest(Unstructured::new(&bytes)).unwrap(); @@ -116,6 +119,7 @@ fn derive_enum() { assert_eq!((4, Some(17)), ::size_hint(0)); } +#[cfg(feature = "alloc")] #[derive(Arbitrary, Debug)] enum RecursiveTree { Leaf, @@ -125,6 +129,7 @@ enum RecursiveTree { }, } +#[cfg(feature = "alloc")] #[test] fn recursive() { let raw = vec![1, 2, 3, 4, 5, 6, 7, 8, 9]; diff --git a/tests/path.rs b/tests/path.rs index c42ec0a..0884c31 100644 --- a/tests/path.rs +++ b/tests/path.rs @@ -23,6 +23,7 @@ pub enum Enum { Y(u8), } +#[cfg(feature = "alloc")] #[derive(arbitrary::Arbitrary, Clone, Debug)] struct EndingInVec(u8, bool, u32, Vec);