From 8e9f8f924cda8193ce1416c45cdcfce35fa6b8d1 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 29 Oct 2014 15:26:29 -0700 Subject: [PATCH] collections: impl Deref for Vec/String This commit adds the following impls: impl Deref<[T]> for Vec impl DerefMut<[T]> for Vec impl Deref for String This commit also removes all duplicated inherent methods from vectors and strings as implementations will now silently call through to the slice implementation. Some breakage occurred at std and beneath due to inherent methods removed in favor of those in the slice traits and std doesn't use its own prelude, cc #18424 --- src/libcollections/str.rs | 69 ----- src/libcollections/string.rs | 5 + src/libcollections/vec.rs | 383 ++---------------------- src/libcoretest/str.rs | 69 +++++ src/libgraphviz/maybe_owned_vec.rs | 2 +- src/libstd/io/comm_adapters.rs | 2 +- src/libstd/io/net/addrinfo.rs | 1 + src/test/compile-fail/unique-vec-res.rs | 8 +- 8 files changed, 102 insertions(+), 437 deletions(-) diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 9cd8bde4a95..7e59111607e 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -1677,40 +1677,6 @@ mod tests { assert_eq!(pos, p.len()); } - #[test] - fn test_split_char_iterator() { - let data = "\nMäry häd ä little lämb\nLittle lämb\n"; - - let split: Vec<&str> = data.split(' ').collect(); - assert_eq!( split, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); - - let mut rsplit: Vec<&str> = data.split(' ').rev().collect(); - rsplit.reverse(); - assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); - - let split: Vec<&str> = data.split(|c: char| c == ' ').collect(); - assert_eq!( split, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); - - let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect(); - rsplit.reverse(); - assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); - - // Unicode - let split: Vec<&str> = data.split('ä').collect(); - assert_eq!( split, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); - - let mut rsplit: Vec<&str> = data.split('ä').rev().collect(); - rsplit.reverse(); - assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); - - let split: Vec<&str> = data.split(|c: char| c == 'ä').collect(); - assert_eq!( split, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); - - let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect(); - rsplit.reverse(); - assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); - } - #[test] fn test_splitn_char_iterator() { let data = "\nMäry häd ä little lämb\nLittle lämb\n"; @@ -1729,28 +1695,6 @@ mod tests { assert_eq!(split, vec!["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]); } - #[test] - fn test_rsplitn_char_iterator() { - let data = "\nMäry häd ä little lämb\nLittle lämb\n"; - - let mut split: Vec<&str> = data.rsplitn(3, ' ').collect(); - split.reverse(); - assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]); - - let mut split: Vec<&str> = data.rsplitn(3, |c: char| c == ' ').collect(); - split.reverse(); - assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]); - - // Unicode - let mut split: Vec<&str> = data.rsplitn(3, 'ä').collect(); - split.reverse(); - assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]); - - let mut split: Vec<&str> = data.rsplitn(3, |c: char| c == 'ä').collect(); - split.reverse(); - assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]); - } - #[test] fn test_split_char_iterator_no_trailing() { let data = "\nMäry häd ä little lämb\nLittle lämb\n"; @@ -1762,19 +1706,6 @@ mod tests { assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb"]); } - #[test] - fn test_rev_split_char_iterator_no_trailing() { - let data = "\nMäry häd ä little lämb\nLittle lämb\n"; - - let mut split: Vec<&str> = data.split('\n').rev().collect(); - split.reverse(); - assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb", ""]); - - let mut split: Vec<&str> = data.split_terminator('\n').rev().collect(); - split.reverse(); - assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb"]); - } - #[test] fn test_words() { let data = "\n \tMäry häd\tä little lämb\nLittle lämb\n"; diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index c44a03b05cd..efe00975f9e 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -744,6 +744,11 @@ impl ops::Slice for String { } } +#[experimental = "waiting on Deref stabilization"] +impl ops::Deref for String { + fn deref<'a>(&'a self) -> &'a str { self.as_slice() } +} + /// Wrapper type providing a `&String` reference via `Deref`. #[experimental] pub struct DerefString<'a> { diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index dd9883ecaae..173f39a3151 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -28,8 +28,7 @@ use core::raw::Slice as RawSlice; use core::uint; use {Mutable, MutableSeq}; -use slice::{MutableOrdSlice, MutableSliceAllocating, CloneableVector}; -use slice::{Items, MutItems}; +use slice::{CloneableVector}; /// An owned, growable vector. /// @@ -464,6 +463,16 @@ impl ops::SliceMut for Vec { } } +#[experimental = "waiting on Deref stability"] +impl ops::Deref<[T]> for Vec { + fn deref<'a>(&'a self) -> &'a [T] { self.as_slice() } +} + +#[experimental = "waiting on DerefMut stability"] +impl ops::DerefMut<[T]> for Vec { + fn deref_mut<'a>(&'a mut self) -> &'a mut [T] { self.as_mut_slice() } +} + #[experimental = "waiting on FromIterator stability"] impl FromIterator for Vec { #[inline] @@ -717,7 +726,7 @@ impl Vec { #[deprecated = "use .extend(other.into_iter())"] #[cfg(stage0)] pub fn push_all_move(&mut self, other: Vec) { - self.extend(other.into_iter()); + self.extend(other.into_iter()); } /// Returns a mutable slice of the elements of `self`. @@ -735,7 +744,7 @@ impl Vec { pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] { unsafe { mem::transmute(RawSlice { - data: self.as_mut_ptr() as *const T, + data: self.ptr as *const T, len: self.len, }) } @@ -809,124 +818,6 @@ impl Vec { &mut self.as_mut_slice()[index] } - /// Returns an iterator over references to the elements of the vector in - /// order. - /// - /// # Example - /// - /// ``` - /// let vec = vec![1i, 2, 3]; - /// for num in vec.iter() { - /// println!("{}", *num); - /// } - /// ``` - #[inline] - pub fn iter<'a>(&'a self) -> Items<'a,T> { - self.as_slice().iter() - } - - /// Returns an iterator over mutable references to the elements of the - /// vector in order. - /// - /// # Example - /// - /// ``` - /// let mut vec = vec![1i, 2, 3]; - /// for num in vec.iter_mut() { - /// *num = 0; - /// } - /// assert_eq!(vec, vec![0i, 0, 0]); - /// ``` - #[inline] - pub fn iter_mut<'a>(&'a mut self) -> MutItems<'a,T> { - self.as_mut_slice().iter_mut() - } - - /// Sorts the vector, in place, using `compare` to compare elements. - /// - /// This sort is `O(n log n)` worst-case and stable, but allocates - /// approximately `2 * n`, where `n` is the length of `self`. - /// - /// # Example - /// - /// ``` - /// let mut v = vec![5i, 4, 1, 3, 2]; - /// v.sort_by(|a, b| a.cmp(b)); - /// assert_eq!(v, vec![1i, 2, 3, 4, 5]); - /// - /// // reverse sorting - /// v.sort_by(|a, b| b.cmp(a)); - /// assert_eq!(v, vec![5i, 4, 3, 2, 1]); - /// ``` - #[inline] - pub fn sort_by(&mut self, compare: |&T, &T| -> Ordering) { - self.as_mut_slice().sort_by(compare) - } - - /// Returns a slice of self spanning the interval [`start`, `end`). - /// - /// # Failure - /// - /// Fails when the slice (or part of it) is outside the bounds of self, or when - /// `start` > `end`. - /// - /// # Example - /// - /// ``` - /// let vec = vec![1i, 2, 3, 4]; - /// assert!(vec[0..2] == [1, 2]); - /// ``` - #[inline] - pub fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [T] { - self[start..end] - } - - /// Returns a slice containing all but the first element of the vector. - /// - /// # Failure - /// - /// Fails when the vector is empty. - /// - /// # Example - /// - /// ``` - /// let vec = vec![1i, 2, 3]; - /// assert!(vec.tail() == [2, 3]); - /// ``` - #[inline] - pub fn tail<'a>(&'a self) -> &'a [T] { - self[].tail() - } - - /// Returns a reference to the last element of a vector, or `None` if it is - /// empty. - /// - /// # Example - /// - /// ``` - /// let vec = vec![1i, 2, 3]; - /// assert!(vec.last() == Some(&3)); - /// ``` - #[inline] - pub fn last<'a>(&'a self) -> Option<&'a T> { - self[].last() - } - - /// Returns a mutable reference to the last element of a vector, or `None` - /// if it is empty. - /// - /// # Example - /// - /// ``` - /// let mut vec = vec![1i, 2, 3]; - /// *vec.last_mut().unwrap() = 4; - /// assert_eq!(vec, vec![1i, 2, 4]); - /// ``` - #[inline] - pub fn last_mut<'a>(&'a mut self) -> Option<&'a mut T> { - self.as_mut_slice().last_mut() - } - /// Removes an element from anywhere in the vector and return it, replacing /// it with the last element. This does not preserve ordering, but is O(1). /// @@ -1035,215 +926,6 @@ impl Vec { } } - /// Returns a mutable slice of `self` between `start` and `end`. - /// - /// # Failure - /// - /// Fails when `start` or `end` point outside the bounds of `self`, or when - /// `start` > `end`. - /// - /// # Example - /// - /// ``` - /// let mut vec = vec![1i, 2, 3, 4]; - /// assert!(vec[mut 0..2] == [1, 2]); - /// ``` - #[inline] - pub fn slice_mut<'a>(&'a mut self, start: uint, end: uint) - -> &'a mut [T] { - self[mut start..end] - } - - /// Returns a mutable slice of `self` from `start` to the end of the `Vec`. - /// - /// # Failure - /// - /// Fails when `start` points outside the bounds of self. - /// - /// # Example - /// - /// ``` - /// let mut vec = vec![1i, 2, 3, 4]; - /// assert!(vec[mut 2..] == [3, 4]); - /// ``` - #[inline] - pub fn slice_from_mut<'a>(&'a mut self, start: uint) -> &'a mut [T] { - self[mut start..] - } - - /// Returns a mutable slice of `self` from the start of the `Vec` to `end`. - /// - /// # Failure - /// - /// Fails when `end` points outside the bounds of self. - /// - /// # Example - /// - /// ``` - /// let mut vec = vec![1i, 2, 3, 4]; - /// assert!(vec[mut ..2] == [1, 2]); - /// ``` - #[inline] - pub fn slice_to_mut<'a>(&'a mut self, end: uint) -> &'a mut [T] { - self[mut ..end] - } - - /// Returns a pair of mutable slices that divides the `Vec` at an index. - /// - /// The first will contain all indices from `[0, mid)` (excluding - /// the index `mid` itself) and the second will contain all - /// indices from `[mid, len)` (excluding the index `len` itself). - /// - /// # Failure - /// - /// Fails if `mid > len`. - /// - /// # Example - /// - /// ``` - /// let mut vec = vec![1i, 2, 3, 4, 5, 6]; - /// - /// // scoped to restrict the lifetime of the borrows - /// { - /// let (left, right) = vec.split_at_mut(0); - /// assert!(left == &mut []); - /// assert!(right == &mut [1, 2, 3, 4, 5, 6]); - /// } - /// - /// { - /// let (left, right) = vec.split_at_mut(2); - /// assert!(left == &mut [1, 2]); - /// assert!(right == &mut [3, 4, 5, 6]); - /// } - /// - /// { - /// let (left, right) = vec.split_at_mut(6); - /// assert!(left == &mut [1, 2, 3, 4, 5, 6]); - /// assert!(right == &mut []); - /// } - /// ``` - #[inline] - pub fn split_at_mut<'a>(&'a mut self, mid: uint) -> (&'a mut [T], &'a mut [T]) { - self[mut].split_at_mut(mid) - } - - /// Reverses the order of elements in a vector, in place. - /// - /// # Example - /// - /// ``` - /// let mut v = vec![1i, 2, 3]; - /// v.reverse(); - /// assert_eq!(v, vec![3i, 2, 1]); - /// ``` - #[inline] - pub fn reverse(&mut self) { - self[mut].reverse() - } - - /// Returns a slice of `self` from `start` to the end of the vec. - /// - /// # Failure - /// - /// Fails when `start` points outside the bounds of self. - /// - /// # Example - /// - /// ``` - /// let vec = vec![1i, 2, 3]; - /// assert!(vec[1..] == [2, 3]); - /// ``` - #[inline] - pub fn slice_from<'a>(&'a self, start: uint) -> &'a [T] { - self[start..] - } - - /// Returns a slice of self from the start of the vec to `end`. - /// - /// # Failure - /// - /// Fails when `end` points outside the bounds of self. - /// - /// # Example - /// - /// ``` - /// let vec = vec![1i, 2, 3, 4]; - /// assert!(vec[..2] == [1, 2]); - /// ``` - #[inline] - pub fn slice_to<'a>(&'a self, end: uint) -> &'a [T] { - self[..end] - } - - /// Returns a slice containing all but the last element of the vector. - /// - /// # Failure - /// - /// Fails if the vector is empty - /// - /// # Example - /// - /// ``` - /// let vec = vec![1i, 2, 3]; - /// assert!(vec.init() == [1, 2]); - /// ``` - #[inline] - pub fn init<'a>(&'a self) -> &'a [T] { - self[0..self.len() - 1] - } - - - /// Returns an unsafe pointer to the vector's buffer. - /// - /// The caller must ensure that the vector outlives the pointer this - /// function returns, or else it will end up pointing to garbage. - /// - /// Modifying the vector may cause its buffer to be reallocated, which - /// would also make any pointers to it invalid. - /// - /// # Example - /// - /// ``` - /// let v = vec![1i, 2, 3]; - /// let p = v.as_ptr(); - /// unsafe { - /// // Examine each element manually - /// assert_eq!(*p, 1i); - /// assert_eq!(*p.offset(1), 2i); - /// assert_eq!(*p.offset(2), 3i); - /// } - /// ``` - #[inline] - pub fn as_ptr(&self) -> *const T { - self.ptr as *const T - } - - /// Returns a mutable unsafe pointer to the vector's buffer. - /// - /// The caller must ensure that the vector outlives the pointer this - /// function returns, or else it will end up pointing to garbage. - /// - /// Modifying the vector may cause its buffer to be reallocated, which - /// would also make any pointers to it invalid. - /// - /// # Example - /// - /// ``` - /// use std::ptr; - /// - /// let mut v = vec![1i, 2, 3]; - /// let p = v.as_mut_ptr(); - /// unsafe { - /// ptr::write(p, 9i); - /// ptr::write(p.offset(2), 5i); - /// } - /// assert_eq!(v, vec![9i, 2, 5]); - /// ``` - #[inline] - pub fn as_mut_ptr(&mut self) -> *mut T { - self.ptr - } - /// Retains only the elements specified by the predicate. /// /// In other words, remove all elements `e` such that `f(&e)` returns false. @@ -1297,24 +979,6 @@ impl Vec { } } -impl Vec { - /// Sorts the vector in place. - /// - /// This sort is `O(n log n)` worst-case and stable, but allocates - /// approximately `2 * n`, where `n` is the length of `self`. - /// - /// # Example - /// - /// ``` - /// let mut vec = vec![3i, 1, 2]; - /// vec.sort(); - /// assert_eq!(vec, vec![1, 2, 3]); - /// ``` - pub fn sort(&mut self) { - self.as_mut_slice().sort() - } -} - #[experimental = "waiting on Mutable stability"] impl Mutable for Vec { #[inline] @@ -1325,19 +989,6 @@ impl Mutable for Vec { } impl Vec { - /// Returns true if a vector contains an element equal to the given value. - /// - /// # Example - /// - /// ``` - /// let vec = vec![1i, 2, 3]; - /// assert!(vec.contains(&1)); - /// ``` - #[inline] - pub fn contains(&self, x: &T) -> bool { - self.as_slice().contains(x) - } - /// Removes consecutive repeated elements in the vector. /// /// If the vector is sorted, this removes all duplicates. @@ -1449,7 +1100,12 @@ impl AsSlice for Vec { #[inline] #[stable] fn as_slice<'a>(&'a self) -> &'a [T] { - unsafe { mem::transmute(RawSlice { data: self.as_ptr(), len: self.len }) } + unsafe { + mem::transmute(RawSlice { + data: self.ptr as *const T, + len: self.len + }) + } } } @@ -1697,6 +1353,7 @@ pub fn as_vec<'a, T>(x: &'a [T]) -> DerefVec<'a, T> { pub mod raw { use super::Vec; use core::ptr; + use core::slice::MutableSlice; /// Constructs a vector from an unsafe pointer to a buffer. /// diff --git a/src/libcoretest/str.rs b/src/libcoretest/str.rs index 51bd72ec014..d3f77c47c44 100644 --- a/src/libcoretest/str.rs +++ b/src/libcoretest/str.rs @@ -38,3 +38,72 @@ fn test_strslice_contains() { let x = "There are moments, Jeeves, when one asks oneself, 'Do trousers matter?'"; check_contains_all_substrings(x); } + +#[test] +fn test_rsplitn_char_iterator() { + let data = "\nMäry häd ä little lämb\nLittle lämb\n"; + + let mut split: Vec<&str> = data.rsplitn(3, ' ').collect(); + split.reverse(); + assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]); + + let mut split: Vec<&str> = data.rsplitn(3, |c: char| c == ' ').collect(); + split.reverse(); + assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]); + + // Unicode + let mut split: Vec<&str> = data.rsplitn(3, 'ä').collect(); + split.reverse(); + assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]); + + let mut split: Vec<&str> = data.rsplitn(3, |c: char| c == 'ä').collect(); + split.reverse(); + assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]); +} + +#[test] +fn test_split_char_iterator() { + let data = "\nMäry häd ä little lämb\nLittle lämb\n"; + + let split: Vec<&str> = data.split(' ').collect(); + assert_eq!( split, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); + + let mut rsplit: Vec<&str> = data.split(' ').rev().collect(); + rsplit.reverse(); + assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); + + let split: Vec<&str> = data.split(|c: char| c == ' ').collect(); + assert_eq!( split, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); + + let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect(); + rsplit.reverse(); + assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); + + // Unicode + let split: Vec<&str> = data.split('ä').collect(); + assert_eq!( split, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); + + let mut rsplit: Vec<&str> = data.split('ä').rev().collect(); + rsplit.reverse(); + assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); + + let split: Vec<&str> = data.split(|c: char| c == 'ä').collect(); + assert_eq!( split, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); + + let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect(); + rsplit.reverse(); + assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); +} + +#[test] +fn test_rev_split_char_iterator_no_trailing() { + let data = "\nMäry häd ä little lämb\nLittle lämb\n"; + + let mut split: Vec<&str> = data.split('\n').rev().collect(); + split.reverse(); + assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb", ""]); + + let mut split: Vec<&str> = data.split_terminator('\n').rev().collect(); + split.reverse(); + assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb"]); +} diff --git a/src/libgraphviz/maybe_owned_vec.rs b/src/libgraphviz/maybe_owned_vec.rs index c7659dc1b9f..a4d794d1f99 100644 --- a/src/libgraphviz/maybe_owned_vec.rs +++ b/src/libgraphviz/maybe_owned_vec.rs @@ -58,7 +58,7 @@ impl<'a,T> IntoMaybeOwnedVector<'a,T> for &'a [T] { impl<'a,T> MaybeOwnedVector<'a,T> { pub fn iter(&'a self) -> slice::Items<'a,T> { match self { - &Growable(ref v) => v.iter(), + &Growable(ref v) => v.as_slice().iter(), &Borrowed(ref v) => v.iter(), } } diff --git a/src/libstd/io/comm_adapters.rs b/src/libstd/io/comm_adapters.rs index bd9577c8cfc..338d293fa0a 100644 --- a/src/libstd/io/comm_adapters.rs +++ b/src/libstd/io/comm_adapters.rs @@ -15,7 +15,7 @@ use comm::{Sender, Receiver}; use io; use option::{None, Some}; use result::{Ok, Err}; -use slice::{bytes, CloneableVector}; +use slice::{bytes, CloneableVector, ImmutableSlice}; use super::{Buffer, Reader, Writer, IoResult}; use vec::Vec; diff --git a/src/libstd/io/net/addrinfo.rs b/src/libstd/io/net/addrinfo.rs index 9d85701eb29..eaf47bb004c 100644 --- a/src/libstd/io/net/addrinfo.rs +++ b/src/libstd/io/net/addrinfo.rs @@ -125,6 +125,7 @@ fn lookup(hostname: Option<&str>, servname: Option<&str>, hint: Option) // permission without help of apk #[cfg(all(test, not(target_os = "android")))] mod test { + use prelude::*; use super::*; use io::net::ip::*; diff --git a/src/test/compile-fail/unique-vec-res.rs b/src/test/compile-fail/unique-vec-res.rs index 62fabc0b33f..ba39f3e0d17 100644 --- a/src/test/compile-fail/unique-vec-res.rs +++ b/src/test/compile-fail/unique-vec-res.rs @@ -29,14 +29,16 @@ impl<'a> Drop for r<'a> { fn f(_i: Vec , _j: Vec ) { } +fn clone(t: &T) -> T { t.clone() } + fn main() { let i1 = &Cell::new(0); let i2 = &Cell::new(1); let r1 = vec!(box r { i: i1 }); let r2 = vec!(box r { i: i2 }); - f(r1.clone(), r2.clone()); - //~^ ERROR does not implement any method in scope named `clone` - //~^^ ERROR does not implement any method in scope named `clone` + f(clone(&r1), clone(&r2)); + //~^ ERROR the trait `core::clone::Clone` is not implemented for the type + //~^^ ERROR the trait `core::clone::Clone` is not implemented for the type println!("{}", (r2, i1.get())); println!("{}", (r1, i2.get())); }