Skip to content

Commit c38ee77

Browse files
committed
add impl const for Clone
1 parent a980cd4 commit c38ee77

File tree

9 files changed

+66
-30
lines changed

9 files changed

+66
-30
lines changed

library/core/src/clone.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,8 @@ mod impls {
543543
($($t:ty)*) => {
544544
$(
545545
#[stable(feature = "rust1", since = "1.0.0")]
546-
impl Clone for $t {
546+
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
547+
impl const Clone for $t {
547548
#[inline(always)]
548549
fn clone(&self) -> Self {
549550
*self
@@ -561,23 +562,26 @@ mod impls {
561562
}
562563

563564
#[unstable(feature = "never_type", issue = "35121")]
564-
impl Clone for ! {
565+
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
566+
impl const Clone for ! {
565567
#[inline]
566568
fn clone(&self) -> Self {
567569
*self
568570
}
569571
}
570572

571573
#[stable(feature = "rust1", since = "1.0.0")]
572-
impl<T: PointeeSized> Clone for *const T {
574+
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
575+
impl<T: PointeeSized> const Clone for *const T {
573576
#[inline(always)]
574577
fn clone(&self) -> Self {
575578
*self
576579
}
577580
}
578581

579582
#[stable(feature = "rust1", since = "1.0.0")]
580-
impl<T: PointeeSized> Clone for *mut T {
583+
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
584+
impl<T: PointeeSized> const Clone for *mut T {
581585
#[inline(always)]
582586
fn clone(&self) -> Self {
583587
*self
@@ -586,7 +590,8 @@ mod impls {
586590

587591
/// Shared references can be cloned, but mutable references *cannot*!
588592
#[stable(feature = "rust1", since = "1.0.0")]
589-
impl<T: PointeeSized> Clone for &T {
593+
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
594+
impl<T: PointeeSized> const Clone for &T {
590595
#[inline(always)]
591596
#[rustc_diagnostic_item = "noop_method_clone"]
592597
fn clone(&self) -> Self {

library/core/src/marker.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,9 @@ marker_impls! {
462462
// library, and there's no way to safely have this behavior right now.
463463
#[rustc_unsafe_specialization_marker]
464464
#[rustc_diagnostic_item = "Copy"]
465-
pub trait Copy: Clone {
465+
#[const_trait]
466+
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
467+
pub trait Copy: [const] Clone {
466468
// Empty.
467469
}
468470

@@ -852,10 +854,12 @@ impl<T: PointeeSized> cmp::Ord for PhantomData<T> {
852854
}
853855

854856
#[stable(feature = "rust1", since = "1.0.0")]
855-
impl<T: PointeeSized> Copy for PhantomData<T> {}
857+
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
858+
impl<T: PointeeSized> const Copy for PhantomData<T> {}
856859

857860
#[stable(feature = "rust1", since = "1.0.0")]
858-
impl<T: PointeeSized> Clone for PhantomData<T> {
861+
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
862+
impl<T: PointeeSized> const Clone for PhantomData<T> {
859863
fn clone(&self) -> Self {
860864
Self
861865
}

library/core/src/num/bignum.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,8 @@ macro_rules! define_bignum {
398398
}
399399
}
400400

401-
impl crate::clone::Clone for $name {
401+
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
402+
impl const crate::clone::Clone for $name {
402403
fn clone(&self) -> Self {
403404
Self { size: self.size, base: self.base }
404405
}

library/core/src/num/niche_types.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ macro_rules! define_valid_range_type {
1414
$(#[$m:meta])*
1515
$vis:vis struct $name:ident($int:ident as $uint:ident in $low:literal..=$high:literal);
1616
)+) => {$(
17-
#[derive(Clone, Copy, Eq)]
17+
#[derive(Eq)]
18+
#[derive_const(Clone, Copy)]
1819
#[repr(transparent)]
1920
#[rustc_layout_scalar_valid_range_start($low)]
2021
#[rustc_layout_scalar_valid_range_end($high)]

library/core/src/ops/control_flow.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ use crate::{convert, ops};
8383
#[must_use]
8484
// ControlFlow should not implement PartialOrd or Ord, per RFC 3058:
8585
// https://rust-lang.github.io/rfcs/3058-try-trait-v2.html#traits-for-controlflow
86-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
86+
#[derive(Debug, Eq, Hash)]
87+
#[derive_const(Clone, Copy, PartialEq)]
8788
pub enum ControlFlow<B, C = ()> {
8889
/// Move on to the next phase of the operation as normal.
8990
#[stable(feature = "control_flow_enum_type", since = "1.55.0")]

library/core/src/ops/index_range.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ use crate::ub_checks;
99
///
1010
/// (Normal `Range` code needs to handle degenerate ranges like `10..0`,
1111
/// which takes extra checks compared to only handling the canonical form.)
12-
#[derive(Clone, Debug, PartialEq, Eq)]
12+
#[derive(Debug, Eq)]
13+
#[derive_const(Clone, PartialEq)]
1314
pub(crate) struct IndexRange {
1415
start: usize,
1516
end: usize,

library/core/src/ops/range.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ use crate::hash::Hash;
3838
/// [slicing index]: crate::slice::SliceIndex
3939
#[lang = "RangeFull"]
4040
#[doc(alias = "..")]
41-
#[derive(Copy, Clone, Default, PartialEq, Eq, Hash)]
41+
#[derive(Eq, Hash)]
42+
#[derive_const(Copy, Clone, Default, PartialEq)]
4243
#[stable(feature = "rust1", since = "1.0.0")]
4344
pub struct RangeFull;
4445

@@ -75,7 +76,8 @@ impl fmt::Debug for RangeFull {
7576
/// ```
7677
#[lang = "Range"]
7778
#[doc(alias = "..")]
78-
#[derive(Clone, Default, PartialEq, Eq, Hash)] // not Copy -- see #27186
79+
#[derive(Eq, Hash)]
80+
#[derive_const(Clone, Default, PartialEq)] // not Copy -- see #27186
7981
#[stable(feature = "rust1", since = "1.0.0")]
8082
pub struct Range<Idx> {
8183
/// The lower bound of the range (inclusive).
@@ -184,7 +186,8 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
184186
/// ```
185187
#[lang = "RangeFrom"]
186188
#[doc(alias = "..")]
187-
#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
189+
#[derive(Eq, Hash)]
190+
#[derive_const(Clone, PartialEq)] // not Copy -- see #27186
188191
#[stable(feature = "rust1", since = "1.0.0")]
189192
pub struct RangeFrom<Idx> {
190193
/// The lower bound of the range (inclusive).
@@ -266,7 +269,8 @@ impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> {
266269
/// [slicing index]: crate::slice::SliceIndex
267270
#[lang = "RangeTo"]
268271
#[doc(alias = "..")]
269-
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
272+
#[derive(Eq, Hash)]
273+
#[derive_const(Copy, Clone, PartialEq)]
270274
#[stable(feature = "rust1", since = "1.0.0")]
271275
pub struct RangeTo<Idx> {
272276
/// The upper bound of the range (exclusive).
@@ -340,7 +344,8 @@ impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
340344
/// ```
341345
#[lang = "RangeInclusive"]
342346
#[doc(alias = "..=")]
343-
#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
347+
#[derive(Eq, Hash)]
348+
#[derive_const(Clone, PartialEq)] // not Copy -- see #27186
344349
#[stable(feature = "inclusive_range", since = "1.26.0")]
345350
pub struct RangeInclusive<Idx> {
346351
// Note that the fields here are not public to allow changing the
@@ -587,7 +592,8 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
587592
/// [slicing index]: crate::slice::SliceIndex
588593
#[lang = "RangeToInclusive"]
589594
#[doc(alias = "..=")]
590-
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
595+
#[derive(Hash)]
596+
#[derive(Copy, Clone, PartialEq, Eq)]
591597
#[stable(feature = "inclusive_range", since = "1.26.0")]
592598
pub struct RangeToInclusive<Idx> {
593599
/// The upper bound of the range (inclusive)
@@ -668,7 +674,8 @@ impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {
668674
///
669675
/// [`BTreeMap::range`]: ../../std/collections/btree_map/struct.BTreeMap.html#method.range
670676
#[stable(feature = "collections_bound", since = "1.17.0")]
671-
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
677+
#[derive(Debug, Eq, Hash)]
678+
#[derive_const(Clone, Copy, PartialEq)]
672679
pub enum Bound<T> {
673680
/// An inclusive bound.
674681
#[stable(feature = "collections_bound", since = "1.17.0")]

library/core/src/slice/mod.rs

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
use crate::cmp::Ordering::{self, Equal, Greater, Less};
1010
use crate::intrinsics::{exact_div, unchecked_sub};
11+
use crate::marker::Destruct;
1112
use crate::mem::{self, MaybeUninit, SizedTypeProperties};
1213
use crate::num::NonZero;
1314
use crate::ops::{OneSidedRange, OneSidedRangeBound, Range, RangeBounds, RangeInclusive};
@@ -3785,10 +3786,12 @@ impl<T> [T] {
37853786
/// [`copy_from_slice`]: slice::copy_from_slice
37863787
/// [`split_at_mut`]: slice::split_at_mut
37873788
#[stable(feature = "clone_from_slice", since = "1.7.0")]
3789+
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
3790+
#[rustc_allow_const_fn_unstable(const_precise_live_drops)]
37883791
#[track_caller]
3789-
pub fn clone_from_slice(&mut self, src: &[T])
3792+
pub const fn clone_from_slice(&mut self, src: &[T])
37903793
where
3791-
T: Clone,
3794+
T: [const] Clone + [const] Destruct,
37923795
{
37933796
self.spec_clone_from(src);
37943797
}
@@ -5089,31 +5092,43 @@ impl [f64] {
50895092
}
50905093
}
50915094

5095+
#[const_trait]
5096+
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
50925097
trait CloneFromSpec<T> {
5093-
fn spec_clone_from(&mut self, src: &[T]);
5098+
fn spec_clone_from(&mut self, src: &[T])
5099+
where
5100+
T: [const] Destruct;
50945101
}
50955102

5096-
impl<T> CloneFromSpec<T> for [T]
5103+
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
5104+
impl<T> const CloneFromSpec<T> for [T]
50975105
where
5098-
T: Clone,
5106+
T: [const] Clone,
50995107
{
51005108
#[track_caller]
5101-
default fn spec_clone_from(&mut self, src: &[T]) {
5109+
default fn spec_clone_from(&mut self, src: &[T])
5110+
where
5111+
T: [const] Destruct,
5112+
{
51025113
assert!(self.len() == src.len(), "destination and source slices have different lengths");
51035114
// NOTE: We need to explicitly slice them to the same length
51045115
// to make it easier for the optimizer to elide bounds checking.
51055116
// But since it can't be relied on we also have an explicit specialization for T: Copy.
51065117
let len = self.len();
51075118
let src = &src[..len];
5108-
for i in 0..len {
5109-
self[i].clone_from(&src[i]);
5119+
// FIXME(const_hack): make this a `for idx in 0..self.len()` loop.
5120+
let mut idx = 0;
5121+
while idx < self.len() {
5122+
self[idx].clone_from(&src[idx]);
5123+
idx += 1;
51105124
}
51115125
}
51125126
}
51135127

5114-
impl<T> CloneFromSpec<T> for [T]
5128+
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
5129+
impl<T> const CloneFromSpec<T> for [T]
51155130
where
5116-
T: Copy,
5131+
T: [const] Copy,
51175132
{
51185133
#[track_caller]
51195134
fn spec_clone_from(&mut self, src: &[T]) {

library/core/src/tuple.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ macro_rules! tuple_impls {
122122
maybe_tuple_doc! {
123123
$($T)+ @
124124
#[stable(feature = "rust1", since = "1.0.0")]
125-
impl<$($T: Default),+> Default for ($($T,)+) {
125+
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
126+
impl<$($T: ~const Default),+> const Default for ($($T,)+) {
126127
#[inline]
127128
fn default() -> ($($T,)+) {
128129
($({ let x: $T = Default::default(); x},)+)

0 commit comments

Comments
 (0)