Zerocopy comprises two crates: zerocopy and zerocopy-derive. Zerocopy has a disabled-by-default feature called derive. When it's enabled, zerocopy depends on zerocopy-derive and re-exports its derives so that users can just depend on zerocopy and don't have to also depend directly on zerocopy-derive.
Some of zerocopy's types implement the same traits that we provide derives for (currently, FromZeroes, FromBytes, AsBytes, and Unaligned). When the derive feature is enabled, we use the derives to derive implementations of those traits for our own types. When the derive feature is disabled, we implement those traits manually.
This creates a potential footgun: How do we know that the impls we emit when derive is enabled are identical to the impls that we emit when derive is disabled? Do they have the same bounds?
This issue tracks using the cargo-semver-checks crate to detect such mismatches for us. We already use cargo-semver-checks in CI:
Specifically, this issue tracks using cargo-semver-checks to make sure that:
The derive feature is semver backwards-compatible with the absence of the derive feature
The absence of the derive feature is semver backwards-compatible with the derive feature
Combined, these two conditions should have the effect of ensuring that the APIs with and without derive are equivalent.
This issue tracks the following concrete tasks:
[ ] Using the technique described in this comment, update ci.yml's cargo-semver-checks use to check that:
[ ] The crate with the derive feature is semver backwards-compatible with the crate without the derive feature
[ ] The crate without the derive feature is semver backwards-compatible with the crate with the derive feature. Note that this case is extra tricky! The derive feature re-exports the derives, which means that the APIs are expected to differ! Specifically, we expect that the crate without derive will fail to be backwards-compatible because it has "removed" these exports compared to the crate with derive. You will need to do one of the following:
Figure out how to tell cargo-semver-checks to expect this difference, and allow it
Decide that there's no way to support this in cargo-semver-checks, and leave a comment in ci.yml explaining why we don't currently support this check
[ ] Intentionally push two PRs which include this technique and which update zerocopy's source code to violate compatibility:
[ ] One which makes a change which makes derive semver-incompatible with no-derive
[ ] One which makes a change which makes no-derive semver-incompatible with derive
Zerocopy comprises two crates: zerocopy and zerocopy-derive. Zerocopy has a disabled-by-default feature called
derive
. When it's enabled, zerocopy depends on zerocopy-derive and re-exports its derives so that users can just depend on zerocopy and don't have to also depend directly on zerocopy-derive.Some of zerocopy's types implement the same traits that we provide derives for (currently,
FromZeroes
,FromBytes
,AsBytes
, andUnaligned
). When thederive
feature is enabled, we use the derives to derive implementations of those traits for our own types. When thederive
feature is disabled, we implement those traits manually.This creates a potential footgun: How do we know that the impls we emit when
derive
is enabled are identical to the impls that we emit whenderive
is disabled? Do they have the same bounds?This issue tracks using the cargo-semver-checks crate to detect such mismatches for us. We already use cargo-semver-checks in CI:
https://github.com/google/zerocopy/blob/3bb9a54ff458e104f7eb24beda7f8fb09794e1a5/.github/workflows/ci.yml#L207-L227
Specifically, this issue tracks using cargo-semver-checks to make sure that:
derive
feature is semver backwards-compatible with the absence of thederive
featurederive
feature is semver backwards-compatible with thederive
featureCombined, these two conditions should have the effect of ensuring that the APIs with and without
derive
are equivalent.This issue tracks the following concrete tasks:
ci.yml
's cargo-semver-checks use to check that:derive
feature is semver backwards-compatible with the crate without thederive
featurederive
feature is semver backwards-compatible with the crate with thederive
feature. Note that this case is extra tricky! Thederive
feature re-exports the derives, which means that the APIs are expected to differ! Specifically, we expect that the crate withoutderive
will fail to be backwards-compatible because it has "removed" these exports compared to the crate withderive
. You will need to do one of the following:ci.yml
explaining why we don't currently support this checkderive
semver-incompatible with no-derive
derive
semver-incompatible withderive