Make LinkedList and its read-only iterators covariant

CC #30642
This commit is contained in:
Andrew Paseltiner 2015-12-31 15:17:50 -05:00
parent 8aee5826f9
commit c9fd3d4f91
2 changed files with 15 additions and 7 deletions

View 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)]

View 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;