@@ -176,6 +176,32 @@ pub trait Clone: Sized {
176
176
}
177
177
}
178
178
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
+
179
205
/// Derive macro generating an impl of the trait `Clone`.
180
206
#[ rustc_builtin_macro]
181
207
#[ stable( feature = "builtin_macro_prelude" , since = "1.38.0" ) ]
@@ -495,6 +521,8 @@ unsafe impl CloneToUninit for crate::bstr::ByteStr {
495
521
/// are implemented in `traits::SelectionContext::copy_clone_conditions()`
496
522
/// in `rustc_trait_selection`.
497
523
mod impls {
524
+ use super :: TrivialClone ;
525
+
498
526
macro_rules! impl_clone {
499
527
( $( $t: ty) * ) => {
500
528
$(
@@ -505,6 +533,9 @@ mod impls {
505
533
* self
506
534
}
507
535
}
536
+
537
+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
538
+ unsafe impl TrivialClone for $t { }
508
539
) *
509
540
}
510
541
}
@@ -524,6 +555,12 @@ mod impls {
524
555
}
525
556
}
526
557
558
+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
559
+ unsafe impl TrivialClone for ! { }
560
+
561
+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
562
+ unsafe impl TrivialClone for ( ) { }
563
+
527
564
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
528
565
impl < T : ?Sized > Clone for * const T {
529
566
#[ inline( always) ]
@@ -532,6 +569,9 @@ mod impls {
532
569
}
533
570
}
534
571
572
+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
573
+ unsafe impl < T : ?Sized > TrivialClone for * const T { }
574
+
535
575
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
536
576
impl < T : ?Sized > Clone for * mut T {
537
577
#[ inline( always) ]
@@ -540,6 +580,9 @@ mod impls {
540
580
}
541
581
}
542
582
583
+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
584
+ unsafe impl < T : ?Sized > TrivialClone for * mut T { }
585
+
543
586
/// Shared references can be cloned, but mutable references *cannot*!
544
587
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
545
588
impl < T : ?Sized > Clone for & T {
@@ -550,6 +593,9 @@ mod impls {
550
593
}
551
594
}
552
595
596
+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
597
+ unsafe impl < T : ?Sized > TrivialClone for & T { }
598
+
553
599
/// Shared references can be cloned, but mutable references *cannot*!
554
600
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
555
601
impl < T : ?Sized > !Clone for & mut T { }
0 commit comments