Skip to content

Commit 2fb3d0c

Browse files
committed
minor fixes and clarification on semver
1 parent 21e5431 commit 2fb3d0c

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

text/0000-safety-tags.md

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ requirement into a single, check-off reminder.
1515
The following snippet [compiles] today if we enable enough nightly features, but we expect Clippy
1616
and Rust-Analyzer to enforce tag checks and provide first-class IDE support.
1717

18-
[compiles]: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=6eb0e47c416953da1f2470b11417e69a
18+
[compiles]: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=322dbd93610aca05db49382802c732c3
1919

2020
```rust
2121
#[safety::requires { // 💡 define safety tags on an unsafe function
@@ -100,9 +100,9 @@ ad-hoc practice with four concrete gains:
100100
2. **Versioned invariants**. Tags are a part of API; any change to their definition is a
101101
*semver-breaking* API change, so safety invariants evolve explicitly.
102102

103-
3. **Semantic granularity**. Tags must label a single unsafe call, or an expression contains single
104-
unsafe call. No longer constrained by the visual boundaries of `unsafe {}`. This sidesteps the
105-
precision vs completeness tension of unsafe blocks, and zeros in on real unsafe operations.
103+
3. **Semantic granularity**. Tags must label a single unsafe call, or an expression containing
104+
single unsafe call. No longer constrained by the visual boundaries of `unsafe {}`. This sidesteps
105+
the precision vs completeness tension of unsafe blocks, and zeros in on real unsafe operations.
106106
* It's viable to extend tagging to [more unsafe operations] beyond unsafe calls.
107107
* To enable truly semantic checking, we envision an [entity-reference] system that meticulously
108108
traces every unsafe related operation that could break an invariant in source code.
@@ -220,7 +220,7 @@ unsafe fn propogation<T>(ptr: *const T) -> T {
220220
Tags defined on an unsafe function must be **fully** discharged at callsites. No partial discharge:
221221

222222
```rust
223-
#[safety::requires { ValidPtr = "...", Aligned = "...", Initialized = "..." }]
223+
#[safety::requires { ValidPtr = "...", Initialized = "..." }]
224224
unsafe fn delegation<T>(ptr: *const T) -> T {
225225
#[safety::checked { Aligned }] // 💥 Error: Tags are not fully discharged.
226226
unsafe { read(ptr) }
@@ -270,12 +270,18 @@ against [Semantic Versioning][semver].
270270
* Adding a tag definition is a **major** change, because new tag is missing.
271271
* Removing a tag definition is a **minor** change. The tag doesn't exist anymore, and discharing
272272
an undefined tag just emits a warning-by-default diagnostic.
273-
* Changing the definition of a tag in a way that *requires more*, is a **major** change, because
274-
callsites only checked the weaker requirement for this tag. However, it's strongly discouraged to
275-
change the tag in such way, as newly added requirements may blindly discharged by callsites.
273+
* Renaming a tag definition is a **major** change, because it's the result of removal and addition.
276274
* Changing the definition of a tag in an *equivalent* or in a way that *requires less* (the old tag
277275
implies the new tag), is a **minor** change.
278-
* Renaming a tag definition is a **major** change, because it's the result of removal and addition.
276+
* Changing the definition of a tag in a way that *requires more*, is a **major** change, because
277+
callsites only checked the weaker requirement for this tag.
278+
* However, adding more safety requirements to an existing tag definition is strongly discouraged:
279+
call sites that were blindly compiled against the old definition may unsoundly assume the new,
280+
weaker requirements still hold.
281+
* Instead, replace the tag with a distinct name. This guarantees downstream crates notice the
282+
change. It's a potential hazard to reuse the tag name back in the future, due to the same reason
283+
stated above. Renaming the unsafe function to keep the original tag name for new definition is
284+
also good, because tags are scoped to their defining function.
279285

280286
[semver]: https://doc.rust-lang.org/cargo/reference/semver.html
281287

0 commit comments

Comments
 (0)