-// Rust-101, Part 11: Trait Objects, Box (WIP)
-// ===========================================
-
-//@ Now that we know about closures, let's have some fun with them. We will try to implement some kind of generic "callback"
-//@ mechanism, providing two functions: Registering a new callback, and calling all registered callbacks. There will be two
-//@ versions, so to avoid clashes of names, we put them into modules.
+// Rust-101, Part 11: Trait Objects, Box, Lifetime bounds
+// ======================================================
+
+//@ We will play around with closures a bit more. Let us implement some kind of generic "callback"
+//@ mechanism, providing two functions: Registering a new callback, and calling all registered callbacks.
+
+//@ First of all, we need to find a way to store the callbacks. Clearly, there will be a `Vec` involved, so that we can
+//@ always grow the number of registered callbacks. A callback will be a closure, i.e., something implementing
+//@ `FnMut(i32)` (we want to call this multiple times, so clearly `FnOnce` would be no good). So our first attempt may be the following.
+// For now, we just decide that the callbacks have an argument of type `i32`.
+struct CallbacksV1<F: FnMut(i32)> {
+ callbacks: Vec<F>,
+}
+//@ However, this will not work. Remember how the "type" of a closure is specific to the environment of captured variables. Different closures
+//@ all implementing `FnMut(i32)` may have different types. However, a `Vec<F>` is a *uniformly typed* vector.
+
+//@ We will thus need a way to store things of *different* types in the same vector. We know all these types implement `FnMut(i32)`. For this scenario,
+//@ Rust provides *trait objects*: The truth is, `FnMut(i32)` is not just a trait. It is also a type, that can be given to anything implementing
+//@ this trait. So, we may write the following.
+/* struct CallbacksV2 {
+ callbacks: Vec<FnMut(i32)>,
+} */
+//@ But, Rust complains about this definition. It says something about "Sized". What's the trouble? See, for many things we want to do, it is crucial that
+//@ Rust knows the precise, fixed size of the type - that is, how large this type will be when represented in memory. For example, for a `Vec`, the
+//@ elements are stored one right after the other. How should that be possible, without a fixed size? The point is, `FnMut(i32)` could be of any size.
+//@ We don't know how large that "type that implements `FnMut(i32)`" is. Rust calls this an *unsized* type. Whenever we introduce a type variable, Rust
+//@ will implicitly add a bound to that variable, demanding that it is sized. That's why we did not have to worry about this so far. <br/>
+//@ You can opt-out of this implicit bound by saying `T: ?Sized`. Then `T` may or may not be sized.
+
+//@ So, what can we do, if we can't store the callbacks in a vector? We can put them in a box. Semantically, `Box<T>` is a lot like `T`: You fully own
+//@ the data stored there. On the machine, however, `Box<T>` is a *pointer* to a heap-allocated `T`. It is a lot like `std::unique_ptr` in C++. In our current example,
+//@ the important bit is that since it's a pointer, `T` can be unsized, but `Box<T>` itself will always be sized. So we can put it in a `Vec`.
+pub struct Callbacks {
+ callbacks: Vec<Box<FnMut(i32)>>,
+}