You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/subtyping.md
+57-4
Original file line number
Diff line number
Diff line change
@@ -120,7 +120,7 @@ fn main() {
120
120
let world = String::from("world");
121
121
assign(&mut hello, &world);
122
122
}
123
-
println!("{}", hello);
123
+
println!("{}", hello); // use after free 😿
124
124
}
125
125
```
126
126
@@ -258,9 +258,24 @@ So the compiler decides that `&'static str` can become `&'b str` if and only if
258
258
`&'static str` is a subtype of `&'b str`, which will hold if `'static: 'b`.
259
259
This is true, so the compiler is happy to continue compiling this code.
260
260
261
-
`Box<T>` is also *covariant* over `T`. This would make sense, since it's supposed to be
262
-
usable the same as `&T`. If you try to mutate the box, you'll need a `&mut Box<T>` and the
263
-
invariance of `&mut` will kick in here.
261
+
As it turns out, the argument for why it's ok for Box (and Vec, Hashmap, etc.) to be covariant is pretty similar to the argument for why it's ok for lifetimes to be covariant: as soon as you try to stuff them in something like a mutable reference, they inherit invariance and you're prevented from doing anything bad.
262
+
263
+
However Box makes it easier to focus on by-value aspect of references that we partially glossed over.
264
+
265
+
Unlike a lot of languages which allow values to be freely aliased at all times, Rust has a very strict rule: if you're allowed to mutate or move a value, you are guaranteed to be the only one with access to it.
266
+
267
+
Consider the following code:
268
+
269
+
```rust,ignore
270
+
let hello: Box<&'static str> = Box::new("hello");
271
+
272
+
let mut world: Box<&'b str>;
273
+
world = hello;
274
+
```
275
+
276
+
There is no problem at all with the fact that we have forgotten that `hello` was alive for `'static`,
277
+
because as soon as we moved `hello` to a variable that only knew he it was alive for `'b`,
278
+
**we destroyed the only thing in the universe that remembered it lived for longer**!
264
279
265
280
Only one thing left to explain: function pointers.
266
281
@@ -303,6 +318,44 @@ Covariance doesn't work here. But if we flip it around, it actually *does*
303
318
work! If we need a function that can handle `&'static str`, a function that can handle *any* reference lifetime
0 commit comments