@@ -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" ) ]
@@ -327,6 +353,8 @@ unsafe impl CloneToUninit for crate::bstr::ByteStr {
327353/// are implemented in `traits::SelectionContext::copy_clone_conditions()`
328354/// in `rustc_trait_selection`.
329355mod impls {
356+ use super :: TrivialClone ;
357+
330358 macro_rules! impl_clone {
331359 ( $( $t: ty) * ) => {
332360 $(
@@ -337,6 +365,9 @@ mod impls {
337365 * self
338366 }
339367 }
368+
369+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
370+ unsafe impl TrivialClone for $t { }
340371 ) *
341372 }
342373 }
@@ -356,6 +387,12 @@ mod impls {
356387 }
357388 }
358389
390+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
391+ unsafe impl TrivialClone for ! { }
392+
393+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
394+ unsafe impl TrivialClone for ( ) { }
395+
359396 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
360397 impl < T : ?Sized > Clone for * const T {
361398 #[ inline( always) ]
@@ -364,6 +401,9 @@ mod impls {
364401 }
365402 }
366403
404+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
405+ unsafe impl < T : ?Sized > TrivialClone for * const T { }
406+
367407 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
368408 impl < T : ?Sized > Clone for * mut T {
369409 #[ inline( always) ]
@@ -372,6 +412,9 @@ mod impls {
372412 }
373413 }
374414
415+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
416+ unsafe impl < T : ?Sized > TrivialClone for * mut 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 & T {
@@ -382,6 +425,9 @@ mod impls {
382425 }
383426 }
384427
428+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
429+ unsafe impl < T : ?Sized > TrivialClone for & T { }
430+
385431 /// Shared references can be cloned, but mutable references *cannot*!
386432 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
387433 impl < T : ?Sized > !Clone for & mut T { }
0 commit comments