]> git.lizzy.rs Git - rust.git/commitdiff
Make `LinkedList` and its read-only iterators covariant
authorAndrew Paseltiner <apaseltiner@gmail.com>
Thu, 31 Dec 2015 20:17:50 +0000 (15:17 -0500)
committerAndrew Paseltiner <apaseltiner@gmail.com>
Thu, 31 Dec 2015 20:22:22 +0000 (15:22 -0500)
CC #30642

src/libcollections/lib.rs
src/libcollections/linked_list.rs

index 000ec4f0f66105a67f4707ab0c457fd9b5ddc0d9..370857287d6e6aea59368b200ddd79eca66b0e21 100644 (file)
@@ -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)]
index 631857f8e3c56e472d7cf6e706f04ad9631c4a45..1bd5a83d4370860223f13966ab449a006369b14f 100644 (file)
@@ -27,7 +27,7 @@
 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<T> {
 type Link<T> = Option<Box<Node<T>>>;
 
 struct Rawlink<T> {
-    p: *mut T,
+    p: Option<Shared<T>>,
 }
 
 impl<T> Copy for Rawlink<T> {}
@@ -93,12 +93,12 @@ pub struct IntoIter<T> {
 impl<T> Rawlink<T> {
     /// Like Option::None for Rawlink
     fn none() -> Rawlink<T> {
-        Rawlink { p: ptr::null_mut() }
+        Rawlink { p: None }
     }
 
     /// Like Option::Some for Rawlink
     fn some(n: &mut T) -> Rawlink<T> {
-        Rawlink { p: n }
+        unsafe { Rawlink { p: Some(Shared::new(n)) } }
     }
 
     /// Convert the `Rawlink` into an Option value
@@ -108,7 +108,7 @@ fn some(n: &mut T) -> Rawlink<T> {
     /// - 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 @@ unsafe fn resolve<'a>(&self) -> Option<&'a T> {
     /// - 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 @@ fn hash<H: Hasher>(&self, state: &mut H) {
     }
 }
 
+// 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;