X-Git-Url: https://git.ralfj.de/rust-101.git/blobdiff_plain/1a691352b57b7338388ff568403495ecb44272eb..501b20b712b2e5c176ca581232970e1e74d62ab0:/src/part16.rs diff --git a/src/part16.rs b/src/part16.rs index fefccdf..c02959d 100644 --- a/src/part16.rs +++ b/src/part16.rs @@ -43,19 +43,19 @@ type NodePtr = *mut Node; // will own data of type `T`. //@ The type `PhantomData` does not actually store anything in memory - it has size zero. However, logically, //@ Rust will consider a `T` to be present. In this case, Rust knows that data of type `T` may be dropped -//@ whenever a `LinkedList` is dropped. The checks involving destructors are pretty subtle, so it's always -//@ a good idea to provide such extra information. In safe Rust, this can all be done automatically, but here, -//@ we just have a `*mut Node`, which Rust does not consider as actually owning the data it points to. +//@ whenever a `LinkedList` is dropped. Dropping has a lot of subtle checks to it, making sure that things can't go +//@ wrong. For this to work, Rust needs to know which types could potentially be dropped. In safe Rust, this can all be inferred +//@ automatically, but here, we just have a `*mut Node`, and we need to tell Rust that we actually own such data and will drop it. +//@ (For more of the glory details, see [this RFC](https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md).) pub struct LinkedList { first: NodePtr, last: NodePtr, _marker: PhantomData, } -//@ Before we get to the actual linked-list methods, we write two short helper functions converting between -//@ mutable raw pointers, and owned pointers (aka `Box`). Both employ `mem::transmute`, which is Rust's -//@ `reinterpret_cast`: It can convert anything to anything, by just re-interpreting the bytes. Clearly, -//@ that's an unsafe operation and must only be used with great care. If at all possible, its use should be avoided.
+//@ Before we get to the actual linked-list methods, we write two short helper functions converting between mutable raw pointers, +//@ and boxed data. Both employ `mem::transmute`, which can convert anything to anything, by just re-interpreting the bytes. +//@ Clearly, that's an unsafe operation and must only be used with great care - or even better, not at all.
//@ We are making the assumption here that a `Box` and a raw pointer have the same representation in memory. In the future, //@ Rust will [provide](http://doc.rust-lang.org/beta/alloc/boxed/struct.Box.html#method.from_raw) such [operations](http://doc.rust-lang.org/beta/alloc/boxed/struct.Box.html#method.into_raw) in the standard library, but the exact API is still being fleshed out. @@ -166,7 +166,7 @@ impl<'a, T> Iterator for IterMut<'a, T> { //@ The linked list we wrote is already working quite nicely, but there is one problem: When the list is dropped, //@ nobody bothers to deallocate the remaining nodes. Even worse, if `T` itself has a destructor that needs to //@ clean up, it is not called for the element remaining in the list. We need to take care of that ourselves. -//@ + //@ In Rust, adding a destructor for a type is done by implementing the `Drop` trait. This is a very special trait. //@ It can only be implemented for *nominal types*, i.e., you cannot implement `Drop` for `&mut T`. You also cannot //@ restrict the type and lifetime parameters further than the type does - the `Drop` implementation has to apply to *all* instances