@@ -176,6 +176,32 @@ pub trait Clone: Sized {
176176 }
177177}
178178
179+ /// Indicates that the `Clone` implementation is identical to copying the value.
180+ ///
181+ /// This is used for some optimizations in the standard library, which specializes
182+ /// on this trait to select faster implementations of functions such as
183+ /// [`clone_from_slice`](slice::clone_from_slice). It is automatically implemented
184+ /// when using `#[derive(Clone, Copy)]`.
185+ ///
186+ /// Note that this trait does not imply that the type is `Copy`, because e.g.
187+ /// `core::ops::Range<i32>` could soundly implement this trait.
188+ ///
189+ /// # Safety
190+ /// `Clone::clone` must be equivalent to copying the value, otherwise calling functions
191+ /// such as `slice::clone_from_slice` can have undefined behaviour.
192+ #[ unstable(
193+ feature = "trivial_clone" ,
194+ reason = "this isn't part of any API guarantee" ,
195+ issue = "none"
196+ ) ]
197+ // SAFETY:
198+ // It is sound to specialize on this because the `clone` implementation cannot be
199+ // lifetime-dependent. Therefore, if `TrivialClone` is implemented for any lifetime,
200+ // its invariant holds whenever `Clone` is implemented, even if the actual
201+ // `TrivialClone` bound would not be satisfied because of lifetime bounds.
202+ #[ rustc_unsafe_specialization_marker]
203+ pub unsafe trait TrivialClone : Clone { }
204+
179205/// Derive macro generating an impl of the trait `Clone`.
180206#[ rustc_builtin_macro]
181207#[ stable( feature = "builtin_macro_prelude" , since = "1.38.0" ) ]
@@ -317,6 +343,8 @@ unsafe impl CloneToUninit for crate::ffi::CStr {
317343/// are implemented in `traits::SelectionContext::copy_clone_conditions()`
318344/// in `rustc_trait_selection`.
319345mod impls {
346+ use super :: TrivialClone ;
347+
320348 macro_rules! impl_clone {
321349 ( $( $t: ty) * ) => {
322350 $(
@@ -327,6 +355,9 @@ mod impls {
327355 * self
328356 }
329357 }
358+
359+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
360+ unsafe impl TrivialClone for $t { }
330361 ) *
331362 }
332363 }
@@ -346,6 +377,9 @@ mod impls {
346377 }
347378 }
348379
380+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
381+ unsafe impl TrivialClone for ! { }
382+
349383 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
350384 impl < T : ?Sized > Clone for * const T {
351385 #[ inline( always) ]
@@ -354,6 +388,9 @@ mod impls {
354388 }
355389 }
356390
391+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
392+ unsafe impl < T : ?Sized > TrivialClone for * const T { }
393+
357394 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
358395 impl < T : ?Sized > Clone for * mut T {
359396 #[ inline( always) ]
@@ -362,6 +399,9 @@ mod impls {
362399 }
363400 }
364401
402+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
403+ unsafe impl < T : ?Sized > TrivialClone for * mut T { }
404+
365405 /// Shared references can be cloned, but mutable references *cannot*!
366406 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
367407 impl < T : ?Sized > Clone for & T {
@@ -372,6 +412,9 @@ mod impls {
372412 }
373413 }
374414
415+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
416+ unsafe impl < T : ?Sized > TrivialClone for & T { }
417+
375418 /// Shared references can be cloned, but mutable references *cannot*!
376419 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
377420 impl < T : ?Sized > !Clone for & mut T { }
0 commit comments