Rollup merge of #147938 - const-clone-slice, r=tgross35
Add const cloning of slices and tests As discussed in https://github.com/rust-lang/rust/pull/143628#discussion_r2390170336, splitting off slice cloning as a separate PR. r? @tgross35
This commit is contained in:
commit
807a5cefd2
3 changed files with 94 additions and 10 deletions
|
|
@ -9,6 +9,7 @@
|
|||
use crate::clone::TrivialClone;
|
||||
use crate::cmp::Ordering::{self, Equal, Greater, Less};
|
||||
use crate::intrinsics::{exact_div, unchecked_sub};
|
||||
use crate::marker::Destruct;
|
||||
use crate::mem::{self, MaybeUninit, SizedTypeProperties};
|
||||
use crate::num::NonZero;
|
||||
use crate::ops::{OneSidedRange, OneSidedRangeBound, Range, RangeBounds, RangeInclusive};
|
||||
|
|
@ -4036,9 +4037,10 @@ impl<T> [T] {
|
|||
/// [`split_at_mut`]: slice::split_at_mut
|
||||
#[stable(feature = "clone_from_slice", since = "1.7.0")]
|
||||
#[track_caller]
|
||||
pub fn clone_from_slice(&mut self, src: &[T])
|
||||
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
|
||||
pub const fn clone_from_slice(&mut self, src: &[T])
|
||||
where
|
||||
T: Clone,
|
||||
T: [const] Clone + [const] Destruct,
|
||||
{
|
||||
self.spec_clone_from(src);
|
||||
}
|
||||
|
|
@ -5367,13 +5369,17 @@ const unsafe fn copy_from_slice_impl<T: Clone>(dest: &mut [T], src: &[T]) {
|
|||
}
|
||||
}
|
||||
|
||||
trait CloneFromSpec<T> {
|
||||
fn spec_clone_from(&mut self, src: &[T]);
|
||||
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
|
||||
const trait CloneFromSpec<T> {
|
||||
fn spec_clone_from(&mut self, src: &[T])
|
||||
where
|
||||
T: [const] Destruct;
|
||||
}
|
||||
|
||||
impl<T> CloneFromSpec<T> for [T]
|
||||
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
|
||||
impl<T> const CloneFromSpec<T> for [T]
|
||||
where
|
||||
T: Clone,
|
||||
T: [const] Clone + [const] Destruct,
|
||||
{
|
||||
#[track_caller]
|
||||
default fn spec_clone_from(&mut self, src: &[T]) {
|
||||
|
|
@ -5383,15 +5389,19 @@ where
|
|||
// But since it can't be relied on we also have an explicit specialization for T: Copy.
|
||||
let len = self.len();
|
||||
let src = &src[..len];
|
||||
for i in 0..len {
|
||||
self[i].clone_from(&src[i]);
|
||||
// FIXME(const_hack): make this a `for idx in 0..self.len()` loop.
|
||||
let mut idx = 0;
|
||||
while idx < self.len() {
|
||||
self[idx].clone_from(&src[idx]);
|
||||
idx += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> CloneFromSpec<T> for [T]
|
||||
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
|
||||
impl<T> const CloneFromSpec<T> for [T]
|
||||
where
|
||||
T: TrivialClone,
|
||||
T: [const] TrivialClone + [const] Destruct,
|
||||
{
|
||||
#[track_caller]
|
||||
fn spec_clone_from(&mut self, src: &[T]) {
|
||||
|
|
|
|||
|
|
@ -121,3 +121,74 @@ fn cstr_metadata_is_length_with_nul() {
|
|||
let bytes: *const [u8] = p as *const [u8];
|
||||
assert_eq!(s.to_bytes_with_nul().len(), bytes.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_const_clone() {
|
||||
const {
|
||||
let bool: bool = Default::default();
|
||||
let char: char = Default::default();
|
||||
let ascii_char: std::ascii::Char = Default::default();
|
||||
let usize: usize = Default::default();
|
||||
let u8: u8 = Default::default();
|
||||
let u16: u16 = Default::default();
|
||||
let u32: u32 = Default::default();
|
||||
let u64: u64 = Default::default();
|
||||
let u128: u128 = Default::default();
|
||||
let i8: i8 = Default::default();
|
||||
let i16: i16 = Default::default();
|
||||
let i32: i32 = Default::default();
|
||||
let i64: i64 = Default::default();
|
||||
let i128: i128 = Default::default();
|
||||
let f16: f16 = Default::default();
|
||||
let f32: f32 = Default::default();
|
||||
let f64: f64 = Default::default();
|
||||
let f128: f128 = Default::default();
|
||||
|
||||
let bool_clone: bool = bool.clone();
|
||||
let char_clone: char = char.clone();
|
||||
let ascii_char_clone: std::ascii::Char = ascii_char.clone();
|
||||
|
||||
let usize_clone: usize = usize.clone();
|
||||
let u8_clone: u8 = u8.clone();
|
||||
let u16_clone: u16 = u16.clone();
|
||||
let u32_clone: u32 = u32.clone();
|
||||
let u64_clone: u64 = u64.clone();
|
||||
let u128_clone: u128 = u128.clone();
|
||||
let i8_clone: i8 = i8.clone();
|
||||
let i16_clone: i16 = i16.clone();
|
||||
let i32_clone: i32 = i32.clone();
|
||||
let i64_clone: i64 = i64.clone();
|
||||
let i128_clone: i128 = i128.clone();
|
||||
let f16_clone: f16 = f16.clone();
|
||||
let f32_clone: f32 = f32.clone();
|
||||
let f64_clone: f64 = f64.clone();
|
||||
let f128_clone: f128 = f128.clone();
|
||||
|
||||
assert!(bool == bool_clone);
|
||||
assert!(char == char_clone);
|
||||
assert!(ascii_char == ascii_char_clone);
|
||||
assert!(usize == usize_clone);
|
||||
assert!(u8 == u8_clone);
|
||||
assert!(u16 == u16_clone);
|
||||
assert!(u32 == u32_clone);
|
||||
assert!(u64 == u64_clone);
|
||||
assert!(u128 == u128_clone);
|
||||
assert!(i8 == i8_clone);
|
||||
assert!(i16 == i16_clone);
|
||||
assert!(i32 == i32_clone);
|
||||
assert!(i64 == i64_clone);
|
||||
assert!(i128 == i128_clone);
|
||||
assert!(f16 == f16_clone);
|
||||
assert!(f32 == f32_clone);
|
||||
assert!(f64 == f64_clone);
|
||||
assert!(f128 == f128_clone);
|
||||
|
||||
let src: [i32; 4] = [1, 2, 3, 4];
|
||||
let mut dst: [i32; 2] = [0, 0];
|
||||
|
||||
dst.clone_from_slice(&src[2..]);
|
||||
|
||||
assert!(src == [1, 2, 3, 4]);
|
||||
assert!(dst == [3, 4]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,11 +19,14 @@
|
|||
#![feature(clone_to_uninit)]
|
||||
#![feature(const_array)]
|
||||
#![feature(const_cell_traits)]
|
||||
#![feature(const_clone)]
|
||||
#![feature(const_cmp)]
|
||||
#![feature(const_convert)]
|
||||
#![feature(const_default)]
|
||||
#![feature(const_destruct)]
|
||||
#![feature(const_drop_in_place)]
|
||||
#![feature(const_eval_select)]
|
||||
#![feature(const_index)]
|
||||
#![feature(const_ops)]
|
||||
#![feature(const_option_ops)]
|
||||
#![feature(const_ref_cell)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue