Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 9 pull requests #122331

Merged
merged 23 commits into from
Mar 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
290cbdf
Add slice::try_range
clarfonthey Feb 15, 2024
7e6dccc
Win10: Use GetSystemTimePreciseAsFileTime directly
ChrisDenton Feb 26, 2024
eb40adb
Add shim for GetSystemTimePreciseAsFileTime
ChrisDenton Feb 26, 2024
f030d49
Expose `Freeze` trait again
oli-obk Feb 23, 2024
7849230
Forbid implementing `Freeze` even if the trait is stabilized
oli-obk Feb 23, 2024
7ff3bad
std::threads: revisit stack address calculation on netbsd.
devnexen Mar 4, 2024
dd95cb7
Add `target.*.runner` configuration for targets
alexcrichton Mar 6, 2024
9bdb8a6
Add a change entry
alexcrichton Mar 8, 2024
ffdd97f
further changes from feedback
devnexen Mar 8, 2024
e5e1fa6
skip sanity check for non-host targets in `check` builds
onur-ozkan Mar 2, 2024
81ebaf2
RawVec::into_box: avoid unnecessary intermediate reference
RalfJung Mar 10, 2024
a7443f5
test into_boxed_slice with custom allocator in Miri
RalfJung Mar 10, 2024
50760aa
Optimize `process_heap_alloc`
Zoxc Mar 11, 2024
47b4b8e
Allow multiple `impl Into<{D,Subd}iagMessage>` parameters in a function.
nnethercote Mar 10, 2024
6c8c272
Rollup merge of #121148 - clarfonthey:try-range, r=dtolnay
jhpratt Mar 11, 2024
1a989e0
Rollup merge of #121633 - ChrisDenton:precise, r=Nilstrieb
jhpratt Mar 11, 2024
05f22c3
Rollup merge of #121840 - oli-obk:freeze, r=dtolnay
jhpratt Mar 11, 2024
1009859
Rollup merge of #121907 - onur-ozkan:better-target-sanity-check, r=al…
jhpratt Mar 11, 2024
b3ac6fa
Rollup merge of #122002 - devnexen:thread_stack_netbsd_fix, r=working…
jhpratt Mar 11, 2024
9b30f01
Rollup merge of #122108 - alexcrichton:target-config-runtool, r=Waffl…
jhpratt Mar 11, 2024
eb1ebbf
Rollup merge of #122298 - RalfJung:raw-vec-into-box, r=cuviper
jhpratt Mar 11, 2024
6f15816
Rollup merge of #122315 - nnethercote:multiple-into-diag-message, r=N…
jhpratt Mar 11, 2024
5a3d6c9
Rollup merge of #122326 - Zoxc:win-alloc-tweak, r=ChrisDenton
jhpratt Mar 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/rustc_codegen_cranelift/example/mini_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
rustc_attrs,
transparent_unions,
auto_traits,
freeze_impls,
thread_local
)]
#![no_core]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_gcc/example/mini_core.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![feature(
no_core, lang_items, intrinsics, unboxed_closures, type_ascription, extern_types,
decl_macro, rustc_attrs, transparent_unions, auto_traits,
decl_macro, rustc_attrs, transparent_unions, auto_traits, freeze_impls,
thread_local
)]
#![no_core]
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,8 @@ declare_features! (
(unstable, fn_align, "1.53.0", Some(82232)),
/// Support delegating implementation of functions to other already implemented functions.
(incomplete, fn_delegation, "1.76.0", Some(118212)),
/// Allows impls for the Freeze trait.
(internal, freeze_impls, "CURRENT_RUSTC_VERSION", Some(121675)),
/// Allows defining gen blocks and `gen fn`.
(unstable, gen_blocks, "1.75.0", Some(117078)),
/// Infer generic args for both consts and types.
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_hir_analysis/src/coherence/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use rustc_errors::{codes::*, struct_span_code_err};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::query::Providers;
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
use rustc_session::parse::feature_err;
use rustc_span::{sym, ErrorGuaranteed};
use rustc_trait_selection::traits;

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

if tcx.lang_items().freeze_trait() == Some(trait_def_id) {
if !tcx.features().freeze_impls {
feature_err(
&tcx.sess,
sym::freeze_impls,
impl_header_span,
"explicit impls for the `Freeze` trait are not permitted",
)
.with_span_label(impl_header_span, format!("impl of `Freeze` not allowed"))
.emit();
}
}

// Disallow *all* explicit impls of traits marked `#[rustc_deny_explicit_impl]`
if trait_def.deny_explicit_impl {
let trait_name = tcx.item_name(trait_def_id);
Expand Down
17 changes: 5 additions & 12 deletions compiler/rustc_lint/src/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,9 +409,8 @@ impl LateLintPass<'_> for Diagnostics {
}
};

// Does the callee have a `impl Into<{D,Subd}iagMessage>` parameter? (There should be at
// most one.)
let mut impl_into_diagnostic_message_param = None;
// Does the callee have one or more `impl Into<{D,Subd}iagMessage>` parameters?
let mut impl_into_diagnostic_message_params = vec![];
let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder();
let predicates = cx.tcx.predicates_of(def_id).instantiate_identity(cx.tcx).predicates;
for (i, &param_ty) in fn_sig.inputs().iter().enumerate() {
Expand All @@ -425,20 +424,14 @@ impl LateLintPass<'_> for Diagnostics {
&& let ty1 = trait_ref.args.type_at(1)
&& is_diag_message(ty1)
{
if impl_into_diagnostic_message_param.is_some() {
cx.tcx.dcx().span_bug(
span,
"can't handle multiple `impl Into<{D,Sub}iagMessage>` params",
);
}
impl_into_diagnostic_message_param = Some((i, p.name));
impl_into_diagnostic_message_params.push((i, p.name));
}
}
}
}

// Is the callee interesting?
if !has_attr && impl_into_diagnostic_message_param.is_none() {
if !has_attr && impl_into_diagnostic_message_params.is_empty() {
return;
}

Expand Down Expand Up @@ -481,7 +474,7 @@ impl LateLintPass<'_> for Diagnostics {
// Calls to methods with an `impl Into<{D,Subd}iagMessage>` parameter must be passed an arg
// with type `{D,Subd}iagMessage` or `impl Into<{D,Subd}iagMessage>`. Otherwise, emit an
// `UNTRANSLATABLE_DIAGNOSTIC` lint.
if let Some((param_i, param_i_p_name)) = impl_into_diagnostic_message_param {
for (param_i, param_i_p_name) in impl_into_diagnostic_message_params {
// Is the arg type `{Sub,D}iagMessage`or `impl Into<{Sub,D}iagMessage>`?
let arg_ty = call_tys[param_i];
let is_translatable = is_diag_message(arg_ty)
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,7 @@ symbols! {
format_placeholder,
format_unsafe_arg,
freeze,
freeze_impls,
freg,
frem_algebraic,
frem_fast,
Expand Down
11 changes: 11 additions & 0 deletions config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,17 @@
# See that option for more info.
#codegen-backends = rust.codegen-backends (array)

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

# =============================================================================
# Distribution options
#
Expand Down
3 changes: 1 addition & 2 deletions library/alloc/src/raw_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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))
}
}
Expand Down
4 changes: 2 additions & 2 deletions library/alloc/src/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand All @@ -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")]
Expand Down
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
10 changes: 8 additions & 2 deletions library/core/src/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
59 changes: 55 additions & 4 deletions library/core/src/slice/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -704,17 +704,15 @@ 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())
}
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())
}
Expand All @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 3 additions & 2 deletions library/std/src/sys/pal/unix/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -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
Expand Down
55 changes: 36 additions & 19 deletions library/std/src/sys/pal/windows/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand All @@ -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]
Expand All @@ -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();
Expand Down
Loading
Loading