about summary refs log tree commit diff
path: root/library/core
diff options
context:
space:
mode:
Diffstat (limited to 'library/core')
-rw-r--r--library/core/src/clone.rs34
-rw-r--r--library/core/src/num/bignum.rs2
-rw-r--r--library/core/src/num/nonzero.rs4
-rw-r--r--library/core/src/option.rs3
-rw-r--r--library/core/src/result.rs8
5 files changed, 51 insertions, 0 deletions
diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs
index 00300328b64..249ca6c091f 100644
--- a/library/core/src/clone.rs
+++ b/library/core/src/clone.rs
@@ -184,6 +184,40 @@ pub macro Clone($item:item) {
     /* compiler built-in */
 }
 
+/// Trait for objects whose [`Clone`] impl is lightweight (e.g. reference-counted)
+///
+/// Cloning an object implementing this trait should in general:
+/// - be O(1) (constant) time regardless of the amount of data managed by the object,
+/// - not require a memory allocation,
+/// - not require copying more than roughly 64 bytes (a typical cache line size),
+/// - not block the current thread,
+/// - not have any semantic side effects (e.g. allocating a file descriptor), and
+/// - not have overhead larger than a couple of atomic operations.
+///
+/// The `UseCloned` trait does not provide a method; instead, it indicates that
+/// `Clone::clone` is lightweight, and allows the use of the `.use` syntax.
+#[unstable(feature = "ergonomic_clones", issue = "132290")]
+#[cfg_attr(not(bootstrap), lang = "use_cloned")]
+pub trait UseCloned: Clone {
+    // Empty.
+}
+
+macro_rules! impl_use_cloned {
+    ($($t:ty)*) => {
+        $(
+            #[unstable(feature = "ergonomic_clones", issue = "132290")]
+            impl UseCloned for $t {}
+        )*
+    }
+}
+
+impl_use_cloned! {
+    usize u8 u16 u32 u64 u128
+    isize i8 i16 i32 i64 i128
+             f16 f32 f64 f128
+    bool char
+}
+
 // FIXME(aburka): these structs are used solely by #[derive] to
 // assert that every component of a type implements Clone or Copy.
 //
diff --git a/library/core/src/num/bignum.rs b/library/core/src/num/bignum.rs
index 2a47c89e2ae..9de6b349d94 100644
--- a/library/core/src/num/bignum.rs
+++ b/library/core/src/num/bignum.rs
@@ -405,6 +405,8 @@ macro_rules! define_bignum {
             }
         }
 
+        impl crate::clone::UseCloned for $name {}
+
         impl crate::fmt::Debug for $name {
             fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result {
                 let sz = if self.size < 1 { 1 } else { self.size };
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index a967b72c4fa..5b997d44278 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -1,6 +1,7 @@
 //! Definitions of integer that is known not to equal zero.
 
 use super::{IntErrorKind, ParseIntError};
+use crate::clone::UseCloned;
 use crate::cmp::Ordering;
 use crate::hash::{Hash, Hasher};
 use crate::marker::{Freeze, StructuralPartialEq};
@@ -183,6 +184,9 @@ where
     }
 }
 
+#[unstable(feature = "ergonomic_clones", issue = "132290")]
+impl<T> UseCloned for NonZero<T> where T: ZeroablePrimitive {}
+
 #[stable(feature = "nonzero", since = "1.28.0")]
 impl<T> Copy for NonZero<T> where T: ZeroablePrimitive {}
 
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index a9f06b92ad5..f668c6f0672 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -2050,6 +2050,9 @@ where
     }
 }
 
+#[unstable(feature = "ergonomic_clones", issue = "132290")]
+impl<T> crate::clone::UseCloned for Option<T> where T: crate::clone::UseCloned {}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Default for Option<T> {
     /// Returns [`None`][Option::None].
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index 92b5cba1531..ee98a47523f 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -1744,6 +1744,14 @@ where
     }
 }
 
+#[unstable(feature = "ergonomic_clones", issue = "132290")]
+impl<T, E> crate::clone::UseCloned for Result<T, E>
+where
+    T: crate::clone::UseCloned,
+    E: crate::clone::UseCloned,
+{
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T, E> IntoIterator for Result<T, E> {
     type Item = T;