Skip to content

Commit 0fae530

Browse files
authored
[unsafe-fields] Add README.md (#1961)
Release 0.2.1. Makes progress on #1931 gherrit-pr-id: Icc9b6841e66c961989862ff6fb3b4f5140c54513
1 parent 60a7497 commit 0fae530

File tree

6 files changed

+126
-7
lines changed

6 files changed

+126
-7
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,4 +201,4 @@ Zerocopy uses [GitHub Releases].
201201

202202
## Disclaimer
203203

204-
Disclaimer: Zerocopy is not an officially supported Google product.
204+
Disclaimer: This is not an officially supported Google product.

ci/check_readme.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@ set -eo pipefail
1616
cargo install -q cargo-readme --version 3.2.0
1717

1818
diff <(cargo -q run --manifest-path tools/Cargo.toml -p generate-readme) README.md >&2
19-
exit $?
19+
20+
cd unsafe-fields
21+
diff <(cargo -q run --manifest-path ../tools/Cargo.toml -p generate-readme) README.md >&2

tools/generate-readme/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ made in the doc comment on `src/lib.rs` or in `tools/generate-readme`.
2727
const DISCLAIMER_FOOTER: &str = "\
2828
## Disclaimer
2929
30-
Disclaimer: Zerocopy is not an officially supported Google product.\
30+
Disclaimer: This is not an officially supported Google product.\
3131
";
3232

3333
fn main() {

unsafe-fields/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
[package]
1010
name = "unsafe-fields"
11-
version = "0.2.0"
11+
version = "0.2.1"
1212
edition = "2021"
1313
description = "Make it unsafe to access or modify fields with safety invariants"
1414
license = "BSD-2-Clause OR Apache-2.0 OR MIT"

unsafe-fields/README.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<!-- Copyright 2024 The Fuchsia Authors
2+
3+
Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
4+
<LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
5+
license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
6+
This file may not be copied, modified, or distributed except according to
7+
those terms.
8+
9+
WARNING: DO NOT EDIT THIS FILE. It is generated automatically. Edits should be
10+
made in the doc comment on `src/lib.rs` or in `tools/generate-readme`.
11+
-->
12+
13+
# unsafe-fields
14+
15+
Support for unsafe fields.
16+
17+
This crate provides the `unsafe_fields!` macro, which can be used to mark
18+
fields as unsafe. Unsafe fields automatically have their types wrapped using
19+
the `Unsafe` wrapper type. An `Unsafe` is intended to be used to for
20+
struct, enum, or union fields which carry safety invariants. All accessors
21+
are `unsafe`, which requires any use of an `Unsafe` field to be inside an
22+
`unsafe` block. One exception is `Unsafe::as_ref`, which is available when
23+
the `zerocopy_0_8` feature is enabled. See its docs for more information.
24+
25+
An unsafe field has the type `Unsafe<O, F, const NAME_HASH: u128>`. `O` is
26+
the enclosing type (struct, enum, or union), `F` is the type of the field,
27+
and `NAME_HASH` is the hash of the field's name. `O` prevents swapping
28+
unsafe fields of the same `F` type between different enclosing types, and
29+
`NAME_HASH` prevents swapping different fields of the same `F` type within
30+
the same enclosing type. Note that swapping the same field between instances
31+
of the same type [cannot be prevented](crate#limitations).
32+
33+
[immutable]: zerocopy_0_8::Immutable
34+
35+
## Examples
36+
37+
```rust
38+
use unsafe_fields::{unsafe_fields, Unsafe};
39+
40+
unsafe_fields! {
41+
/// A `usize` which is guaranteed to be even.
42+
pub struct EvenUsize {
43+
// INVARIANT: `n` is even.
44+
#[unsafe]
45+
n: usize,
46+
}
47+
}
48+
49+
impl EvenUsize {
50+
/// Constructs a new `EvenUsize`.
51+
///
52+
/// Returns `None` if `n` is odd.
53+
pub fn new(n: usize) -> Option<EvenUsize> {
54+
if n % 2 != 0 {
55+
return None;
56+
}
57+
// SAFETY: We just confirmed that `n` is even.
58+
let n = unsafe { Unsafe::new(n) };
59+
Some(EvenUsize { n })
60+
}
61+
}
62+
```
63+
64+
Attempting to swap unsafe fields of the same type is prevented:
65+
66+
```rust,compile_fail,E0308
67+
use unsafe_fields::{unsafe_fields, Unsafe};
68+
69+
unsafe_fields! {
70+
/// A range.
71+
pub struct Range {
72+
// INVARIANT: `lo <= hi`.
73+
#[unsafe]
74+
lo: usize,
75+
#[unsafe]
76+
hi: usize,
77+
}
78+
}
79+
80+
impl Range {
81+
pub fn swap(&mut self) {
82+
// ERROR: Mismatched types
83+
core::mem::swap(&mut self.lo, &mut self.hi);
84+
}
85+
}
86+
```
87+
88+
## Limitations
89+
90+
Note that we cannot prevent `Unsafe`s from being swapped between the same
91+
field in instances of the same type:
92+
93+
```rust
94+
use unsafe_fields::{unsafe_fields, Unsafe};
95+
96+
unsafe_fields! {
97+
/// A `usize` which is guaranteed to be even.
98+
pub struct EvenUsize {
99+
// INVARIANT: `n` is even.
100+
#[unsafe]
101+
n: usize,
102+
}
103+
}
104+
105+
pub fn swap(a: &mut EvenUsize, b: &mut EvenUsize) {
106+
core::mem::swap(&mut a.n, &mut b.n);
107+
}
108+
```
109+
110+
## Disclaimer
111+
112+
Disclaimer: This is not an officially supported Google product.

unsafe-fields/src/lib.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
// This file may not be copied, modified, or distributed except according to
77
// those terms.
88

9+
// After updating the following doc comment, make sure to run the following
10+
// command to update `README.md` based on its contents:
11+
//
12+
// cargo -q run --manifest-path ../tools/Cargo.toml -p generate-readme > README.md
13+
914
//! Support for unsafe fields.
1015
//!
1116
//! This crate provides the [`unsafe_fields!`] macro, which can be used to mark
@@ -28,7 +33,7 @@
2833
//!
2934
//! # Examples
3035
//!
31-
//! ```
36+
//! ```rust
3237
//! use unsafe_fields::{unsafe_fields, Unsafe};
3338
//!
3439
//! unsafe_fields! {
@@ -57,7 +62,7 @@
5762
//!
5863
//! Attempting to swap unsafe fields of the same type is prevented:
5964
//!
60-
//! ```compile_fail,E0308
65+
//! ```rust,compile_fail,E0308
6166
//! use unsafe_fields::{unsafe_fields, Unsafe};
6267
//!
6368
//! unsafe_fields! {
@@ -84,7 +89,7 @@
8489
//! Note that we cannot prevent `Unsafe`s from being swapped between the same
8590
//! field in instances of the same type:
8691
//!
87-
//! ```
92+
//! ```rust
8893
//! use unsafe_fields::{unsafe_fields, Unsafe};
8994
//!
9095
//! unsafe_fields! {

0 commit comments

Comments
 (0)