Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/libcore/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,29 @@ pub trait Clone : Sized {
}
}

/// Falliable version of [`Clone`].
#[unstable(feature = "try_clone", issue = "0")]
pub trait TryClone : Sized {
/// The type returned when cloning fails.
type Error;

/// Returns a copy of the value, or an error if the value could not be cloned.
#[unstable(feature = "try_clone", issue = "0")]
#[must_use = "cloning is often expensive and is not expected to have side effects"]
fn try_clone(&self) -> Result<Self, Self::Error>;
}

// Infallible clones are semantically equivalent to fallible clones
// with an uninhabited error type.
#[unstable(feature = "try_clone", issue = "0")]
impl<T> TryClone for T where T: Clone {
type Error = !;

fn try_clone(&self) -> Result<Self, Self::Error> {
Ok(self.clone())
}
}

// FIXME(aburka): these structs are used solely by #[derive] to
// assert that every component of a type implements Clone or Copy.
//
Expand Down
9 changes: 9 additions & 0 deletions src/libstd/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#![stable(feature = "rust1", since = "1.0.0")]

use clone::TryClone;
use fmt;
use ffi::OsString;
use io::{self, SeekFrom, Seek, Read, Initializer, Write};
Expand Down Expand Up @@ -572,6 +573,14 @@ impl File {
}
}

#[unstable(feature = "try_clone", issue = "0")]
impl TryClone for File {
type Error = io::Error;
fn try_clone(&self) -> io::Result<File> {
File::try_clone(self)
}
}

impl AsInner<fs_imp::File> for File {
fn as_inner(&self) -> &fs_imp::File { &self.inner }
}
Expand Down
1 change: 1 addition & 0 deletions src/libstd/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@
#![feature(rustc_private)]
#![feature(thread_local)]
#![feature(toowned_clone_into)]
#![feature(try_clone)]
#![feature(try_from)]
#![feature(try_reserve)]
#![feature(unboxed_closures)]
Expand Down
17 changes: 17 additions & 0 deletions src/libstd/net/tcp.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use io::prelude::*;

use clone::TryClone;
use fmt;
use io::{self, Initializer};
use net::{ToSocketAddrs, SocketAddr, Shutdown};
Expand Down Expand Up @@ -565,6 +566,14 @@ impl TcpStream {
}
}

#[unstable(feature = "try_clone", issue = "0")]
impl TryClone for TcpStream {
type Error = io::Error;
fn try_clone(&self) -> io::Result<TcpStream> {
TcpStream::try_clone(self)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Read for TcpStream {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
Expand Down Expand Up @@ -880,6 +889,14 @@ impl TcpListener {
}
}

#[unstable(feature = "try_clone", issue = "0")]
impl TryClone for TcpListener {
type Error = io::Error;
fn try_clone(&self) -> io::Result<TcpListener> {
TcpListener::try_clone(self)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Iterator for Incoming<'a> {
type Item = io::Result<TcpStream>;
Expand Down
9 changes: 9 additions & 0 deletions src/libstd/net/udp.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use clone::TryClone;
use fmt;
use io::{self, Error, ErrorKind};
use net::{ToSocketAddrs, SocketAddr, Ipv4Addr, Ipv6Addr};
Expand Down Expand Up @@ -787,6 +788,14 @@ impl UdpSocket {
}
}

#[unstable(feature = "try_clone", issue = "0")]
impl TryClone for UdpSocket {
type Error = io::Error;
fn try_clone(&self) -> io::Result<UdpSocket> {
UdpSocket::try_clone(self)
}
}

impl AsInner<net_imp::UdpSocket> for UdpSocket {
fn as_inner(&self) -> &net_imp::UdpSocket { &self.0 }
}
Expand Down