From 27164faaef69853e2c1adcc0ccd6e70780b6da0a Mon Sep 17 00:00:00 2001 From: Francis Gagné Date: Mon, 12 Feb 2018 01:17:32 -0500 Subject: Move some implementations of Clone and Copy to libcore Add implementations of `Clone` and `Copy` for some primitive types to libcore so that they show up in the documentation. The concerned types are the following: * All primitive signed and unsigned integer types (`usize`, `u8`, `u16`, `u32`, `u64`, `u128`, `isize`, `i8`, `i16`, `i32`, `i64`, `i128`); * All primitive floating point types (`f32`, `f64`) * `bool` * `char` * `!` * Raw pointers (`*const T` and `*mut T`) * Shared references (`&'a T`) These types already implemented `Clone` and `Copy`, but the implementation was provided by the compiler. The compiler no longer provides these implementations and instead tries to look them up as normal trait implementations. The goal of this change is to make the implementations appear in the generated documentation. For `Copy` specifically, the compiler would reject an attempt to write an `impl` for the primitive types listed above with error `E0206`; this error no longer occurs for these types, but it will still occur for the other types that used to raise that error. The trait implementations are guarded with `#[cfg(not(stage0))]` because they are invalid according to the stage0 compiler. When the stage0 compiler is updated to a revision that includes this change, the attribute will have to be removed, otherwise the stage0 build will fail because the types mentioned above no longer implement `Clone` or `Copy`. For type variants that are variadic, such as tuples and function pointers, and for array types, the `Clone` and `Copy` implementations are still provided by the compiler, because the language is not expressive enough yet to be able to write the appropriate implementations in Rust. The initial plan was to add `impl` blocks guarded by `#[cfg(dox)]` to make them apply only when generating documentation, without having to touch the compiler. However, rustdoc's usage of the compiler still rejected those `impl` blocks. This is a [breaking-change] for users of `#![no_core]`, because they will now have to supply their own implementations of `Clone` and `Copy` for the primitive types listed above. The easiest way to do that is to simply copy the implementations from `src/libcore/clone.rs` and `src/libcore/marker.rs`. Fixes #25893 --- src/libcore/clone.rs | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/libcore/marker.rs | 40 ++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) (limited to 'src/libcore') diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index d25f498b99e..5c83dd79bd7 100644 --- a/src/libcore/clone.rs +++ b/src/libcore/clone.rs @@ -135,3 +135,63 @@ pub struct AssertParamIsClone { _field: ::marker::PhantomData reason = "deriving hack, should not be public", issue = "0")] pub struct AssertParamIsCopy { _field: ::marker::PhantomData } + +/// 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 { + 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 ! { + fn clone(&self) -> Self { + *self + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Clone for *const T { + fn clone(&self) -> Self { + *self + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Clone for *mut T { + 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 { + fn clone(&self) -> Self { + *self + } + } + +} diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 7d0174a178a..008cb15131d 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -593,3 +593,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 Copy for *const T {} + + #[stable(feature = "rust1", since = "1.0.0")] + impl 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 {} + +} -- cgit 1.4.1-3-g733a5 From f48c043154aeed1af44e6be66b17122fafacda51 Mon Sep 17 00:00:00 2001 From: Francis Gagné Date: Mon, 12 Feb 2018 02:31:26 -0500 Subject: Document builtin implementations of Clone and Copy There are types that implement `Clone` and `Copy` but are not mentioned in the documentation, because the implementations are provided by the compiler. They are types of variants that cannot be fully covered by trait implementations in Rust code, because the language is not expressive enough. --- src/libcore/clone.rs | 22 +++++++++++++++++----- src/libcore/marker.rs | 21 ++++++++++++++++----- 2 files changed, 33 insertions(+), 10 deletions(-) (limited to 'src/libcore') diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index 5c83dd79bd7..b6a5948e645 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 { diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 008cb15131d..885aabe0806 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -166,11 +166,6 @@ pub trait Unsize { /// 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 { /// 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`]: ../../std/vec/struct.Vec.html /// [`String`]: ../../std/string/struct.String.html /// [`Drop`]: ../../std/ops/trait.Drop.html @@ -272,6 +282,7 @@ pub trait Unsize { /// [`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 { -- cgit 1.4.1-3-g733a5 From afa7f5bc8ac79503bb99a20a1dd19365318f504f Mon Sep 17 00:00:00 2001 From: Francis Gagné Date: Sat, 10 Mar 2018 17:43:44 -0500 Subject: Add #[inline] to Clone impls for primitive types --- src/libcore/clone.rs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/libcore') diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index b6a5948e645..f8e8c69621a 100644 --- a/src/libcore/clone.rs +++ b/src/libcore/clone.rs @@ -162,6 +162,7 @@ mod impls { $( #[stable(feature = "rust1", since = "1.0.0")] impl Clone for $t { + #[inline] fn clone(&self) -> Self { *self } @@ -179,6 +180,7 @@ mod impls { #[stable(feature = "never_type", since = "1.26.0")] impl Clone for ! { + #[inline] fn clone(&self) -> Self { *self } @@ -186,6 +188,7 @@ mod impls { #[stable(feature = "rust1", since = "1.0.0")] impl Clone for *const T { + #[inline] fn clone(&self) -> Self { *self } @@ -193,6 +196,7 @@ mod impls { #[stable(feature = "rust1", since = "1.0.0")] impl Clone for *mut T { + #[inline] fn clone(&self) -> Self { *self } @@ -201,6 +205,7 @@ mod impls { // 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 } -- cgit 1.4.1-3-g733a5