-
Notifications
You must be signed in to change notification settings - Fork 105
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Makes progress on #1931 gherrit-pr-id: Icc9b6841e66c961989862ff6fb3b4f5140c54513
- Loading branch information
Showing
4 changed files
with
121 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
<!-- Copyright 2024 The Fuchsia Authors | ||
Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0 | ||
<LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT | ||
license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option. | ||
This file may not be copied, modified, or distributed except according to | ||
those terms. | ||
WARNING: DO NOT EDIT THIS FILE. It is generated automatically. Edits should be | ||
made in the doc comment on `src/lib.rs` or in `tools/generate-readme`. | ||
--> | ||
|
||
# unsafe-fields | ||
|
||
Support for unsafe fields. | ||
|
||
This crate provides the `unsafe_fields!` macro, which can be used to mark | ||
fields as unsafe. Unsafe fields automatically have their types wrapped using | ||
the `Unsafe` wrapper type. An `Unsafe` is intended to be used to for | ||
struct, enum, or union fields which carry safety invariants. All accessors | ||
are `unsafe`, which requires any use of an `Unsafe` field to be inside an | ||
`unsafe` block. One exception is `Unsafe::as_ref`, which is available when | ||
the `zerocopy_0_8` feature is enabled. See its docs for more information. | ||
|
||
An unsafe field has the type `Unsafe<O, F, const NAME_HASH: u128>`. `O` is | ||
the enclosing type (struct, enum, or union), `F` is the type of the field, | ||
and `NAME_HASH` is the hash of the field's name. `O` prevents swapping | ||
unsafe fields of the same `F` type between different enclosing types, and | ||
`NAME_HASH` prevents swapping different fields of the same `F` type within | ||
the same enclosing type. Note that swapping the same field between instances | ||
of the same type [cannot be prevented](crate#limitations). | ||
|
||
[immutable]: zerocopy_0_8::Immutable | ||
|
||
## Examples | ||
|
||
```rust | ||
use unsafe_fields::{unsafe_fields, Unsafe}; | ||
|
||
unsafe_fields! { | ||
/// A `usize` which is guaranteed to be even. | ||
pub struct EvenUsize { | ||
// INVARIANT: `n` is even. | ||
#[unsafe] | ||
n: usize, | ||
} | ||
} | ||
|
||
impl EvenUsize { | ||
/// Constructs a new `EvenUsize`. | ||
/// | ||
/// Returns `None` if `n` is odd. | ||
pub fn new(n: usize) -> Option<EvenUsize> { | ||
if n % 2 != 0 { | ||
return None; | ||
} | ||
// SAFETY: We just confirmed that `n` is even. | ||
let n = unsafe { Unsafe::new(n) }; | ||
Some(EvenUsize { n }) | ||
} | ||
} | ||
``` | ||
|
||
Attempting to swap unsafe fields of the same type is prevented: | ||
|
||
```compile_fail,E0308 | ||
use unsafe_fields::{unsafe_fields, Unsafe}; | ||
unsafe_fields! { | ||
/// A range. | ||
pub struct Range { | ||
// INVARIANT: `lo <= hi`. | ||
#[unsafe] | ||
lo: usize, | ||
#[unsafe] | ||
hi: usize, | ||
} | ||
} | ||
impl Range { | ||
pub fn swap(&mut self) { | ||
// ERROR: Mismatched types | ||
core::mem::swap(&mut self.lo, &mut self.hi); | ||
} | ||
} | ||
``` | ||
|
||
## Limitations | ||
|
||
Note that we cannot prevent `Unsafe`s from being swapped between the same | ||
field in instances of the same type: | ||
|
||
```rust | ||
use unsafe_fields::{unsafe_fields, Unsafe}; | ||
|
||
unsafe_fields! { | ||
/// A `usize` which is guaranteed to be even. | ||
pub struct EvenUsize { | ||
// INVARIANT: `n` is even. | ||
#[unsafe] | ||
n: usize, | ||
} | ||
} | ||
|
||
pub fn swap(a: &mut EvenUsize, b: &mut EvenUsize) { | ||
core::mem::swap(&mut a.n, &mut b.n); | ||
} | ||
``` | ||
|
||
## Disclaimer | ||
|
||
Disclaimer: Zerocopy is not an officially supported Google product. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters