Skip to content

Commit e919669

Browse files
committedMar 11, 2024·
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 6639672 + 5a3d6c9 commit e919669

File tree

40 files changed

+277
-81
lines changed

40 files changed

+277
-81
lines changed
 

‎compiler/rustc_codegen_cranelift/example/mini_core.rs

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
rustc_attrs,
99
transparent_unions,
1010
auto_traits,
11+
freeze_impls,
1112
thread_local
1213
)]
1314
#![no_core]

‎compiler/rustc_codegen_gcc/example/mini_core.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![feature(
22
no_core, lang_items, intrinsics, unboxed_closures, type_ascription, extern_types,
3-
decl_macro, rustc_attrs, transparent_unions, auto_traits,
3+
decl_macro, rustc_attrs, transparent_unions, auto_traits, freeze_impls,
44
thread_local
55
)]
66
#![no_core]

‎compiler/rustc_feature/src/unstable.rs

+2
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,8 @@ declare_features! (
471471
(unstable, fn_align, "1.53.0", Some(82232)),
472472
/// Support delegating implementation of functions to other already implemented functions.
473473
(incomplete, fn_delegation, "1.76.0", Some(118212)),
474+
/// Allows impls for the Freeze trait.
475+
(internal, freeze_impls, "CURRENT_RUSTC_VERSION", Some(121675)),
474476
/// Allows defining gen blocks and `gen fn`.
475477
(unstable, gen_blocks, "1.75.0", Some(117078)),
476478
/// Infer generic args for both consts and types.

‎compiler/rustc_hir_analysis/src/coherence/mod.rs

+14
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_errors::{codes::*, struct_span_code_err};
1010
use rustc_hir::def_id::{DefId, LocalDefId};
1111
use rustc_middle::query::Providers;
1212
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
13+
use rustc_session::parse::feature_err;
1314
use rustc_span::{sym, ErrorGuaranteed};
1415
use rustc_trait_selection::traits;
1516

@@ -49,6 +50,19 @@ fn enforce_trait_manually_implementable(
4950
) -> Result<(), ErrorGuaranteed> {
5051
let impl_header_span = tcx.def_span(impl_def_id);
5152

53+
if tcx.lang_items().freeze_trait() == Some(trait_def_id) {
54+
if !tcx.features().freeze_impls {
55+
feature_err(
56+
&tcx.sess,
57+
sym::freeze_impls,
58+
impl_header_span,
59+
"explicit impls for the `Freeze` trait are not permitted",
60+
)
61+
.with_span_label(impl_header_span, format!("impl of `Freeze` not allowed"))
62+
.emit();
63+
}
64+
}
65+
5266
// Disallow *all* explicit impls of traits marked `#[rustc_deny_explicit_impl]`
5367
if trait_def.deny_explicit_impl {
5468
let trait_name = tcx.item_name(trait_def_id);

‎compiler/rustc_lint/src/internal.rs

+5-12
Original file line numberDiff line numberDiff line change
@@ -409,9 +409,8 @@ impl LateLintPass<'_> for Diagnostics {
409409
}
410410
};
411411

412-
// Does the callee have a `impl Into<{D,Subd}iagMessage>` parameter? (There should be at
413-
// most one.)
414-
let mut impl_into_diagnostic_message_param = None;
412+
// Does the callee have one or more `impl Into<{D,Subd}iagMessage>` parameters?
413+
let mut impl_into_diagnostic_message_params = vec![];
415414
let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder();
416415
let predicates = cx.tcx.predicates_of(def_id).instantiate_identity(cx.tcx).predicates;
417416
for (i, &param_ty) in fn_sig.inputs().iter().enumerate() {
@@ -425,20 +424,14 @@ impl LateLintPass<'_> for Diagnostics {
425424
&& let ty1 = trait_ref.args.type_at(1)
426425
&& is_diag_message(ty1)
427426
{
428-
if impl_into_diagnostic_message_param.is_some() {
429-
cx.tcx.dcx().span_bug(
430-
span,
431-
"can't handle multiple `impl Into<{D,Sub}iagMessage>` params",
432-
);
433-
}
434-
impl_into_diagnostic_message_param = Some((i, p.name));
427+
impl_into_diagnostic_message_params.push((i, p.name));
435428
}
436429
}
437430
}
438431
}
439432

440433
// Is the callee interesting?
441-
if !has_attr && impl_into_diagnostic_message_param.is_none() {
434+
if !has_attr && impl_into_diagnostic_message_params.is_empty() {
442435
return;
443436
}
444437

@@ -481,7 +474,7 @@ impl LateLintPass<'_> for Diagnostics {
481474
// Calls to methods with an `impl Into<{D,Subd}iagMessage>` parameter must be passed an arg
482475
// with type `{D,Subd}iagMessage` or `impl Into<{D,Subd}iagMessage>`. Otherwise, emit an
483476
// `UNTRANSLATABLE_DIAGNOSTIC` lint.
484-
if let Some((param_i, param_i_p_name)) = impl_into_diagnostic_message_param {
477+
for (param_i, param_i_p_name) in impl_into_diagnostic_message_params {
485478
// Is the arg type `{Sub,D}iagMessage`or `impl Into<{Sub,D}iagMessage>`?
486479
let arg_ty = call_tys[param_i];
487480
let is_translatable = is_diag_message(arg_ty)

‎compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,7 @@ symbols! {
864864
format_placeholder,
865865
format_unsafe_arg,
866866
freeze,
867+
freeze_impls,
867868
freg,
868869
frem_algebraic,
869870
frem_fast,

‎config.example.toml

+11
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,17 @@
842842
# See that option for more info.
843843
#codegen-backends = rust.codegen-backends (array)
844844

845+
# This is a "runner" to pass to `compiletest` when executing tests. Tests will
846+
# execute this tool where the binary-to-test is passed as an argument. Can
847+
# be useful for situations such as when WebAssembly is being tested and a
848+
# runtime needs to be configured. This value is similar to
849+
# Cargo's `CARGO_$target_RUNNER` configuration.
850+
#
851+
# This configuration is a space-separated list of arguments so `foo bar` would
852+
# execute the program `foo` with the first argument as `bar` and the second
853+
# argument as the test binary.
854+
#runner = <none> (string)
855+
845856
# =============================================================================
846857
# Distribution options
847858
#

‎library/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
}

‎library/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")]

‎library/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)]

‎library/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,

‎library/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,

‎library/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;

‎library/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

‎library/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();

0 commit comments

Comments
 (0)
Please sign in to comment.