Skip to content

Commit 6161a90

Browse files
committed
add impl const for Clone
1 parent e05ab47 commit 6161a90

File tree

11 files changed

+151
-28
lines changed

11 files changed

+151
-28
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
@@ -463,7 +463,9 @@ marker_impls! {
463463
// library, and there's no way to safely have this behavior right now.
464464
#[rustc_unsafe_specialization_marker]
465465
#[rustc_diagnostic_item = "Copy"]
466-
pub trait Copy: Clone {
466+
#[const_trait]
467+
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
468+
pub trait Copy: ~const Clone {
467469
// Empty.
468470
}
469471

@@ -853,10 +855,12 @@ impl<T: PointeeSized> cmp::Ord for PhantomData<T> {
853855
}
854856

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

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

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: 17 additions & 8 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};
@@ -3861,10 +3862,11 @@ impl<T> [T] {
38613862
/// [`copy_from_slice`]: slice::copy_from_slice
38623863
/// [`split_at_mut`]: slice::split_at_mut
38633864
#[stable(feature = "clone_from_slice", since = "1.7.0")]
3865+
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
38643866
#[track_caller]
3865-
pub fn clone_from_slice(&mut self, src: &[T])
3867+
pub const fn clone_from_slice(&mut self, src: &[T])
38663868
where
3867-
T: Clone,
3869+
T: ~const Clone + ~const Destruct,
38683870
{
38693871
self.spec_clone_from(src);
38703872
}
@@ -5164,13 +5166,16 @@ impl [f64] {
51645166
}
51655167
}
51665168

5169+
#[const_trait]
5170+
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
51675171
trait CloneFromSpec<T> {
51685172
fn spec_clone_from(&mut self, src: &[T]);
51695173
}
51705174

5171-
impl<T> CloneFromSpec<T> for [T]
5175+
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
5176+
impl<T> const CloneFromSpec<T> for [T]
51725177
where
5173-
T: Clone,
5178+
T: ~const Clone + ~const Destruct,
51745179
{
51755180
#[track_caller]
51765181
default fn spec_clone_from(&mut self, src: &[T]) {
@@ -5180,15 +5185,19 @@ where
51805185
// But since it can't be relied on we also have an explicit specialization for T: Copy.
51815186
let len = self.len();
51825187
let src = &src[..len];
5183-
for i in 0..len {
5184-
self[i].clone_from(&src[i]);
5188+
// FIXME(const_hack): make this a `for idx in 0..self.len()` loop.
5189+
let mut idx = 0;
5190+
while idx < self.len() {
5191+
self[idx].clone_from(&src[idx]);
5192+
idx += 1;
51855193
}
51865194
}
51875195
}
51885196

5189-
impl<T> CloneFromSpec<T> for [T]
5197+
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
5198+
impl<T> const CloneFromSpec<T> for [T]
51905199
where
5191-
T: Copy,
5200+
T: ~const Copy + ~const Destruct,
51925201
{
51935202
#[track_caller]
51945203
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},)+)
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#![feature(
2+
const_trait_impl, const_default, const_clone, ptr_alignment_type,
3+
ascii_char, f16, f128, sync_unsafe_cell,
4+
)]
5+
#![allow(dead_code)]
6+
// core::default
7+
const UNIT: () = Default::default();
8+
const BOOL: bool = Default::default();
9+
const CHAR: char = Default::default();
10+
const ASCII_CHAR: std::ascii::Char = Default::default();
11+
const USIZE: usize = Default::default();
12+
const U8: u8 = Default::default();
13+
const U16: u16 = Default::default();
14+
const U32: u32 = Default::default();
15+
const U64: u64 = Default::default();
16+
const U128: u128 = Default::default();
17+
const I8: i8 = Default::default();
18+
const I16: i16 = Default::default();
19+
const I32: i32 = Default::default();
20+
const I64: i64 = Default::default();
21+
const I128: i128 = Default::default();
22+
const F16: f16 = Default::default();
23+
const F32: f32 = Default::default();
24+
const F64: f64 = Default::default();
25+
const F128: f128 = Default::default();
26+
// core::marker
27+
const PHANTOM: std::marker::PhantomData<()> = Default::default();
28+
// core::option
29+
const OPT: Option<i32> = Default::default();
30+
// core::iter::sources::empty
31+
const EMPTY: std::iter::Empty<()> = Default::default();
32+
// core::ptr::alignment
33+
const ALIGNMENT: std::ptr::Alignment = Default::default();
34+
// core::slice
35+
const SLICE: &[()] = Default::default();
36+
const MUT_SLICE: &mut [()] = Default::default();
37+
// core::str
38+
const STR: &str = Default::default();
39+
const MUT_STR: &mut str = Default::default();
40+
// core::cell
41+
const CELL: std::cell::Cell<()> = Default::default();
42+
const REF_CELL: std::cell::RefCell<()> = Default::default();
43+
const UNSAFE_CELL: std::cell::UnsafeCell<()> = Default::default();
44+
const SYNC_UNSAFE_CELL: std::cell::SyncUnsafeCell<()> = Default::default();
45+
const TUPLE: (u8, u16, u32, u64, u128, i8) = Default::default();
46+
47+
// core::clone
48+
const UNIT_CLONE: () = UNIT.clone();
49+
//~^ ERROR: the trait bound `(): const Clone` is not satisfied
50+
const BOOL_CLONE: bool = BOOL.clone();
51+
const CHAR_CLONE: char = CHAR.clone();
52+
const ASCII_CHAR_CLONE: std::ascii::Char = ASCII_CHAR.clone();
53+
//~^ ERROR: the trait bound `Char: const Clone` is not satisfied
54+
const USIZE_CLONE: usize = USIZE.clone();
55+
const U8_CLONE: u8 = U8.clone();
56+
const U16_CLONE: u16 = U16.clone();
57+
const U32_CLONE: u32 = U32.clone();
58+
const U64_CLONE: u64 = U64.clone();
59+
const U128_CLONE: u128 = U128.clone();
60+
const I8_CLONE: i8 = I8.clone();
61+
const I16_CLONE: i16 = I16.clone();
62+
const I32_CLONE: i32 = I32.clone();
63+
const I64_CLONE: i64 = I64.clone();
64+
const I128_CLONE: i128 = I128.clone();
65+
const F16_CLONE: f16 = F16.clone();
66+
const F32_CLONE: f32 = F32.clone();
67+
const F64_CLONE: f64 = F64.clone();
68+
const F128_CLONE: f128 = F128.clone();
69+
const TUPLE_CLONE: (u8, u16, u32, u64, u128, i8) = TUPLE.clone();
70+
//~^ ERROR: the trait bound `(u8, u16, u32, u64, u128, i8): const Clone` is not satisfied [E0277]
71+
72+
fn main() {}

0 commit comments

Comments
 (0)