From c9fd3d4f91abeacc5be5155e5f584dac4e8273d9 Mon Sep 17 00:00:00 2001 From: Andrew Paseltiner Date: Thu, 31 Dec 2015 15:17:50 -0500 Subject: [PATCH] Make `LinkedList` and its read-only iterators covariant CC #30642 --- src/libcollections/lib.rs | 2 +- src/libcollections/linked_list.rs | 20 ++++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 000ec4f0f6610..370857287d6e6 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -46,7 +46,7 @@ #![feature(num_bits_bytes)] #![feature(oom)] #![feature(pattern)] -#![feature(ptr_as_ref)] +#![feature(shared)] #![feature(slice_bytes)] #![feature(slice_patterns)] #![feature(staged_api)] diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs index 631857f8e3c56..1bd5a83d43708 100644 --- a/src/libcollections/linked_list.rs +++ b/src/libcollections/linked_list.rs @@ -27,7 +27,7 @@ use core::fmt; use core::hash::{Hasher, Hash}; use core::iter::FromIterator; use core::mem; -use core::ptr; +use core::ptr::Shared; /// A doubly-linked list. #[stable(feature = "rust1", since = "1.0.0")] @@ -40,7 +40,7 @@ pub struct LinkedList { type Link = Option>>; struct Rawlink { - p: *mut T, + p: Option>, } impl Copy for Rawlink {} @@ -93,12 +93,12 @@ pub struct IntoIter { impl Rawlink { /// Like Option::None for Rawlink fn none() -> Rawlink { - Rawlink { p: ptr::null_mut() } + Rawlink { p: None } } /// Like Option::Some for Rawlink fn some(n: &mut T) -> Rawlink { - Rawlink { p: n } + unsafe { Rawlink { p: Some(Shared::new(n)) } } } /// Convert the `Rawlink` into an Option value @@ -108,7 +108,7 @@ impl Rawlink { /// - Dereference of raw pointer. /// - Returns reference of arbitrary lifetime. unsafe fn resolve<'a>(&self) -> Option<&'a T> { - self.p.as_ref() + self.p.map(|p| &**p) } /// Convert the `Rawlink` into an Option value @@ -118,7 +118,7 @@ impl Rawlink { /// - Dereference of raw pointer. /// - Returns reference of arbitrary lifetime. unsafe fn resolve_mut<'a>(&mut self) -> Option<&'a mut T> { - self.p.as_mut() + self.p.map(|p| &mut **p) } /// Return the `Rawlink` and replace with `Rawlink::none()` @@ -984,6 +984,14 @@ impl Hash for LinkedList { } } +// Ensure that `LinkedList` and its read-only iterators are covariant in their type parameters. +#[allow(dead_code)] +fn assert_covariance() { + fn a<'a>(x: LinkedList<&'static str>) -> LinkedList<&'a str> { x } + fn b<'i, 'a>(x: Iter<'i, &'static str>) -> Iter<'i, &'a str> { x } + fn c<'a>(x: IntoIter<&'static str>) -> IntoIter<&'a str> { x } +} + #[cfg(test)] mod tests { use std::clone::Clone;