diff --git a/CHANGELOG.md b/CHANGELOG.md index a991cf9..eb270e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,30 @@ Released YYYY-MM-DD. -------------------------------------------------------------------------------- +## 1.4.0 + +Released 2024-10-30. + +### Added + +* Added an `Arbitrary` implementation for `PhantomPinned`. +* Added the `Unstructured::choose_iter` helper method. +* Added `#[arbitrary(skip)]` for `enum` variants in the derive macro. +* Added the `Arbitrary::try_size_hint` trait method. + +### Changed + +* Implement `Arbitrary` for `PhantomData` even when `A` does not implement + `Arbitrary` and when `A` is `?Sized`. +* Make `usize`'s underlying encoding independent of machine word size so that + corpora are more portable. + +### Fixed + +* Make `derive(Arbitrary)` work for local definitions of `struct Option`. + +-------------------------------------------------------------------------------- + ## 1.3.2 Released 2023-10-30. diff --git a/Cargo.toml b/Cargo.toml index 4f7b725..56c9d48 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "arbitrary" -version = "1.3.2" # Make sure this matches the derive crate version (not including the patch version) +version = "1.4.0" # Make sure this matches the derive crate version (not including the patch version) authors = [ "The Rust-Fuzz Project Developers", "Nick Fitzgerald ", @@ -20,7 +20,7 @@ documentation = "https://docs.rs/arbitrary/" rust-version = "1.63.0" [dependencies] -derive_arbitrary = { version = "1.3.2", path = "./derive", optional = true } +derive_arbitrary = { version = "1.4.0", path = "./derive", optional = true } [features] # Turn this feature on to enable support for `#[derive(Arbitrary)]`. diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 9cbf384..c623d65 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "derive_arbitrary" -version = "1.3.2" # Make sure it matches the version of the arbitrary crate itself (not including the patch version) +version = "1.4.0" # Make sure it matches the version of the arbitrary crate itself (not including the patch version) authors = [ "The Rust-Fuzz Project Developers", "Nick Fitzgerald ", @@ -24,4 +24,4 @@ quote = "1.0" syn = { version = "2", features = ['derive', 'parsing', 'extra-traits'] } [lib] -proc_macro = true +proc-macro = true diff --git a/src/lib.rs b/src/lib.rs index 79f26e8..a7ea6cf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -223,21 +223,22 @@ pub trait Arbitrary<'a>: Sized { /// This is useful for determining how many elements we should insert when /// creating an arbitrary collection. /// - /// The return value is similar to - /// [`Iterator::size_hint`]: it returns a tuple where - /// the first element is a lower bound on the number of bytes required, and - /// the second element is an optional upper bound. + /// The return value is similar to [`Iterator::size_hint`]: it returns a + /// tuple where the first element is a lower bound on the number of bytes + /// required, and the second element is an optional upper bound. /// /// The default implementation return `(0, None)` which is correct for any /// type, but not ultimately that useful. Using `#[derive(Arbitrary)]` will /// create a better implementation. If you are writing an `Arbitrary` /// implementation by hand, and your type can be part of a dynamically sized /// collection (such as `Vec`), you are strongly encouraged to override this - /// default with a better implementation, and also override [`try_size_hint`] + /// default with a better implementation, and also override + /// [`try_size_hint`]. /// /// ## How to implement this /// - /// If the size hint calculation is a trivial constant and does not recurse into any other `size_hint` call, you should implement it in `size_hint`: + /// If the size hint calculation is a trivial constant and does not recurse + /// into any other `size_hint` call, you should implement it in `size_hint`: /// /// ``` /// use arbitrary::{size_hint, Arbitrary, Result, Unstructured}; @@ -272,7 +273,8 @@ pub trait Arbitrary<'a>: Sized { /// /// impl<'a, A: Arbitrary<'a>, B: Arbitrary<'a>> Arbitrary<'a> for SomeStruct { /// fn arbitrary(u: &mut Unstructured<'a>) -> Result { - /// todo!() + /// // ... + /// # todo!() /// } /// /// fn size_hint(depth: usize) -> (usize, Option) { @@ -323,20 +325,22 @@ pub trait Arbitrary<'a>: Sized { /// Get a size hint for how many bytes out of an `Unstructured` this type /// needs to construct itself. /// - /// Unlike [`size_hint`], this function keeps the information - /// that the recursion limit was reached. This is required to "short circuit" the calculation - /// and avoid exponential blowup with recursive structures. + /// Unlike [`size_hint`], this function keeps the information that the + /// recursion limit was reached. This is required to "short circuit" the + /// calculation and avoid exponential blowup with recursive structures. /// - /// If you are implementing [`size_hint`] for a struct that could be recursive, you should implement `try_size_hint` and call the `try_size_hint` when recursing + /// If you are implementing [`size_hint`] for a struct that could be + /// recursive, you should implement `try_size_hint` and call the + /// `try_size_hint` when recursing /// /// - /// The return value is similar to - /// [`Iterator::size_hint`][iterator-size-hint]: it returns a tuple where - /// the first element is a lower bound on the number of bytes required, and - /// the second element is an optional upper bound. + /// The return value is similar to [`core::iter::Iterator::size_hint`]: it + /// returns a tuple where the first element is a lower bound on the number + /// of bytes required, and the second element is an optional upper bound. /// - /// The default implementation return the value of [`size_hint`] which is correct for any - /// type, but might lead to exponential blowup when dealing with recursive types. + /// The default implementation returns the value of [`size_hint`] which is + /// correct for any type, but might lead to exponential blowup when dealing + /// with recursive types. /// /// ## Invariant /// @@ -353,11 +357,15 @@ pub trait Arbitrary<'a>: Sized { /// /// If you 100% know that the type you are implementing `Arbitrary` for is /// not a recursive type, or your implementation is not transitively calling - /// any other `size_hint` methods, you just implement [`size_hint`], and the + /// any other `size_hint` methods, you may implement [`size_hint`], and the /// default `try_size_hint` implementation will use it. + /// /// Note that if you are implementing `Arbitrary` for a generic type, you /// cannot guarantee the lack of type recursion! /// + /// Otherwise, when there is possible type recursion, you should implement + /// `try_size_hint` instead. + /// /// ## The `depth` parameter /// /// When implementing `try_size_hint`, you need to use @@ -386,9 +394,10 @@ pub trait Arbitrary<'a>: Sized { /// } /// /// fn size_hint(depth: usize) -> (usize, Option) { - /// // Return the value of try_size_hint + /// // Return the value of `try_size_hint` /// // - /// // If the recursion fails, return the default, always valid `(0, None)` + /// // If the recursion fails, return the default `(0, None)` range, + /// // which is always valid. /// Self::try_size_hint(depth).unwrap_or_default() /// } /// @@ -410,8 +419,6 @@ pub trait Arbitrary<'a>: Sized { /// } /// } /// ``` - /// [iterator-size-hint]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.size_hint - /// [`size_hint`]: Arbitrary::size_hint #[inline] fn try_size_hint(depth: usize) -> Result<(usize, Option), MaxRecursionReached> { Ok(Self::size_hint(depth))