@@ -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" ) ]
@@ -327,6 +353,8 @@ unsafe impl CloneToUninit for crate::bstr::ByteStr {
327
353
/// are implemented in `traits::SelectionContext::copy_clone_conditions()`
328
354
/// in `rustc_trait_selection`.
329
355
mod impls {
356
+ use super :: TrivialClone ;
357
+
330
358
macro_rules! impl_clone {
331
359
( $( $t: ty) * ) => {
332
360
$(
@@ -337,6 +365,9 @@ mod impls {
337
365
* self
338
366
}
339
367
}
368
+
369
+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
370
+ unsafe impl TrivialClone for $t { }
340
371
) *
341
372
}
342
373
}
@@ -356,6 +387,12 @@ mod impls {
356
387
}
357
388
}
358
389
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
+
359
396
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
360
397
impl < T : ?Sized > Clone for * const T {
361
398
#[ inline( always) ]
@@ -364,6 +401,9 @@ mod impls {
364
401
}
365
402
}
366
403
404
+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
405
+ unsafe impl < T : ?Sized > TrivialClone for * const T { }
406
+
367
407
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
368
408
impl < T : ?Sized > Clone for * mut T {
369
409
#[ inline( always) ]
@@ -372,6 +412,9 @@ mod impls {
372
412
}
373
413
}
374
414
415
+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
416
+ unsafe impl < T : ?Sized > TrivialClone for * mut T { }
417
+
375
418
/// Shared references can be cloned, but mutable references *cannot*!
376
419
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
377
420
impl < T : ?Sized > Clone for & T {
@@ -382,6 +425,9 @@ mod impls {
382
425
}
383
426
}
384
427
428
+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
429
+ unsafe impl < T : ?Sized > TrivialClone for & T { }
430
+
385
431
/// Shared references can be cloned, but mutable references *cannot*!
386
432
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
387
433
impl < T : ?Sized > !Clone for & mut T { }
0 commit comments