diff options
| author | bors <bors@rust-lang.org> | 2020-12-30 12:43:02 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-12-30 12:43:02 +0000 |
| commit | bbcaed03bf5505f3fed351887769ed1531599502 (patch) | |
| tree | 1934000322455e6fb61afe0c5956c05ad0090eb2 /library | |
| parent | d107a87d34c1fc3521aaab7a2576ffbaf59cb2cb (diff) | |
| parent | 0cea1c9206388edccf9132543df1ab2da00daaaa (diff) | |
| download | rust-bbcaed03bf5505f3fed351887769ed1531599502.tar.gz rust-bbcaed03bf5505f3fed351887769ed1531599502.zip | |
Auto merge of #79684 - usbalbin:const_copy, r=oli-obk
Make copy[_nonoverlapping] const Constifies * `intrinsics::copy` and `intrinsics::copy_nonoverlapping` * `ptr::read` and `ptr::read_unaligned` * `*const T::read` and `*const T::read_unaligned` * `*mut T::read` and `*mut T::read_unaligned` * `MaybeUninit::assume_init_read`
Diffstat (limited to 'library')
| -rw-r--r-- | library/core/src/intrinsics.rs | 17 | ||||
| -rw-r--r-- | library/core/src/lib.rs | 2 | ||||
| -rw-r--r-- | library/core/src/mem/maybe_uninit.rs | 3 | ||||
| -rw-r--r-- | library/core/src/ptr/const_ptr.rs | 6 | ||||
| -rw-r--r-- | library/core/src/ptr/mod.rs | 6 | ||||
| -rw-r--r-- | library/core/src/ptr/mut_ptr.rs | 6 | ||||
| -rw-r--r-- | library/core/tests/const_ptr.rs | 51 | ||||
| -rw-r--r-- | library/core/tests/lib.rs | 7 | ||||
| -rw-r--r-- | library/core/tests/mem.rs | 7 |
9 files changed, 92 insertions, 13 deletions
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 52921822693..87863ab5c68 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1846,20 +1846,22 @@ pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) - /// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append #[doc(alias = "memcpy")] #[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "none")] #[inline] -pub unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) { +pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) { extern "rust-intrinsic" { fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize); } - if cfg!(debug_assertions) + // FIXME: Perform these checks only at run time + /*if cfg!(debug_assertions) && !(is_aligned_and_not_null(src) && is_aligned_and_not_null(dst) && is_nonoverlapping(src, dst, count)) { // Not panicking to keep codegen impact smaller. abort(); - } + }*/ // SAFETY: the safety contract for `copy_nonoverlapping` must be // upheld by the caller. @@ -1928,16 +1930,19 @@ pub unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) { /// ``` #[doc(alias = "memmove")] #[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "none")] #[inline] -pub unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) { +pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) { extern "rust-intrinsic" { + #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "none")] fn copy<T>(src: *const T, dst: *mut T, count: usize); } - if cfg!(debug_assertions) && !(is_aligned_and_not_null(src) && is_aligned_and_not_null(dst)) { + // FIXME: Perform these checks only at run time + /*if cfg!(debug_assertions) && !(is_aligned_and_not_null(src) && is_aligned_and_not_null(dst)) { // Not panicking to keep codegen impact smaller. abort(); - } + }*/ // SAFETY: the safety contract for `copy` must be upheld by the caller. unsafe { copy(src, dst, count) } diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 5b19bf6b80f..4a3020d6b99 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -73,6 +73,7 @@ #![feature(const_assert_type)] #![feature(const_discriminant)] #![feature(const_cell_into_inner)] +#![feature(const_intrinsic_copy)] #![feature(const_checked_int_methods)] #![feature(const_euclidean_int_methods)] #![feature(const_float_classify)] @@ -93,6 +94,7 @@ #![feature(const_precise_live_drops)] #![feature(const_ptr_offset)] #![feature(const_ptr_offset_from)] +#![feature(const_ptr_read)] #![feature(const_raw_ptr_comparison)] #![feature(const_raw_ptr_deref)] #![feature(const_slice_from_raw_parts)] diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 57e0bb1499b..b2a4d897eed 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -575,8 +575,9 @@ impl<T> MaybeUninit<T> { /// // they both get dropped! /// ``` #[unstable(feature = "maybe_uninit_extra", issue = "63567")] + #[rustc_const_unstable(feature = "maybe_uninit_extra", issue = "63567")] #[inline(always)] - pub unsafe fn assume_init_read(&self) -> T { + pub const unsafe fn assume_init_read(&self) -> T { // SAFETY: the caller must guarantee that `self` is initialized. // Reading from `self.as_ptr()` is safe since `self` should be initialized. unsafe { diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 38519f759ae..66300116786 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -745,8 +745,9 @@ impl<T: ?Sized> *const T { /// /// [`ptr::read`]: crate::ptr::read() #[stable(feature = "pointer_methods", since = "1.26.0")] + #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")] #[inline] - pub unsafe fn read(self) -> T + pub const unsafe fn read(self) -> T where T: Sized, { @@ -783,8 +784,9 @@ impl<T: ?Sized> *const T { /// /// [`ptr::read_unaligned`]: crate::ptr::read_unaligned() #[stable(feature = "pointer_methods", since = "1.26.0")] + #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")] #[inline] - pub unsafe fn read_unaligned(self) -> T + pub const unsafe fn read_unaligned(self) -> T where T: Sized, { diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 27d49529a5e..807f114ea46 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -685,7 +685,8 @@ pub unsafe fn replace<T>(dst: *mut T, mut src: T) -> T { /// [valid]: self#safety #[inline] #[stable(feature = "rust1", since = "1.0.0")] -pub unsafe fn read<T>(src: *const T) -> T { +#[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")] +pub const unsafe fn read<T>(src: *const T) -> T { // `copy_nonoverlapping` takes care of debug_assert. let mut tmp = MaybeUninit::<T>::uninit(); // SAFETY: the caller must guarantee that `src` is valid for reads. @@ -784,7 +785,8 @@ pub unsafe fn read<T>(src: *const T) -> T { /// ``` #[inline] #[stable(feature = "ptr_unaligned", since = "1.17.0")] -pub unsafe fn read_unaligned<T>(src: *const T) -> T { +#[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")] +pub const unsafe fn read_unaligned<T>(src: *const T) -> T { // `copy_nonoverlapping` takes care of debug_assert. let mut tmp = MaybeUninit::<T>::uninit(); // SAFETY: the caller must guarantee that `src` is valid for reads. diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 92f4e431de4..785bf70c299 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -852,8 +852,9 @@ impl<T: ?Sized> *mut T { /// /// [`ptr::read`]: crate::ptr::read() #[stable(feature = "pointer_methods", since = "1.26.0")] + #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")] #[inline] - pub unsafe fn read(self) -> T + pub const unsafe fn read(self) -> T where T: Sized, { @@ -890,8 +891,9 @@ impl<T: ?Sized> *mut T { /// /// [`ptr::read_unaligned`]: crate::ptr::read_unaligned() #[stable(feature = "pointer_methods", since = "1.26.0")] + #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")] #[inline] - pub unsafe fn read_unaligned(self) -> T + pub const unsafe fn read_unaligned(self) -> T where T: Sized, { diff --git a/library/core/tests/const_ptr.rs b/library/core/tests/const_ptr.rs new file mode 100644 index 00000000000..4acd059ab03 --- /dev/null +++ b/library/core/tests/const_ptr.rs @@ -0,0 +1,51 @@ +// Aligned to two bytes +const DATA: [u16; 2] = [u16::from_ne_bytes([0x01, 0x23]), u16::from_ne_bytes([0x45, 0x67])]; + +const fn unaligned_ptr() -> *const u16 { + // Since DATA.as_ptr() is aligned to two bytes, adding 1 byte to that produces an unaligned *const u16 + unsafe { (DATA.as_ptr() as *const u8).add(1) as *const u16 } +} + +#[test] +fn read() { + use core::ptr; + + const FOO: i32 = unsafe { ptr::read(&42 as *const i32) }; + assert_eq!(FOO, 42); + + const ALIGNED: i32 = unsafe { ptr::read_unaligned(&42 as *const i32) }; + assert_eq!(ALIGNED, 42); + + const UNALIGNED_PTR: *const u16 = unaligned_ptr(); + + const UNALIGNED: u16 = unsafe { ptr::read_unaligned(UNALIGNED_PTR) }; + assert_eq!(UNALIGNED, u16::from_ne_bytes([0x23, 0x45])); +} + +#[test] +fn const_ptr_read() { + const FOO: i32 = unsafe { (&42 as *const i32).read() }; + assert_eq!(FOO, 42); + + const ALIGNED: i32 = unsafe { (&42 as *const i32).read_unaligned() }; + assert_eq!(ALIGNED, 42); + + const UNALIGNED_PTR: *const u16 = unaligned_ptr(); + + const UNALIGNED: u16 = unsafe { UNALIGNED_PTR.read_unaligned() }; + assert_eq!(UNALIGNED, u16::from_ne_bytes([0x23, 0x45])); +} + +#[test] +fn mut_ptr_read() { + const FOO: i32 = unsafe { (&42 as *const i32 as *mut i32).read() }; + assert_eq!(FOO, 42); + + const ALIGNED: i32 = unsafe { (&42 as *const i32 as *mut i32).read_unaligned() }; + assert_eq!(ALIGNED, 42); + + const UNALIGNED_PTR: *mut u16 = unaligned_ptr() as *mut u16; + + const UNALIGNED: u16 = unsafe { UNALIGNED_PTR.read_unaligned() }; + assert_eq!(UNALIGNED, u16::from_ne_bytes([0x23, 0x45])); +} diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 2828235c3e3..9e8ec706021 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -13,6 +13,8 @@ #![feature(const_assume)] #![feature(const_cell_into_inner)] #![feature(const_maybe_uninit_assume_init)] +#![feature(const_ptr_read)] +#![feature(const_ptr_offset)] #![feature(core_intrinsics)] #![feature(core_private_bignum)] #![feature(core_private_diy_float)] @@ -34,6 +36,7 @@ #![feature(raw)] #![feature(sort_internals)] #![feature(slice_partition_at_index)] +#![feature(maybe_uninit_extra)] #![feature(maybe_uninit_write_slice)] #![feature(min_specialization)] #![feature(step_trait)] @@ -82,6 +85,10 @@ mod cell; mod char; mod clone; mod cmp; + +#[cfg(not(bootstrap))] +mod const_ptr; + mod fmt; mod hash; mod intrinsics; diff --git a/library/core/tests/mem.rs b/library/core/tests/mem.rs index 5d0fedd4d9c..a09a2e91804 100644 --- a/library/core/tests/mem.rs +++ b/library/core/tests/mem.rs @@ -267,3 +267,10 @@ fn uninit_write_slice_cloned_no_drop() { forget(src); } + +#[test] +#[cfg(not(bootstrap))] +fn uninit_const_assume_init_read() { + const FOO: u32 = unsafe { MaybeUninit::new(42).assume_init_read() }; + assert_eq!(FOO, 42); +} |
