diff options
| author | bors <bors@rust-lang.org> | 2024-03-11 10:22:10 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-03-11 10:22:10 +0000 |
| commit | e919669d42dfb8950866d4cb268c5359eb3f7c54 (patch) | |
| tree | 08ac6de3309dc8a896699d04b1b1739bd6e413d4 /library | |
| parent | 66396725541ac7920439876fc79cbc7b604b82e0 (diff) | |
| parent | 5a3d6c91b1892806b0cdda8b03e5ceef64a1989f (diff) | |
Auto merge of #122331 - jhpratt:rollup-cbl8xsy, r=jhpratt
Rollup of 9 pull requests
Successful merges:
- #121148 (Add slice::try_range)
- #121633 (Win10: Use `GetSystemTimePreciseAsFileTime` directly)
- #121840 (Expose the Freeze trait again (unstably) and forbid implementing it manually)
- #121907 (skip sanity check for non-host targets in `check` builds)
- #122002 (std::threads: revisit stack address calculation on netbsd.)
- #122108 (Add `target.*.runner` configuration for targets)
- #122298 (RawVec::into_box: avoid unnecessary intermediate reference)
- #122315 (Allow multiple `impl Into<{D,Subd}iagMessage>` parameters in a function.)
- #122326 (Optimize `process_heap_alloc`)
r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'library')
| -rw-r--r-- | library/alloc/src/raw_vec.rs | 3 | ||||
| -rw-r--r-- | library/alloc/src/slice.rs | 4 | ||||
| -rw-r--r-- | library/core/src/lib.rs | 1 | ||||
| -rw-r--r-- | library/core/src/marker.rs | 10 | ||||
| -rw-r--r-- | library/core/src/slice/index.rs | 59 | ||||
| -rw-r--r-- | library/core/src/slice/mod.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/thread.rs | 5 | ||||
| -rw-r--r-- | library/std/src/sys/pal/windows/alloc.rs | 55 | ||||
| -rw-r--r-- | library/std/src/sys/pal/windows/c.rs | 1 | ||||
| -rw-r--r-- | library/std/src/sys/pal/windows/c/bindings.txt | 1 | ||||
| -rw-r--r-- | library/std/src/sys/pal/windows/c/windows_sys.rs | 4 |
11 files changed, 113 insertions, 32 deletions
diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index ace73c0fdaa..0ee293db73a 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -5,7 +5,6 @@ use core::cmp; use core::hint; use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties}; use core::ptr::{self, NonNull, Unique}; -use core::slice; #[cfg(not(no_global_oom_handling))] use crate::alloc::handle_alloc_error; @@ -192,7 +191,7 @@ impl<T, A: Allocator> RawVec<T, A> { let me = ManuallyDrop::new(self); unsafe { - let slice = slice::from_raw_parts_mut(me.ptr() as *mut MaybeUninit<T>, len); + let slice = ptr::slice_from_raw_parts_mut(me.ptr() as *mut MaybeUninit<T>, len); Box::from_raw_in(slice, ptr::read(&me.alloc)) } } diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index f4e392760c8..21d5dce04a0 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -33,8 +33,6 @@ use crate::vec::Vec; #[cfg(test)] mod tests; -#[unstable(feature = "slice_range", issue = "76393")] -pub use core::slice::range; #[unstable(feature = "array_chunks", issue = "74985")] pub use core::slice::ArrayChunks; #[unstable(feature = "array_chunks", issue = "74985")] @@ -51,6 +49,8 @@ pub use core::slice::{from_mut, from_ref}; pub use core::slice::{from_mut_ptr_range, from_ptr_range}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::slice::{from_raw_parts, from_raw_parts_mut}; +#[unstable(feature = "slice_range", issue = "76393")] +pub use core::slice::{range, try_range}; #[stable(feature = "slice_group_by", since = "1.77.0")] pub use core::slice::{ChunkBy, ChunkByMut}; #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 0f7885769c2..6bcf7c13e64 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -204,6 +204,7 @@ // tidy-alphabetical-start #![cfg_attr(bootstrap, feature(diagnostic_namespace))] #![cfg_attr(bootstrap, feature(platform_intrinsics))] +#![cfg_attr(not(bootstrap), feature(freeze_impls))] #![feature(abi_unadjusted)] #![feature(adt_const_params)] #![feature(allow_internal_unsafe)] diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 2e22129d7b6..a56a2578c22 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -810,15 +810,21 @@ pub trait DiscriminantKind { type Discriminant: Clone + Copy + Debug + Eq + PartialEq + Hash + Send + Sync + Unpin; } -/// Compiler-internal trait used to determine whether a type contains +/// Used to determine whether a type contains /// any `UnsafeCell` internally, but not through an indirection. /// This affects, for example, whether a `static` of that type is /// placed in read-only static memory or writable static memory. +/// This can be used to declare that a constant with a generic type +/// will not contain interior mutability, and subsequently allow +/// placing the constant behind references. #[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} +#[unstable(feature = "freeze", issue = "121675")] +pub unsafe auto trait Freeze {} +#[unstable(feature = "freeze", issue = "121675")] impl<T: ?Sized> !Freeze for UnsafeCell<T> {} marker_impls! { + #[unstable(feature = "freeze", issue = "121675")] unsafe Freeze for {T: ?Sized} PhantomData<T>, {T: ?Sized} *const T, diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index 33c2769591d..64f1f360821 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -704,8 +704,7 @@ where { let len = bounds.end; - let start: ops::Bound<&usize> = range.start_bound(); - let start = match start { + let start = match range.start_bound() { ops::Bound::Included(&start) => start, ops::Bound::Excluded(start) => { start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail()) @@ -713,8 +712,7 @@ where ops::Bound::Unbounded => 0, }; - let end: ops::Bound<&usize> = range.end_bound(); - let end = match end { + let end = match range.end_bound() { ops::Bound::Included(end) => { end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail()) } @@ -732,6 +730,59 @@ where ops::Range { start, end } } +/// Performs bounds-checking of a range without panicking. +/// +/// This is a version of [`range`] that returns [`None`] instead of panicking. +/// +/// # Examples +/// +/// ``` +/// #![feature(slice_range)] +/// +/// use std::slice; +/// +/// let v = [10, 40, 30]; +/// assert_eq!(Some(1..2), slice::try_range(1..2, ..v.len())); +/// assert_eq!(Some(0..2), slice::try_range(..2, ..v.len())); +/// assert_eq!(Some(1..3), slice::try_range(1.., ..v.len())); +/// ``` +/// +/// Returns [`None`] when [`Index::index`] would panic: +/// +/// ``` +/// #![feature(slice_range)] +/// +/// use std::slice; +/// +/// assert_eq!(None, slice::try_range(2..1, ..3)); +/// assert_eq!(None, slice::try_range(1..4, ..3)); +/// assert_eq!(None, slice::try_range(1..=usize::MAX, ..3)); +/// ``` +/// +/// [`Index::index`]: ops::Index::index +#[unstable(feature = "slice_range", issue = "76393")] +#[must_use] +pub fn try_range<R>(range: R, bounds: ops::RangeTo<usize>) -> Option<ops::Range<usize>> +where + R: ops::RangeBounds<usize>, +{ + let len = bounds.end; + + let start = match range.start_bound() { + ops::Bound::Included(&start) => start, + ops::Bound::Excluded(start) => start.checked_add(1)?, + ops::Bound::Unbounded => 0, + }; + + let end = match range.end_bound() { + ops::Bound::Included(end) => end.checked_add(1)?, + ops::Bound::Excluded(&end) => end, + ops::Bound::Unbounded => len, + }; + + if start > end || end > len { None } else { Some(ops::Range { start, end }) } +} + /// Convert pair of `ops::Bound`s into `ops::Range` without performing any bounds checking and (in debug) overflow checking pub(crate) fn into_range_unchecked( len: usize, diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 2dd01ba33af..4a574bf0347 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -91,7 +91,7 @@ pub use sort::heapsort; pub use index::SliceIndex; #[unstable(feature = "slice_range", issue = "76393")] -pub use index::range; +pub use index::{range, try_range}; #[stable(feature = "inherent_ascii_escape", since = "1.60.0")] pub use ascii::EscapeAscii; diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 2af6382f3da..6520ca9fc48 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -806,9 +806,9 @@ pub mod guard { #[cfg(any( target_os = "android", target_os = "freebsd", + target_os = "netbsd", target_os = "hurd", target_os = "linux", - target_os = "netbsd", target_os = "l4re" ))] unsafe fn get_stack_start() -> Option<*mut libc::c_void> { @@ -911,9 +911,10 @@ pub mod guard { } }) * page_size; Some(guard) - } else if cfg!(target_os = "openbsd") { + } else if cfg!(any(target_os = "openbsd", target_os = "netbsd")) { // OpenBSD stack already includes a guard page, and stack is // immutable. + // NetBSD stack includes the guard page. // // We'll just note where we expect rlimit to start // faulting, so our handler can report "stack overflow", and diff --git a/library/std/src/sys/pal/windows/alloc.rs b/library/std/src/sys/pal/windows/alloc.rs index 270eca37b14..681d1a5efe9 100644 --- a/library/std/src/sys/pal/windows/alloc.rs +++ b/library/std/src/sys/pal/windows/alloc.rs @@ -6,6 +6,7 @@ use crate::ptr; use crate::sync::atomic::{AtomicPtr, Ordering}; use crate::sys::c; use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN}; +use core::mem::MaybeUninit; #[cfg(test)] mod tests; @@ -94,29 +95,30 @@ static HEAP: AtomicPtr<c_void> = AtomicPtr::new(ptr::null_mut()); // a non-null handle returned by `GetProcessHeap`. #[inline] fn init_or_get_process_heap() -> c::HANDLE { - let heap = HEAP.load(Ordering::Relaxed); - if core::intrinsics::unlikely(heap.is_null()) { - // `HEAP` has not yet been successfully initialized - let heap = unsafe { GetProcessHeap() }; - if !heap.is_null() { - // SAFETY: No locking is needed because within the same process, - // successful calls to `GetProcessHeap` will always return the same value, even on different threads. - HEAP.store(heap, Ordering::Release); - - // SAFETY: `HEAP` contains a non-null handle returned by `GetProcessHeap` - heap - } else { - // Could not get the current process heap. - ptr::null_mut() - } - } else { + // `HEAP` has not yet been successfully initialized + let heap = unsafe { GetProcessHeap() }; + if !heap.is_null() { + // SAFETY: No locking is needed because within the same process, + // successful calls to `GetProcessHeap` will always return the same value, even on different threads. + HEAP.store(heap, Ordering::Release); + // SAFETY: `HEAP` contains a non-null handle returned by `GetProcessHeap` heap + } else { + // Could not get the current process heap. + ptr::null_mut() } } +/// This is outlined from `process_heap_alloc` so that `process_heap_alloc` +/// does not need any stack allocations. #[inline(never)] -fn process_heap_alloc(flags: c::DWORD, dwBytes: c::SIZE_T) -> c::LPVOID { +#[cold] +extern "C" fn process_heap_init_and_alloc( + _heap: MaybeUninit<c::HANDLE>, // We pass this argument to match the ABI of `HeapAlloc` + flags: c::DWORD, + dwBytes: c::SIZE_T, +) -> c::LPVOID { let heap = init_or_get_process_heap(); if core::intrinsics::unlikely(heap.is_null()) { return ptr::null_mut(); @@ -125,6 +127,21 @@ fn process_heap_alloc(flags: c::DWORD, dwBytes: c::SIZE_T) -> c::LPVOID { unsafe { HeapAlloc(heap, flags, dwBytes) } } +#[inline(never)] +fn process_heap_alloc( + _heap: MaybeUninit<c::HANDLE>, // We pass this argument to match the ABI of `HeapAlloc`, + flags: c::DWORD, + dwBytes: c::SIZE_T, +) -> c::LPVOID { + let heap = HEAP.load(Ordering::Relaxed); + if core::intrinsics::likely(!heap.is_null()) { + // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`. + unsafe { HeapAlloc(heap, flags, dwBytes) } + } else { + process_heap_init_and_alloc(MaybeUninit::uninit(), flags, dwBytes) + } +} + // Get a non-null handle to the default heap of the current process. // SAFETY: `HEAP` must have been successfully initialized. #[inline] @@ -148,12 +165,12 @@ unsafe fn allocate(layout: Layout, zeroed: bool) -> *mut u8 { if layout.align() <= MIN_ALIGN { // The returned pointer points to the start of an allocated block. - process_heap_alloc(flags, layout.size()) as *mut u8 + process_heap_alloc(MaybeUninit::uninit(), flags, layout.size()) as *mut u8 } else { // Allocate extra padding in order to be able to satisfy the alignment. let total = layout.align() + layout.size(); - let ptr = process_heap_alloc(flags, total) as *mut u8; + let ptr = process_heap_alloc(MaybeUninit::uninit(), flags, total) as *mut u8; if ptr.is_null() { // Allocation has failed. return ptr::null_mut(); diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs index 2fc6598d876..1c828bac4b6 100644 --- a/library/std/src/sys/pal/windows/c.rs +++ b/library/std/src/sys/pal/windows/c.rs @@ -344,6 +344,7 @@ compat_fn_with_fallback! { // >= Win8 / Server 2012 // https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimepreciseasfiletime + #[cfg(target_vendor = "win7")] pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME) -> () { GetSystemTimeAsFileTime(lpsystemtimeasfiletime) } diff --git a/library/std/src/sys/pal/windows/c/bindings.txt b/library/std/src/sys/pal/windows/c/bindings.txt index 7667f761106..849e64ac591 100644 --- a/library/std/src/sys/pal/windows/c/bindings.txt +++ b/library/std/src/sys/pal/windows/c/bindings.txt @@ -2476,6 +2476,7 @@ Windows.Win32.System.Pipes.PIPE_WAIT Windows.Win32.System.SystemInformation.GetSystemDirectoryW Windows.Win32.System.SystemInformation.GetSystemInfo Windows.Win32.System.SystemInformation.GetSystemTimeAsFileTime +Windows.Win32.System.SystemInformation.GetSystemTimePreciseAsFileTime Windows.Win32.System.SystemInformation.GetWindowsDirectoryW Windows.Win32.System.SystemInformation.PROCESSOR_ARCHITECTURE Windows.Win32.System.SystemInformation.SYSTEM_INFO diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs index 7b751079afb..baaa8257d84 100644 --- a/library/std/src/sys/pal/windows/c/windows_sys.rs +++ b/library/std/src/sys/pal/windows/c/windows_sys.rs @@ -346,6 +346,10 @@ extern "system" { } #[link(name = "kernel32")] extern "system" { + pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME) -> (); +} +#[link(name = "kernel32")] +extern "system" { pub fn GetTempPathW(nbufferlength: u32, lpbuffer: PWSTR) -> u32; } #[link(name = "kernel32")] |
