about summary refs log tree commit diff
path: root/src/libcore/clone.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-04-04 18:11:51 +0000
committerbors <bors@rust-lang.org>2018-04-04 18:11:51 +0000
commitfb44b4c0eb1d344f84f7bb2c90f28e31a8a180be (patch)
tree9f860914840b493b7f11e1be457a861ec0c63e29 /src/libcore/clone.rs
parent17fea66ba46bb32d1a49495518d899cede1d298a (diff)
parent87c08f9926b7078489a93cedd1c9f10df1bdf2e0 (diff)
Auto merge of #48171 - FraGag:doc-copy-clone-impls, r=nikomatsakis
Better document the implementors of Clone and Copy

There are two parts to this change. The first part is a change to the compiler and to the standard library (specifically, libcore) to allow implementations of `Clone` and `Copy` to be written for a subset of builtin types. By adding these implementations to libcore, they now show up in the documentation. This is a [breaking-change] for users of `#![no_core]`, because they will now have to supply their own copy of the implementations of `Clone` and `Copy` that were added in libcore.

The second part is purely a documentation change to document the other implementors of `Clone` and `Copy` that cannot be described in Rust code (yet) and are thus provided by the compiler.

Fixes #25893
Diffstat (limited to 'src/libcore/clone.rs')
-rw-r--r--src/libcore/clone.rs87
1 files changed, 82 insertions, 5 deletions
diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs
index d25f498b99e..f8e8c69621a 100644
--- a/src/libcore/clone.rs
+++ b/src/libcore/clone.rs
@@ -63,11 +63,6 @@
 /// This trait can be used with `#[derive]` if all fields are `Clone`. The `derive`d
 /// implementation of [`clone`] calls [`clone`] on each field.
 ///
-/// ## Closures
-///
-/// Closure types automatically implement `Clone` if they capture no value from the environment
-/// or if all such captured values implement `Clone` themselves.
-///
 /// ## How can I implement `Clone`?
 ///
 /// Types that are [`Copy`] should have a trivial implementation of `Clone`. More formally:
@@ -92,6 +87,23 @@
 ///     fn clone(&self) -> Stats { *self }
 /// }
 /// ```
+///
+/// ## Additional implementors
+///
+/// In addition to the [implementors listed below][impls],
+/// the following types also implement `Clone`:
+///
+/// * Function item types (i.e. the distinct types defined for each function)
+/// * Function pointer types (e.g. `fn() -> i32`)
+/// * Array types, for all sizes, if the item type also implements `Clone` (e.g. `[i32; 123456]`)
+/// * Tuple types, if each component also implements `Clone` (e.g. `()`, `(i32, bool)`)
+/// * Closure types, if they capture no value from the environment
+///   or if all such captured values implement `Clone` themselves.
+///   Note that variables captured by shared reference always implement `Clone`
+///   (even if the referent doesn't),
+///   while variables captured by mutable reference never implement `Clone`.
+///
+/// [impls]: #implementors
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang = "clone"]
 pub trait Clone : Sized {
@@ -135,3 +147,68 @@ pub struct AssertParamIsClone<T: Clone + ?Sized> { _field: ::marker::PhantomData
            reason = "deriving hack, should not be public",
            issue = "0")]
 pub struct AssertParamIsCopy<T: Copy + ?Sized> { _field: ::marker::PhantomData<T> }
+
+/// Implementations of `Clone` for primitive types.
+///
+/// Implementations that cannot be described in Rust
+/// are implemented in `SelectionContext::copy_clone_conditions()` in librustc.
+#[cfg(not(stage0))]
+mod impls {
+
+    use super::Clone;
+
+    macro_rules! impl_clone {
+        ($($t:ty)*) => {
+            $(
+                #[stable(feature = "rust1", since = "1.0.0")]
+                impl Clone for $t {
+                    #[inline]
+                    fn clone(&self) -> Self {
+                        *self
+                    }
+                }
+            )*
+        }
+    }
+
+    impl_clone! {
+        usize u8 u16 u32 u64 u128
+        isize i8 i16 i32 i64 i128
+        f32 f64
+        bool char
+    }
+
+    #[stable(feature = "never_type", since = "1.26.0")]
+    impl Clone for ! {
+        #[inline]
+        fn clone(&self) -> Self {
+            *self
+        }
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<T: ?Sized> Clone for *const T {
+        #[inline]
+        fn clone(&self) -> Self {
+            *self
+        }
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<T: ?Sized> Clone for *mut T {
+        #[inline]
+        fn clone(&self) -> Self {
+            *self
+        }
+    }
+
+    // Shared references can be cloned, but mutable references *cannot*!
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<'a, T: ?Sized> Clone for &'a T {
+        #[inline]
+        fn clone(&self) -> Self {
+            *self
+        }
+    }
+
+}