@@ -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" ) ]
@@ -317,6 +343,8 @@ unsafe impl CloneToUninit for crate::ffi::CStr {
317
343
/// are implemented in `traits::SelectionContext::copy_clone_conditions()`
318
344
/// in `rustc_trait_selection`.
319
345
mod impls {
346
+ use super :: TrivialClone ;
347
+
320
348
macro_rules! impl_clone {
321
349
( $( $t: ty) * ) => {
322
350
$(
@@ -327,6 +355,9 @@ mod impls {
327
355
* self
328
356
}
329
357
}
358
+
359
+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
360
+ unsafe impl TrivialClone for $t { }
330
361
) *
331
362
}
332
363
}
@@ -346,6 +377,9 @@ mod impls {
346
377
}
347
378
}
348
379
380
+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
381
+ unsafe impl TrivialClone for ! { }
382
+
349
383
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
350
384
impl < T : ?Sized > Clone for * const T {
351
385
#[ inline( always) ]
@@ -354,6 +388,9 @@ mod impls {
354
388
}
355
389
}
356
390
391
+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
392
+ unsafe impl < T : ?Sized > TrivialClone for * const T { }
393
+
357
394
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
358
395
impl < T : ?Sized > Clone for * mut T {
359
396
#[ inline( always) ]
@@ -362,6 +399,9 @@ mod impls {
362
399
}
363
400
}
364
401
402
+ #[ unstable( feature = "trivial_clone" , issue = "none" ) ]
403
+ unsafe impl < T : ?Sized > TrivialClone for * mut T { }
404
+
365
405
/// Shared references can be cloned, but mutable references *cannot*!
366
406
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
367
407
impl < T : ?Sized > Clone for & T {
@@ -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 & 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 & mut T { }
0 commit comments