From 6ae87e0d9b7b645cdb6d8b941efca25de236e5a3 Mon Sep 17 00:00:00 2001 From: Clar Fon Date: Wed, 19 Dec 2018 16:00:29 -0500 Subject: [PATCH] Add TryClone trait --- src/libcore/clone.rs | 23 +++++++++++++++++++++++ src/libstd/fs.rs | 9 +++++++++ src/libstd/lib.rs | 1 + src/libstd/net/tcp.rs | 17 +++++++++++++++++ src/libstd/net/udp.rs | 9 +++++++++ 5 files changed, 59 insertions(+) diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index ed90b7de26417..7a7c1d734933b 100644 --- a/src/libcore/clone.rs +++ b/src/libcore/clone.rs @@ -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; +} + +// Infallible clones are semantically equivalent to fallible clones +// with an uninhabited error type. +#[unstable(feature = "try_clone", issue = "0")] +impl TryClone for T where T: Clone { + type Error = !; + + fn try_clone(&self) -> Result { + Ok(self.clone()) + } +} + // FIXME(aburka): these structs are used solely by #[derive] to // assert that every component of a type implements Clone or Copy. // diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 119b3f7f9f296..db3b161da45ea 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -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}; @@ -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::try_clone(self) + } +} + impl AsInner for File { fn as_inner(&self) -> &fs_imp::File { &self.inner } } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index ccfce672e5f9e..40adf388ea2df 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -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)] diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index b75591e53fc72..c72a106eaada7 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -1,5 +1,6 @@ use io::prelude::*; +use clone::TryClone; use fmt; use io::{self, Initializer}; use net::{ToSocketAddrs, SocketAddr, Shutdown}; @@ -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::try_clone(self) + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl Read for TcpStream { fn read(&mut self, buf: &mut [u8]) -> io::Result { self.0.read(buf) } @@ -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::try_clone(self) + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl<'a> Iterator for Incoming<'a> { type Item = io::Result; diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs index 83459946ba6de..3794694131dfa 100644 --- a/src/libstd/net/udp.rs +++ b/src/libstd/net/udp.rs @@ -1,3 +1,4 @@ +use clone::TryClone; use fmt; use io::{self, Error, ErrorKind}; use net::{ToSocketAddrs, SocketAddr, Ipv4Addr, Ipv6Addr}; @@ -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::try_clone(self) + } +} + impl AsInner for UdpSocket { fn as_inner(&self) -> &net_imp::UdpSocket { &self.0 } }