diff options
| author | bors <bors@rust-lang.org> | 2018-04-04 18:11:51 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-04-04 18:11:51 +0000 |
| commit | fb44b4c0eb1d344f84f7bb2c90f28e31a8a180be (patch) | |
| tree | 9f860914840b493b7f11e1be457a861ec0c63e29 /src/libcore | |
| parent | 17fea66ba46bb32d1a49495518d899cede1d298a (diff) | |
| parent | 87c08f9926b7078489a93cedd1c9f10df1bdf2e0 (diff) | |
| download | rust-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.rs | 87 | ||||
| -rw-r--r-- | src/libcore/marker.rs | 61 |
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 {} + +} |
