google / google/zerocopy

Make errors witnesses to a cast's source type

Open
#1,863 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
2.6k
Forks
179
Avg merge
1d 19h
Merged PRs (30d)
29

Description

## Design

### Problem statement

Our errors currently store the source value of any cast or conversion. We also permit the user to discard this value via `.map_src` methods, which is sometimes necessary in order to play nicely with APIs that require errors to be `'static`, `Send`, or `Sync`.

However, we've also discussed supporting #280 by doing the opposite: by *preventing* the user from discarding the source, we can use an error object as a witness that an error was encountered *with a particular source type*, and thus as a witness that certain failure modes are impossible (in particular, when casting from `Src` to `Dst` where `Src` is more aligned than `Dst`, alignment errors are impossible).

### Design

These two goals are at odds, but I think we can reconcile them. We do this by storing both the *original* source type and a source *value*.

```rust
pub struct AlignmentError {
/// The source value involved in the conversion.
src_val: SrcVal,
/// The inner destination type inolved in the conversion.
///
/// INVARIANT: An `AlignmentError` may only be constructed if `Dst`'s
/// alignment requirement is greater `Src`'s alignment requirement.
src_dst: SendSyncPhantomData<(Src, Dst)>,
}

impl AlignmentError {
pub fn map_src(self, f: impl Fn(SrcVal) -> NewSrcVal) -> AlignmentError {
AlignmentError { src_val: f(self.src_val), src_dst: SendSyncPhantomData::default() }
}
}
```

With this change, we can require that both `Src` and `Dst` are the actual types involved in a cast, and thus we can make the internal invariant more powerful. As it stands today, the invariant is that:

https://github.com/google/zerocopy/blob/0b8ad3ea2719acb1485dc1e622926c61dbc7af99/src/error.rs#L237-L238

With this change, we generalize the invariant to require that `Dst`'s alignment is greater than `Src`'s alignment.

### Use

In theory, this should let us infallibly discard alignment errors in more circumstances, generalizing our current support:

https://github.com/google/zerocopy/blob/0b8ad3ea2719acb1485dc1e622926c61dbc7af99/src/error.rs#L720-L769

However, this requires being able to express alignment inequality as a type-level bound (e.g. via #1316), which we don't yet support.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.