Skip to content

Commit

Permalink
Bump to 1.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
fitzgen committed Nov 4, 2024
1 parent 1cc0e46 commit 5b86c44
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 26 deletions.
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<A>` 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.
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -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 <fitzgen@gmail.com>",
Expand All @@ -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)]`.
Expand Down
4 changes: 2 additions & 2 deletions derive/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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 <fitzgen@gmail.com>",
Expand All @@ -24,4 +24,4 @@ quote = "1.0"
syn = { version = "2", features = ['derive', 'parsing', 'extra-traits'] }

[lib]
proc_macro = true
proc-macro = true
51 changes: 29 additions & 22 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -272,7 +273,8 @@ pub trait Arbitrary<'a>: Sized {
///
/// impl<'a, A: Arbitrary<'a>, B: Arbitrary<'a>> Arbitrary<'a> for SomeStruct<A, B> {
/// fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
/// todo!()
/// // ...
/// # todo!()
/// }
///
/// fn size_hint(depth: usize) -> (usize, Option<usize>) {
Expand Down Expand Up @@ -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
///
Expand All @@ -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
Expand Down Expand Up @@ -386,9 +394,10 @@ pub trait Arbitrary<'a>: Sized {
/// }
///
/// fn size_hint(depth: usize) -> (usize, Option<usize>) {
/// // 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()
/// }
///
Expand All @@ -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<usize>), MaxRecursionReached> {
Ok(Self::size_hint(depth))
Expand Down

0 comments on commit 5b86c44

Please sign in to comment.