about summary refs log tree commit diff
path: root/src/libcore
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
parent17fea66ba46bb32d1a49495518d899cede1d298a (diff)
parent87c08f9926b7078489a93cedd1c9f10df1bdf2e0 (diff)
downloadrust-fb44b4c0eb1d344f84f7bb2c90f28e31a8a180be.tar.gz
rust-fb44b4c0eb1d344f84f7bb2c90f28e31a8a180be.zip
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')
-rw-r--r--src/libcore/clone.rs87
-rw-r--r--src/libcore/marker.rs61
2 files changed, 138 insertions, 10 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
+        }
+    }
+
+}
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 7d0174a178a..885aabe0806 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -166,11 +166,6 @@ pub trait Unsize<T: ?Sized> {
 /// are allowed to access `x` after the assignment. Under the hood, both a copy and a move
 /// can result in bits being copied in memory, although this is sometimes optimized away.
 ///
-/// ## Closures
-///
-/// Closure types automatically implement `Copy` if they capture no value from the environment
-/// or if all such captured values implement `Copy` themselves.
-///
 /// ## How can I implement `Copy`?
 ///
 /// There are two ways to implement `Copy` on your type. The simplest is to use `derive`:
@@ -265,6 +260,21 @@ pub trait Unsize<T: ?Sized> {
 /// non-`Copy` in the future, it could be prudent to omit the `Copy` implementation now, to
 /// avoid a breaking API change.
 ///
+/// ## Additional implementors
+///
+/// In addition to the [implementors listed below][impls],
+/// the following types also implement `Copy`:
+///
+/// * 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 `Copy` (e.g. `[i32; 123456]`)
+/// * Tuple types, if each component also implements `Copy` (e.g. `()`, `(i32, bool)`)
+/// * Closure types, if they capture no value from the environment
+///   or if all such captured values implement `Copy` themselves.
+///   Note that variables captured by shared reference always implement `Copy`
+///   (even if the referent doesn't),
+///   while variables captured by mutable reference never implement `Copy`.
+///
 /// [`Vec<T>`]: ../../std/vec/struct.Vec.html
 /// [`String`]: ../../std/string/struct.String.html
 /// [`Drop`]: ../../std/ops/trait.Drop.html
@@ -272,6 +282,7 @@ pub trait Unsize<T: ?Sized> {
 /// [`Clone`]: ../clone/trait.Clone.html
 /// [`String`]: ../../std/string/struct.String.html
 /// [`i32`]: ../../std/primitive.i32.html
+/// [impls]: #implementors
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang = "copy"]
 pub trait Copy : Clone {
@@ -593,3 +604,43 @@ unsafe impl<'a, T: ?Sized> Freeze for &'a mut T {}
 /// This trait is automatically implemented for almost every type.
 #[unstable(feature = "pin", issue = "49150")]
 pub unsafe auto trait Unpin {}
+
+/// Implementations of `Copy` for primitive types.
+///
+/// Implementations that cannot be described in Rust
+/// are implemented in `SelectionContext::copy_clone_conditions()` in librustc.
+#[cfg(not(stage0))]
+mod copy_impls {
+
+    use super::Copy;
+
+    macro_rules! impl_copy {
+        ($($t:ty)*) => {
+            $(
+                #[stable(feature = "rust1", since = "1.0.0")]
+                impl Copy for $t {}
+            )*
+        }
+    }
+
+    impl_copy! {
+        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 Copy for ! {}
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<T: ?Sized> Copy for *const T {}
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<T: ?Sized> Copy for *mut T {}
+
+    // Shared references can be copied, but mutable references *cannot*!
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<'a, T: ?Sized> Copy for &'a T {}
+
+}