rust-unofficial / too-many-lists

Learn Rust by writing Entirely Too Many linked lists
https://rust-unofficial.github.io/too-many-lists/
MIT License
3.16k stars 276 forks source link

In [7.2 Variance and Subtyping], we can add a simple function to prove that `LinkedList<T>` is covariant over `T`, and `type Link<T> = *mut Node<T>` is not like so #259

Open viruscamp opened 1 year ago

viruscamp commented 1 year ago

In 7.2 Variance and Subtyping , we can add a simple function to prove that LinkedList<T> is covariant over T.

use too_many_linked_list::unsafe_deque::LinkedList;
fn ensure_covariant<'long: 'short, 'short>(list_long: LinkedList<&'long i32>, mut list_short: LinkedList<&'short i32>) {
    let list_short_new: LinkedList<&'short i32> = list_long; // to prove `LinkedList<T>` is covariant over `T`
    //let list_long_new: LinkedList<&'long i32> = list_short; // to prove `LinkedList<T>` is contravariant over `T`
}
/// We can prove that `LinkedList<T>` is covariant over `T`.
/// ```no_run
/// # use too_many_linked_list::unsafe_deque::LinkedList;
/// fn ensure_covariant<'long: 'short, 'short>(list_long: LinkedList<&'long i32>, mut list_short: LinkedList<&'short i32>) {
///     let list_short_new: LinkedList<&'short i32> = list_long; // to prove `LinkedList<T>` is covariant over `T`
/// }
/// ```
type Link<T> = Option<NonNull<Node<T>>>;
/// We cannot prove that `LinkedList<T>` is covariant over `T`, if we use `type Link<T> = *mut Node<T>;`
/// ```compile_fail
/// # use too_many_linked_list::unsafe_deque::ptr_mut::LinkedList;
/// fn ensure_covariant<'long: 'short, 'short>(list_long: LinkedList<&'long i32>, mut list_short: LinkedList<&'short i32>) {
///     let list_short_new: LinkedList<&'short i32> = list_long; // to prove `LinkedList<T>` is covariant over `T`
/// }
/// ```
/// compiler errors:
///    = note: requirement occurs because of the type `ptr_mut::LinkedList<&i32>`, which makes the generic argument `&i32` invariant
///    = note: the struct `ptr_mut::LinkedList<T>` is invariant over the parameter `T`
type Link<T> = *mut Node<T>;