experiment with a high-res version of the image
[web.git] / personal / _posts / 2018-08-22-two-kinds-of-invariants.md
index c54a0101833990a2b889f8a4109e6d86dbafe58c..fcf12ea1394dcea6b7c699d86e624f74c2ef1040 100644 (file)
@@ -72,7 +72,7 @@ For `Vec` to work, however, `ptr` will be pointing to valid memory of size `cap
 This is an invariant that all the unsafe code implementing `Vec` maintains, and it is the invariant that the safe API surface of `Vec` expects the outside world to uphold.
 The reason this works is that the fields mentioned in this invariant are all private, so safe code cannot break the invariant and use that broken invariant to cause havoc.
 Again, the safety invariant is about ensuring safe execution of safe code.
-Unsafe code can of course break this invariant, but then it us just Doing It Wrong (TM).
+Unsafe code can of course break this invariant, but then it is just Doing It Wrong (TM).
 
 Thanks to privacy and an abstraction barrier, types in Rust can define *their own safety invariant*, and they can then expect the outside world to respect that invariant.
 As we have seen with `Vec`, when generic types are involved, these custom safety invariants will often have a "structural" element in that being safe at `Vec<T>` is defined in terms of being safe at `T`.
@@ -185,7 +185,7 @@ My gut feeling is that it should not be (i.e., validity should require that `i32
 I have talked about two kinds of invariants that come with every type, the safety invariant and the validity invariant.
 For unsafe code authors, the slogan summarizing this post is:
 
-> *You must always be valid, but you must only be safe in safe code.*
+> *You must always be valid, but you only must be safe in safe code.*
 
 I think we have enough experience writing unsafe code at this point that we can reasonably discuss which validity invariants make sense and which do not -- and I think that it is high time that we do so, because many unsafe code authors are wondering about these exact things all the time.