add link to the rustonomicon example
[web.git] / personal / _posts / 2016-01-09-the-scope-of-unsafe.md
index 6c69d0970e524d3b7377e9e992f4a06779e4b89c..0bbdcfbaf5db7bc85f57bc448d7a81ace1943bd1 100644 (file)
@@ -35,7 +35,7 @@ Roughly speaking, `ptr` points to the heap-allocated block of memory holding the
 It is very easy to add a function to `Vec` that contains no `unsafe` code, and still breaks the safety of the data structure:
 {% highlight rust %}
 impl Vec<T> {
-    fn evil(&mut self) {
+    pub fn evil(&mut self) {
         self.len += 2;
     }
 }
@@ -59,7 +59,7 @@ More precisely speaking, `ptr` points to an array of type `T` and size `cap`, of
 The function `evil` above violates this invariant, while all the functions actually provided by `Vec` (including the ones that are implemented unsafely) preserve the invariant.
 That's why `evil` is the bad guy. (The name kind of gave it away, didn't it?)
 
-This may seem obvious in hindsight, but I think it is actually fairly subtle.
+This may seem obvious in hindsight (and it is also [discussed in the Rustonomicon](https://doc.rust-lang.org/nightly/nomicon/working-with-unsafe.html)), but I think it is actually fairly subtle.
 There used to be claims on the interwebs that "if a Rust program crashes, the bug must be in some `unsafe` block". (And there probably still are.)
 Even academic researchers working on Rust got this wrong, arguing that in order to detect bugs in data structures like `Vec` it suffices to check functions involving unsafe code.
 That's why I think it's worth dedicating an entire blog post to this point.
@@ -82,7 +82,7 @@ pub struct MyType<T> {
 We will define only one function for this type:
 {% highlight rust %}
 impl MyType<T> {
-    fn evil(&mut self) {
+    pub fn evil(&mut self) {
         self.len += 2;
     }
 }