Skip to content

Commit 5fb5861

Browse files
committed
(almost) get rid of the unsound #[rustc_unsafe_specialization_marker] on Copy, introduce TrivialClone
1 parent acda5e9 commit 5fb5861

File tree

24 files changed

+190
-56
lines changed

24 files changed

+190
-56
lines changed

library/alloc/src/boxed/convert.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
use core::any::Any;
2+
#[cfg(not(no_global_oom_handling))]
3+
use core::clone::TrivialClone;
24
use core::error::Error;
35
use core::mem;
46
use core::pin::Pin;
@@ -75,11 +77,13 @@ impl<T: Clone> BoxFromSlice<T> for Box<[T]> {
7577
}
7678

7779
#[cfg(not(no_global_oom_handling))]
78-
impl<T: Copy> BoxFromSlice<T> for Box<[T]> {
80+
impl<T: TrivialClone> BoxFromSlice<T> for Box<[T]> {
7981
#[inline]
8082
fn from_slice(slice: &[T]) -> Self {
8183
let len = slice.len();
8284
let buf = RawVec::with_capacity(len);
85+
// SAFETY: since `T` implements `TrivialClone`, this is sound and
86+
// equivalent to the above.
8387
unsafe {
8488
ptr::copy_nonoverlapping(slice.as_ptr(), buf.ptr(), len);
8589
buf.into_box(slice.len()).assume_init()

library/alloc/src/collections/vec_deque/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
88
#![stable(feature = "rust1", since = "1.0.0")]
99

10+
#[cfg(not(no_global_oom_handling))]
11+
use core::clone::TrivialClone;
1012
use core::cmp::{self, Ordering};
1113
use core::hash::{Hash, Hasher};
1214
use core::iter::{ByRefSized, repeat_n, repeat_with};
@@ -3419,7 +3421,7 @@ impl<T: Clone, A: Allocator> SpecExtendFromWithin for VecDeque<T, A> {
34193421
}
34203422

34213423
#[cfg(not(no_global_oom_handling))]
3422-
impl<T: Copy, A: Allocator> SpecExtendFromWithin for VecDeque<T, A> {
3424+
impl<T: TrivialClone, A: Allocator> SpecExtendFromWithin for VecDeque<T, A> {
34233425
unsafe fn spec_extend_from_within(&mut self, src: Range<usize>) {
34243426
let dst = self.len();
34253427
let count = src.end - src.start;

library/alloc/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@
146146
#![feature(std_internals)]
147147
#![feature(str_internals)]
148148
#![feature(temporary_niche_types)]
149+
#![feature(trivial_clone)]
149150
#![feature(trusted_fused)]
150151
#![feature(trusted_len)]
151152
#![feature(trusted_random_access)]

library/alloc/src/rc.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,9 +243,9 @@
243243

244244
use core::any::Any;
245245
use core::cell::{Cell, CloneFromCell};
246-
#[cfg(not(no_global_oom_handling))]
247-
use core::clone::CloneToUninit;
248246
use core::clone::UseCloned;
247+
#[cfg(not(no_global_oom_handling))]
248+
use core::clone::{CloneToUninit, TrivialClone};
249249
use core::cmp::Ordering;
250250
use core::hash::{Hash, Hasher};
251251
use core::intrinsics::abort;
@@ -2224,7 +2224,8 @@ impl<T> Rc<[T]> {
22242224

22252225
/// Copy elements from slice into newly allocated `Rc<[T]>`
22262226
///
2227-
/// Unsafe because the caller must either take ownership or bind `T: Copy`
2227+
/// Unsafe because the caller must either take ownership, bind `T: Copy` or
2228+
/// bind `T: TrivialClone`.
22282229
#[cfg(not(no_global_oom_handling))]
22292230
unsafe fn copy_from_slice(v: &[T]) -> Rc<[T]> {
22302231
unsafe {
@@ -2314,9 +2315,11 @@ impl<T: Clone> RcFromSlice<T> for Rc<[T]> {
23142315
}
23152316

23162317
#[cfg(not(no_global_oom_handling))]
2317-
impl<T: Copy> RcFromSlice<T> for Rc<[T]> {
2318+
impl<T: TrivialClone> RcFromSlice<T> for Rc<[T]> {
23182319
#[inline]
23192320
fn from_slice(v: &[T]) -> Self {
2321+
// SAFETY: `T` implements `TrivialClone`, so this is sound and equivalent
2322+
// to the above.
23202323
unsafe { Rc::copy_from_slice(v) }
23212324
}
23222325
}

library/alloc/src/slice.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
use core::borrow::{Borrow, BorrowMut};
1313
#[cfg(not(no_global_oom_handling))]
14+
use core::clone::TrivialClone;
15+
#[cfg(not(no_global_oom_handling))]
1416
use core::cmp::Ordering::{self, Less};
1517
#[cfg(not(no_global_oom_handling))]
1618
use core::mem::MaybeUninit;
@@ -439,7 +441,7 @@ impl<T> [T] {
439441
}
440442
}
441443

442-
impl<T: Copy> ConvertVec for T {
444+
impl<T: TrivialClone> ConvertVec for T {
443445
#[inline]
444446
fn to_vec<A: Allocator>(s: &[Self], alloc: A) -> Vec<Self, A> {
445447
let mut v = Vec::with_capacity_in(s.len(), alloc);
@@ -822,7 +824,7 @@ impl<T: Clone, A: Allocator> SpecCloneIntoVec<T, A> for [T] {
822824
}
823825

824826
#[cfg(not(no_global_oom_handling))]
825-
impl<T: Copy, A: Allocator> SpecCloneIntoVec<T, A> for [T] {
827+
impl<T: TrivialClone, A: Allocator> SpecCloneIntoVec<T, A> for [T] {
826828
fn clone_into(&self, target: &mut Vec<T, A>) {
827829
target.clear();
828830
target.extend_from_slice(self);

library/alloc/src/sync.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ use core::any::Any;
1212
use core::cell::CloneFromCell;
1313
#[cfg(not(no_global_oom_handling))]
1414
use core::clone::CloneToUninit;
15+
#[cfg(not(no_global_oom_handling))]
16+
use core::clone::TrivialClone;
1517
use core::clone::UseCloned;
1618
use core::cmp::Ordering;
1719
use core::hash::{Hash, Hasher};
@@ -2156,7 +2158,8 @@ impl<T> Arc<[T]> {
21562158

21572159
/// Copy elements from slice into newly allocated `Arc<[T]>`
21582160
///
2159-
/// Unsafe because the caller must either take ownership or bind `T: Copy`.
2161+
/// Unsafe because the caller must either take ownership, bind `T: Copy` or
2162+
/// bind `T: TrivialClone`.
21602163
#[cfg(not(no_global_oom_handling))]
21612164
unsafe fn copy_from_slice(v: &[T]) -> Arc<[T]> {
21622165
unsafe {
@@ -2248,9 +2251,11 @@ impl<T: Clone> ArcFromSlice<T> for Arc<[T]> {
22482251
}
22492252

22502253
#[cfg(not(no_global_oom_handling))]
2251-
impl<T: Copy> ArcFromSlice<T> for Arc<[T]> {
2254+
impl<T: TrivialClone> ArcFromSlice<T> for Arc<[T]> {
22522255
#[inline]
22532256
fn from_slice(v: &[T]) -> Self {
2257+
// SAFETY: `T` implements `TrivialClone`, so this is sound and equivalent
2258+
// to the above.
22542259
unsafe { Arc::copy_from_slice(v) }
22552260
}
22562261
}

library/alloc/src/vec/mod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@
7373
7474
#![stable(feature = "rust1", since = "1.0.0")]
7575

76+
#[cfg(not(no_global_oom_handling))]
77+
use core::clone::TrivialClone;
7678
#[cfg(not(no_global_oom_handling))]
7779
use core::cmp;
7880
use core::cmp::Ordering;
@@ -3494,7 +3496,7 @@ impl<T: Clone, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
34943496
}
34953497

34963498
#[cfg(not(no_global_oom_handling))]
3497-
impl<T: Copy, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
3499+
impl<T: TrivialClone, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
34983500
unsafe fn spec_extend_from_within(&mut self, src: Range<usize>) {
34993501
let count = src.len();
35003502
{
@@ -3507,8 +3509,8 @@ impl<T: Copy, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
35073509
// SAFETY:
35083510
// - Both pointers are created from unique slice references (`&mut [_]`)
35093511
// so they are valid and do not overlap.
3510-
// - Elements are :Copy so it's OK to copy them, without doing
3511-
// anything with the original values
3512+
// - Elements implement `TrivialClone` so this is equivalent to calling
3513+
// `clone` on every one of them.
35123514
// - `count` is equal to the len of `source`, so source is valid for
35133515
// `count` reads
35143516
// - `.reserve(count)` guarantees that `spare.len() >= count` so spare

library/alloc/src/vec/spec_extend.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use core::clone::TrivialClone;
12
use core::iter::TrustedLen;
23
use core::slice::{self};
34

@@ -48,7 +49,7 @@ where
4849

4950
impl<'a, T: 'a, A: Allocator> SpecExtend<&'a T, slice::Iter<'a, T>> for Vec<T, A>
5051
where
51-
T: Copy,
52+
T: TrivialClone,
5253
{
5354
fn spec_extend(&mut self, iterator: slice::Iter<'a, T>) {
5455
let slice = iterator.as_slice();

library/alloctests/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#![feature(slice_range)]
4141
#![feature(std_internals)]
4242
#![feature(temporary_niche_types)]
43+
#![feature(trivial_clone)]
4344
#![feature(trusted_fused)]
4445
#![feature(trusted_len)]
4546
#![feature(trusted_random_access)]

library/core/src/array/mod.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
#![stable(feature = "core_array", since = "1.35.0")]
66

77
use crate::borrow::{Borrow, BorrowMut};
8+
use crate::clone::TrivialClone;
89
use crate::cmp::Ordering;
910
use crate::convert::Infallible;
1011
use crate::error::Error;
11-
use crate::fmt;
1212
use crate::hash::{self, Hash};
1313
use crate::intrinsics::transmute_unchecked;
1414
use crate::iter::{UncheckedIterator, repeat_n};
@@ -18,6 +18,7 @@ use crate::ops::{
1818
};
1919
use crate::ptr::{null, null_mut};
2020
use crate::slice::{Iter, IterMut};
21+
use crate::{fmt, ptr};
2122

2223
mod ascii;
2324
mod drain;
@@ -451,6 +452,9 @@ impl<T: Clone, const N: usize> Clone for [T; N] {
451452
}
452453
}
453454

455+
#[unstable(feature = "trivial_clone", issue = "none")]
456+
unsafe impl<T: TrivialClone, const N: usize> TrivialClone for [T; N] {}
457+
454458
trait SpecArrayClone: Clone {
455459
fn clone<const N: usize>(array: &[Self; N]) -> [Self; N];
456460
}
@@ -462,10 +466,12 @@ impl<T: Clone> SpecArrayClone for T {
462466
}
463467
}
464468

465-
impl<T: Copy> SpecArrayClone for T {
469+
impl<T: TrivialClone> SpecArrayClone for T {
466470
#[inline]
467471
fn clone<const N: usize>(array: &[T; N]) -> [T; N] {
468-
*array
472+
// SAFETY: `TrivialClone` implies that this is equivalent to calling
473+
// `Clone` on every element.
474+
unsafe { ptr::read(array) }
469475
}
470476
}
471477

0 commit comments

Comments
 (0)