Skip to content

Commit 4436965

Browse files
committed
core: make TrivialClone a subtrait of Copy and revert some associated unsafe
1 parent c5e262c commit 4436965

File tree

5 files changed

+30
-48
lines changed

5 files changed

+30
-48
lines changed

library/core/src/array/mod.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::clone::TrivialClone;
99
use crate::cmp::Ordering;
1010
use crate::convert::Infallible;
1111
use crate::error::Error;
12+
use crate::fmt;
1213
use crate::hash::{self, Hash};
1314
use crate::intrinsics::transmute_unchecked;
1415
use crate::iter::{UncheckedIterator, repeat_n};
@@ -18,7 +19,6 @@ use crate::ops::{
1819
};
1920
use crate::ptr::{null, null_mut};
2021
use crate::slice::{Iter, IterMut};
21-
use crate::{fmt, ptr};
2222

2323
mod ascii;
2424
mod drain;
@@ -444,9 +444,7 @@ impl<T: Clone> SpecArrayClone for T {
444444
impl<T: TrivialClone> SpecArrayClone for T {
445445
#[inline]
446446
fn clone<const N: usize>(array: &[T; N]) -> [T; N] {
447-
// SAFETY: `TrivialClone` implies that this is equivalent to calling
448-
// `Clone` on every element.
449-
unsafe { ptr::read(array) }
447+
*array
450448
}
451449
}
452450

library/core/src/clone.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ pub trait Clone: Sized {
205205
// implementations of `TrivialClone`. To keep it from appearing in error
206206
// messages, make it a `#[marker]` trait.
207207
#[marker]
208-
pub unsafe trait TrivialClone: Clone {}
208+
pub unsafe trait TrivialClone: Copy {}
209209

210210
/// Derive macro generating an impl of the trait `Clone`.
211211
#[rustc_builtin_macro]

library/core/src/mem/maybe_uninit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ impl<T: Copy> Clone for MaybeUninit<T> {
275275

276276
// SAFETY: the clone implementation is a copy, see above.
277277
#[unstable(feature = "trivial_clone", issue = "none")]
278-
unsafe impl<T> TrivialClone for MaybeUninit<T> where MaybeUninit<T>: Clone {}
278+
unsafe impl<T> TrivialClone for MaybeUninit<T> where MaybeUninit<T>: Copy {}
279279

280280
#[stable(feature = "maybe_uninit_debug", since = "1.41.0")]
281281
impl<T> fmt::Debug for MaybeUninit<T> {

library/core/src/slice/mod.rs

+25-38
Original file line numberDiff line numberDiff line change
@@ -3738,8 +3738,30 @@ impl<T> [T] {
37383738
where
37393739
T: Copy,
37403740
{
3741-
// SAFETY: `T` implements `Copy`.
3742-
unsafe { copy_from_slice_impl(self, src) }
3741+
// The panic code path was put into a cold function to not bloat the
3742+
// call site.
3743+
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
3744+
#[cfg_attr(feature = "panic_immediate_abort", inline)]
3745+
#[track_caller]
3746+
const fn len_mismatch_fail(dst_len: usize, src_len: usize) -> ! {
3747+
const_panic!(
3748+
"copy_from_slice: source slice length does not match destination slice length",
3749+
"copy_from_slice: source slice length ({src_len}) does not match destination slice length ({dst_len})",
3750+
src_len: usize,
3751+
dst_len: usize,
3752+
)
3753+
}
3754+
3755+
if self.len() != src.len() {
3756+
len_mismatch_fail(self.len(), src.len());
3757+
}
3758+
3759+
// SAFETY: `self` is valid for `self.len()` elements by definition, and `src` was
3760+
// checked to have the same length. The slices cannot overlap because
3761+
// mutable references are exclusive.
3762+
unsafe {
3763+
ptr::copy_nonoverlapping(src.as_ptr(), self.as_mut_ptr(), self.len());
3764+
}
37433765
}
37443766

37453767
/// Copies elements from one part of the slice to another part of itself,
@@ -4878,38 +4900,6 @@ impl [f64] {
48784900
}
48794901
}
48804902

4881-
/// Copies `src` to `dest`.
4882-
///
4883-
/// # Safety
4884-
/// `T` must implement one of `Copy` or `TrivialClone`.
4885-
#[track_caller]
4886-
const unsafe fn copy_from_slice_impl<T: Clone>(dest: &mut [T], src: &[T]) {
4887-
// The panic code path was put into a cold function to not bloat the
4888-
// call site.
4889-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
4890-
#[cfg_attr(feature = "panic_immediate_abort", inline)]
4891-
#[track_caller]
4892-
const fn len_mismatch_fail(dst_len: usize, src_len: usize) -> ! {
4893-
const_panic!(
4894-
"copy_from_slice: source slice length does not match destination slice length",
4895-
"copy_from_slice: source slice length ({src_len}) does not match destination slice length ({dst_len})",
4896-
src_len: usize,
4897-
dst_len: usize,
4898-
)
4899-
}
4900-
4901-
if dest.len() != src.len() {
4902-
len_mismatch_fail(dest.len(), src.len());
4903-
}
4904-
4905-
// SAFETY: `self` is valid for `self.len()` elements by definition, and `src` was
4906-
// checked to have the same length. The slices cannot overlap because
4907-
// mutable references are exclusive.
4908-
unsafe {
4909-
ptr::copy_nonoverlapping(src.as_ptr(), dest.as_mut_ptr(), dest.len());
4910-
}
4911-
}
4912-
49134903
trait CloneFromSpec<T> {
49144904
fn spec_clone_from(&mut self, src: &[T]);
49154905
}
@@ -4938,10 +4928,7 @@ where
49384928
{
49394929
#[track_caller]
49404930
fn spec_clone_from(&mut self, src: &[T]) {
4941-
// SAFETY: `T` implements `TrivialClone`.
4942-
unsafe {
4943-
copy_from_slice_impl(self, src);
4944-
}
4931+
self.copy_from_slice(src);
49454932
}
49464933
}
49474934

library/core/src/slice/specialize.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use crate::clone::TrivialClone;
2-
use crate::ptr;
32

43
pub(super) trait SpecFill<T> {
54
fn spec_fill(&mut self, value: T);
@@ -20,9 +19,7 @@ impl<T: Clone> SpecFill<T> for [T] {
2019
impl<T: TrivialClone> SpecFill<T> for [T] {
2120
fn spec_fill(&mut self, value: T) {
2221
for item in self.iter_mut() {
23-
// SAFETY: `TrivialClone` indicates that this is equivalent to
24-
// calling `Clone::clone`
25-
*item = unsafe { ptr::read(&value) };
22+
*item = value;
2623
}
2724
}
2825
}

0 commit comments

Comments
 (0)