Skip to content

Commit 5ec2f2c

Browse files
committed
Auto merge of rust-lang#122331 - jhpratt:rollup-cbl8xsy, r=jhpratt
Rollup of 9 pull requests Successful merges: - rust-lang#121148 (Add slice::try_range) - rust-lang#121633 (Win10: Use `GetSystemTimePreciseAsFileTime` directly) - rust-lang#121840 (Expose the Freeze trait again (unstably) and forbid implementing it manually) - rust-lang#121907 (skip sanity check for non-host targets in `check` builds) - rust-lang#122002 (std::threads: revisit stack address calculation on netbsd.) - rust-lang#122108 (Add `target.*.runner` configuration for targets) - rust-lang#122298 (RawVec::into_box: avoid unnecessary intermediate reference) - rust-lang#122315 (Allow multiple `impl Into<{D,Subd}iagMessage>` parameters in a function.) - rust-lang#122326 (Optimize `process_heap_alloc`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 74e8355 + dc5de3d commit 5ec2f2c

File tree

11 files changed

+113
-32
lines changed

11 files changed

+113
-32
lines changed

alloc/src/raw_vec.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use core::cmp;
55
use core::hint;
66
use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties};
77
use core::ptr::{self, NonNull, Unique};
8-
use core::slice;
98

109
#[cfg(not(no_global_oom_handling))]
1110
use crate::alloc::handle_alloc_error;
@@ -192,7 +191,7 @@ impl<T, A: Allocator> RawVec<T, A> {
192191

193192
let me = ManuallyDrop::new(self);
194193
unsafe {
195-
let slice = slice::from_raw_parts_mut(me.ptr() as *mut MaybeUninit<T>, len);
194+
let slice = ptr::slice_from_raw_parts_mut(me.ptr() as *mut MaybeUninit<T>, len);
196195
Box::from_raw_in(slice, ptr::read(&me.alloc))
197196
}
198197
}

alloc/src/slice.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ use crate::vec::Vec;
3333
#[cfg(test)]
3434
mod tests;
3535

36-
#[unstable(feature = "slice_range", issue = "76393")]
37-
pub use core::slice::range;
3836
#[unstable(feature = "array_chunks", issue = "74985")]
3937
pub use core::slice::ArrayChunks;
4038
#[unstable(feature = "array_chunks", issue = "74985")]
@@ -51,6 +49,8 @@ pub use core::slice::{from_mut, from_ref};
5149
pub use core::slice::{from_mut_ptr_range, from_ptr_range};
5250
#[stable(feature = "rust1", since = "1.0.0")]
5351
pub use core::slice::{from_raw_parts, from_raw_parts_mut};
52+
#[unstable(feature = "slice_range", issue = "76393")]
53+
pub use core::slice::{range, try_range};
5454
#[stable(feature = "slice_group_by", since = "1.77.0")]
5555
pub use core::slice::{ChunkBy, ChunkByMut};
5656
#[stable(feature = "rust1", since = "1.0.0")]

core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@
204204
// tidy-alphabetical-start
205205
#![cfg_attr(bootstrap, feature(diagnostic_namespace))]
206206
#![cfg_attr(bootstrap, feature(platform_intrinsics))]
207+
#![cfg_attr(not(bootstrap), feature(freeze_impls))]
207208
#![feature(abi_unadjusted)]
208209
#![feature(adt_const_params)]
209210
#![feature(allow_internal_unsafe)]

core/src/marker.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -810,15 +810,21 @@ pub trait DiscriminantKind {
810810
type Discriminant: Clone + Copy + Debug + Eq + PartialEq + Hash + Send + Sync + Unpin;
811811
}
812812

813-
/// Compiler-internal trait used to determine whether a type contains
813+
/// Used to determine whether a type contains
814814
/// any `UnsafeCell` internally, but not through an indirection.
815815
/// This affects, for example, whether a `static` of that type is
816816
/// placed in read-only static memory or writable static memory.
817+
/// This can be used to declare that a constant with a generic type
818+
/// will not contain interior mutability, and subsequently allow
819+
/// placing the constant behind references.
817820
#[lang = "freeze"]
818-
pub(crate) unsafe auto trait Freeze {}
821+
#[unstable(feature = "freeze", issue = "121675")]
822+
pub unsafe auto trait Freeze {}
819823

824+
#[unstable(feature = "freeze", issue = "121675")]
820825
impl<T: ?Sized> !Freeze for UnsafeCell<T> {}
821826
marker_impls! {
827+
#[unstable(feature = "freeze", issue = "121675")]
822828
unsafe Freeze for
823829
{T: ?Sized} PhantomData<T>,
824830
{T: ?Sized} *const T,

core/src/slice/index.rs

+55-4
Original file line numberDiff line numberDiff line change
@@ -704,17 +704,15 @@ where
704704
{
705705
let len = bounds.end;
706706

707-
let start: ops::Bound<&usize> = range.start_bound();
708-
let start = match start {
707+
let start = match range.start_bound() {
709708
ops::Bound::Included(&start) => start,
710709
ops::Bound::Excluded(start) => {
711710
start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
712711
}
713712
ops::Bound::Unbounded => 0,
714713
};
715714

716-
let end: ops::Bound<&usize> = range.end_bound();
717-
let end = match end {
715+
let end = match range.end_bound() {
718716
ops::Bound::Included(end) => {
719717
end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
720718
}
@@ -732,6 +730,59 @@ where
732730
ops::Range { start, end }
733731
}
734732

733+
/// Performs bounds-checking of a range without panicking.
734+
///
735+
/// This is a version of [`range`] that returns [`None`] instead of panicking.
736+
///
737+
/// # Examples
738+
///
739+
/// ```
740+
/// #![feature(slice_range)]
741+
///
742+
/// use std::slice;
743+
///
744+
/// let v = [10, 40, 30];
745+
/// assert_eq!(Some(1..2), slice::try_range(1..2, ..v.len()));
746+
/// assert_eq!(Some(0..2), slice::try_range(..2, ..v.len()));
747+
/// assert_eq!(Some(1..3), slice::try_range(1.., ..v.len()));
748+
/// ```
749+
///
750+
/// Returns [`None`] when [`Index::index`] would panic:
751+
///
752+
/// ```
753+
/// #![feature(slice_range)]
754+
///
755+
/// use std::slice;
756+
///
757+
/// assert_eq!(None, slice::try_range(2..1, ..3));
758+
/// assert_eq!(None, slice::try_range(1..4, ..3));
759+
/// assert_eq!(None, slice::try_range(1..=usize::MAX, ..3));
760+
/// ```
761+
///
762+
/// [`Index::index`]: ops::Index::index
763+
#[unstable(feature = "slice_range", issue = "76393")]
764+
#[must_use]
765+
pub fn try_range<R>(range: R, bounds: ops::RangeTo<usize>) -> Option<ops::Range<usize>>
766+
where
767+
R: ops::RangeBounds<usize>,
768+
{
769+
let len = bounds.end;
770+
771+
let start = match range.start_bound() {
772+
ops::Bound::Included(&start) => start,
773+
ops::Bound::Excluded(start) => start.checked_add(1)?,
774+
ops::Bound::Unbounded => 0,
775+
};
776+
777+
let end = match range.end_bound() {
778+
ops::Bound::Included(end) => end.checked_add(1)?,
779+
ops::Bound::Excluded(&end) => end,
780+
ops::Bound::Unbounded => len,
781+
};
782+
783+
if start > end || end > len { None } else { Some(ops::Range { start, end }) }
784+
}
785+
735786
/// Convert pair of `ops::Bound`s into `ops::Range` without performing any bounds checking and (in debug) overflow checking
736787
pub(crate) fn into_range_unchecked(
737788
len: usize,

core/src/slice/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ pub use sort::heapsort;
9191
pub use index::SliceIndex;
9292

9393
#[unstable(feature = "slice_range", issue = "76393")]
94-
pub use index::range;
94+
pub use index::{range, try_range};
9595

9696
#[stable(feature = "inherent_ascii_escape", since = "1.60.0")]
9797
pub use ascii::EscapeAscii;

std/src/sys/pal/unix/thread.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -806,9 +806,9 @@ pub mod guard {
806806
#[cfg(any(
807807
target_os = "android",
808808
target_os = "freebsd",
809+
target_os = "netbsd",
809810
target_os = "hurd",
810811
target_os = "linux",
811-
target_os = "netbsd",
812812
target_os = "l4re"
813813
))]
814814
unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
@@ -911,9 +911,10 @@ pub mod guard {
911911
}
912912
}) * page_size;
913913
Some(guard)
914-
} else if cfg!(target_os = "openbsd") {
914+
} else if cfg!(any(target_os = "openbsd", target_os = "netbsd")) {
915915
// OpenBSD stack already includes a guard page, and stack is
916916
// immutable.
917+
// NetBSD stack includes the guard page.
917918
//
918919
// We'll just note where we expect rlimit to start
919920
// faulting, so our handler can report "stack overflow", and

std/src/sys/pal/windows/alloc.rs

+36-19
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::ptr;
66
use crate::sync::atomic::{AtomicPtr, Ordering};
77
use crate::sys::c;
88
use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN};
9+
use core::mem::MaybeUninit;
910

1011
#[cfg(test)]
1112
mod tests;
@@ -94,29 +95,30 @@ static HEAP: AtomicPtr<c_void> = AtomicPtr::new(ptr::null_mut());
9495
// a non-null handle returned by `GetProcessHeap`.
9596
#[inline]
9697
fn init_or_get_process_heap() -> c::HANDLE {
97-
let heap = HEAP.load(Ordering::Relaxed);
98-
if core::intrinsics::unlikely(heap.is_null()) {
99-
// `HEAP` has not yet been successfully initialized
100-
let heap = unsafe { GetProcessHeap() };
101-
if !heap.is_null() {
102-
// SAFETY: No locking is needed because within the same process,
103-
// successful calls to `GetProcessHeap` will always return the same value, even on different threads.
104-
HEAP.store(heap, Ordering::Release);
105-
106-
// SAFETY: `HEAP` contains a non-null handle returned by `GetProcessHeap`
107-
heap
108-
} else {
109-
// Could not get the current process heap.
110-
ptr::null_mut()
111-
}
112-
} else {
98+
// `HEAP` has not yet been successfully initialized
99+
let heap = unsafe { GetProcessHeap() };
100+
if !heap.is_null() {
101+
// SAFETY: No locking is needed because within the same process,
102+
// successful calls to `GetProcessHeap` will always return the same value, even on different threads.
103+
HEAP.store(heap, Ordering::Release);
104+
113105
// SAFETY: `HEAP` contains a non-null handle returned by `GetProcessHeap`
114106
heap
107+
} else {
108+
// Could not get the current process heap.
109+
ptr::null_mut()
115110
}
116111
}
117112

113+
/// This is outlined from `process_heap_alloc` so that `process_heap_alloc`
114+
/// does not need any stack allocations.
118115
#[inline(never)]
119-
fn process_heap_alloc(flags: c::DWORD, dwBytes: c::SIZE_T) -> c::LPVOID {
116+
#[cold]
117+
extern "C" fn process_heap_init_and_alloc(
118+
_heap: MaybeUninit<c::HANDLE>, // We pass this argument to match the ABI of `HeapAlloc`
119+
flags: c::DWORD,
120+
dwBytes: c::SIZE_T,
121+
) -> c::LPVOID {
120122
let heap = init_or_get_process_heap();
121123
if core::intrinsics::unlikely(heap.is_null()) {
122124
return ptr::null_mut();
@@ -125,6 +127,21 @@ fn process_heap_alloc(flags: c::DWORD, dwBytes: c::SIZE_T) -> c::LPVOID {
125127
unsafe { HeapAlloc(heap, flags, dwBytes) }
126128
}
127129

130+
#[inline(never)]
131+
fn process_heap_alloc(
132+
_heap: MaybeUninit<c::HANDLE>, // We pass this argument to match the ABI of `HeapAlloc`,
133+
flags: c::DWORD,
134+
dwBytes: c::SIZE_T,
135+
) -> c::LPVOID {
136+
let heap = HEAP.load(Ordering::Relaxed);
137+
if core::intrinsics::likely(!heap.is_null()) {
138+
// SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`.
139+
unsafe { HeapAlloc(heap, flags, dwBytes) }
140+
} else {
141+
process_heap_init_and_alloc(MaybeUninit::uninit(), flags, dwBytes)
142+
}
143+
}
144+
128145
// Get a non-null handle to the default heap of the current process.
129146
// SAFETY: `HEAP` must have been successfully initialized.
130147
#[inline]
@@ -148,12 +165,12 @@ unsafe fn allocate(layout: Layout, zeroed: bool) -> *mut u8 {
148165

149166
if layout.align() <= MIN_ALIGN {
150167
// The returned pointer points to the start of an allocated block.
151-
process_heap_alloc(flags, layout.size()) as *mut u8
168+
process_heap_alloc(MaybeUninit::uninit(), flags, layout.size()) as *mut u8
152169
} else {
153170
// Allocate extra padding in order to be able to satisfy the alignment.
154171
let total = layout.align() + layout.size();
155172

156-
let ptr = process_heap_alloc(flags, total) as *mut u8;
173+
let ptr = process_heap_alloc(MaybeUninit::uninit(), flags, total) as *mut u8;
157174
if ptr.is_null() {
158175
// Allocation has failed.
159176
return ptr::null_mut();

std/src/sys/pal/windows/c.rs

+1
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ compat_fn_with_fallback! {
344344

345345
// >= Win8 / Server 2012
346346
// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimepreciseasfiletime
347+
#[cfg(target_vendor = "win7")]
347348
pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME) -> () {
348349
GetSystemTimeAsFileTime(lpsystemtimeasfiletime)
349350
}

std/src/sys/pal/windows/c/bindings.txt

+1
Original file line numberDiff line numberDiff line change
@@ -2476,6 +2476,7 @@ Windows.Win32.System.Pipes.PIPE_WAIT
24762476
Windows.Win32.System.SystemInformation.GetSystemDirectoryW
24772477
Windows.Win32.System.SystemInformation.GetSystemInfo
24782478
Windows.Win32.System.SystemInformation.GetSystemTimeAsFileTime
2479+
Windows.Win32.System.SystemInformation.GetSystemTimePreciseAsFileTime
24792480
Windows.Win32.System.SystemInformation.GetWindowsDirectoryW
24802481
Windows.Win32.System.SystemInformation.PROCESSOR_ARCHITECTURE
24812482
Windows.Win32.System.SystemInformation.SYSTEM_INFO

std/src/sys/pal/windows/c/windows_sys.rs

+4
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,10 @@ extern "system" {
345345
pub fn GetSystemTimeAsFileTime(lpsystemtimeasfiletime: *mut FILETIME) -> ();
346346
}
347347
#[link(name = "kernel32")]
348+
extern "system" {
349+
pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME) -> ();
350+
}
351+
#[link(name = "kernel32")]
348352
extern "system" {
349353
pub fn GetTempPathW(nbufferlength: u32, lpbuffer: PWSTR) -> u32;
350354
}

0 commit comments

Comments
 (0)