Skip to content

Commit 20f20ef

Browse files
authored
NonZeroI32 does not have unsafe values (#3)
Fixes #1
1 parent e0403bd commit 20f20ef

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

src/what-is-unsafe.md

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,21 @@ behind the definition of `Foo`. We have to introduce the anonymous type on `Foo`
8181
thing visible, and add those unsafe values.
8282

8383
It is also possible for a custom type definition to have an anonymous type. This is for example the
84-
case of `NonZeroI32`. Its definition is an anonymous type on `i32` removing the safe value zero. The
85-
safety invariant of `NonZeroI32` thus doesn't contain zero, making zero an unsafe value for that
86-
type. One may want to add this unsafe value for some specific occurrences of `NonZeroI32`, requiring
87-
again anonymous types to add unsafe values. This time it's not only because the definition is
88-
hidden, but also because we want to revert the effect of an anonymous type adding back a value that
89-
was removed.
84+
case of `Vec<i32>`. Its simplified definition is an anonymous type on `{ ptr: *mut i32, len: usize,
85+
cap: usize }` removing some safe values. We'll focus on the safe values where not all of the first
86+
`len` elements pointed by `ptr` are initialized. The safety invariant of `Vec<i32>` thus doesn't
87+
contain those (otherwise safe) values, making a pointer to uninitialized data with non-zero length
88+
an unsafe value for that type. One may want to add those unsafe values for some specific occurrences
89+
of `Vec<i32>`, requiring again an anonymous type. This time it's not only because the definition is
90+
hidden, but also because we want to revert the effect of an anonymous type adding back values that
91+
were removed.
92+
93+
Note that, while anonymous types in custom types define a new safety invariant, it is also possible
94+
to define custom types with a different validity invariant using rustc annotations. For example,
95+
`NonZeroI32` has the value zero removed from both the safety invariant and the validity invariant.
96+
This type doesn't have any unsafe value. It is thus not possible to create an unsafe version of that
97+
type. If you would remove the rustc annotations and keep the anonymous type, then zero would not be
98+
safe but still be valid, and thus it would be an unsafe value that can be added to create an unsafe
99+
version of that type.
90100

91101
[two-invariants]: https://www.ralfj.de/blog/2018/08/22/two-kinds-of-invariants.html

0 commit comments

Comments
 (0)