Auto merge of #131612 - tgross35:rollup-zy3yg4p, r=tgross35
Rollup of 7 pull requests Successful merges: - #130870 (Add suggestion for removing invalid path sep `::` in fn def) - #130954 (Stabilize const `ptr::write*` and `mem::replace`) - #131233 (std: fix stdout-before-main) - #131590 (yeet some clones) - #131596 (mark InterpResult as must_use) - #131597 (Take a display name for `tool_check_step!`) - #131605 (`LLVMConstInt` only allows integer types) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
6b9676b454
@ -165,7 +165,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
|
|||||||
universe_causes,
|
universe_causes,
|
||||||
type_tests,
|
type_tests,
|
||||||
liveness_constraints,
|
liveness_constraints,
|
||||||
elements.clone(),
|
elements,
|
||||||
);
|
);
|
||||||
|
|
||||||
// If requested: dump NLL facts, and run legacy polonius analysis.
|
// If requested: dump NLL facts, and run legacy polonius analysis.
|
||||||
|
@ -312,7 +312,7 @@ pub(crate) fn expand_deriving_smart_ptr(
|
|||||||
impl_generics.params.insert(pointee_param_idx + 1, extra_param);
|
impl_generics.params.insert(pointee_param_idx + 1, extra_param);
|
||||||
|
|
||||||
// Add the impl blocks for `DispatchFromDyn` and `CoerceUnsized`.
|
// Add the impl blocks for `DispatchFromDyn` and `CoerceUnsized`.
|
||||||
let gen_args = vec![GenericArg::Type(alt_self_type.clone())];
|
let gen_args = vec![GenericArg::Type(alt_self_type)];
|
||||||
add_impl_block(impl_generics.clone(), sym::DispatchFromDyn, gen_args.clone());
|
add_impl_block(impl_generics.clone(), sym::DispatchFromDyn, gen_args.clone());
|
||||||
add_impl_block(impl_generics.clone(), sym::CoerceUnsized, gen_args);
|
add_impl_block(impl_generics.clone(), sym::CoerceUnsized, gen_args);
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
use rustc_abi::Primitive::Pointer;
|
use rustc_abi::Primitive::Pointer;
|
||||||
use rustc_abi::{AddressSpace, HasDataLayout};
|
use rustc_abi::{AddressSpace, HasDataLayout};
|
||||||
use rustc_ast::Mutability;
|
use rustc_ast::Mutability;
|
||||||
|
use rustc_codegen_ssa::common::TypeKind;
|
||||||
use rustc_codegen_ssa::traits::*;
|
use rustc_codegen_ssa::traits::*;
|
||||||
use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
@ -146,6 +147,10 @@ fn const_i32(&self, i: i32) -> &'ll Value {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn const_int(&self, t: &'ll Type, i: i64) -> &'ll Value {
|
fn const_int(&self, t: &'ll Type, i: i64) -> &'ll Value {
|
||||||
|
debug_assert!(
|
||||||
|
self.type_kind(t) == TypeKind::Integer,
|
||||||
|
"only allows integer types in const_int"
|
||||||
|
);
|
||||||
unsafe { llvm::LLVMConstInt(t, i as u64, True) }
|
unsafe { llvm::LLVMConstInt(t, i as u64, True) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,10 +181,18 @@ fn const_usize(&self, i: u64) -> &'ll Value {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn const_uint(&self, t: &'ll Type, i: u64) -> &'ll Value {
|
fn const_uint(&self, t: &'ll Type, i: u64) -> &'ll Value {
|
||||||
|
debug_assert!(
|
||||||
|
self.type_kind(t) == TypeKind::Integer,
|
||||||
|
"only allows integer types in const_uint"
|
||||||
|
);
|
||||||
unsafe { llvm::LLVMConstInt(t, i, False) }
|
unsafe { llvm::LLVMConstInt(t, i, False) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn const_uint_big(&self, t: &'ll Type, u: u128) -> &'ll Value {
|
fn const_uint_big(&self, t: &'ll Type, u: u128) -> &'ll Value {
|
||||||
|
debug_assert!(
|
||||||
|
self.type_kind(t) == TypeKind::Integer,
|
||||||
|
"only allows integer types in const_uint_big"
|
||||||
|
);
|
||||||
unsafe {
|
unsafe {
|
||||||
let words = [u as u64, (u >> 64) as u64];
|
let words = [u as u64, (u >> 64) as u64];
|
||||||
llvm::LLVMConstIntOfArbitraryPrecision(t, 2, words.as_ptr())
|
llvm::LLVMConstIntOfArbitraryPrecision(t, 2, words.as_ptr())
|
||||||
|
@ -754,6 +754,7 @@ fn drop(&mut self) {
|
|||||||
///
|
///
|
||||||
/// We also make things panic if this type is ever implicitly dropped.
|
/// We also make things panic if this type is ever implicitly dropped.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[must_use]
|
||||||
pub struct InterpResult_<'tcx, T> {
|
pub struct InterpResult_<'tcx, T> {
|
||||||
res: Result<T, InterpErrorInfo<'tcx>>,
|
res: Result<T, InterpErrorInfo<'tcx>>,
|
||||||
guard: Guard,
|
guard: Guard,
|
||||||
|
@ -422,6 +422,9 @@ parse_invalid_meta_item = expected unsuffixed literal, found `{$token}`
|
|||||||
|
|
||||||
parse_invalid_offset_of = offset_of expects dot-separated field and variant names
|
parse_invalid_offset_of = offset_of expects dot-separated field and variant names
|
||||||
|
|
||||||
|
parse_invalid_path_sep_in_fn_definition = invalid path separator in function definition
|
||||||
|
.suggestion = remove invalid path separator
|
||||||
|
|
||||||
parse_invalid_unicode_escape = invalid unicode character escape
|
parse_invalid_unicode_escape = invalid unicode character escape
|
||||||
.label = invalid escape
|
.label = invalid escape
|
||||||
.help = unicode escape must {$surrogate ->
|
.help = unicode escape must {$surrogate ->
|
||||||
|
@ -1755,6 +1755,14 @@ pub(crate) struct MissingFnParams {
|
|||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(parse_invalid_path_sep_in_fn_definition)]
|
||||||
|
pub(crate) struct InvalidPathSepInFnDefinition {
|
||||||
|
#[primary_span]
|
||||||
|
#[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(parse_missing_trait_in_trait_impl)]
|
#[diag(parse_missing_trait_in_trait_impl)]
|
||||||
pub(crate) struct MissingTraitInTraitImpl {
|
pub(crate) struct MissingTraitInTraitImpl {
|
||||||
|
@ -269,6 +269,13 @@ pub(super) fn parse_generic_params(&mut self) -> PResult<'a, ThinVec<ast::Generi
|
|||||||
/// | ( < lifetimes , typaramseq ( , )? > )
|
/// | ( < lifetimes , typaramseq ( , )? > )
|
||||||
/// where typaramseq = ( typaram ) | ( typaram , typaramseq )
|
/// where typaramseq = ( typaram ) | ( typaram , typaramseq )
|
||||||
pub(super) fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
|
pub(super) fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
|
||||||
|
// invalid path separator `::` in function definition
|
||||||
|
// for example `fn invalid_path_separator::<T>() {}`
|
||||||
|
if self.eat_noexpect(&token::PathSep) {
|
||||||
|
self.dcx()
|
||||||
|
.emit_err(errors::InvalidPathSepInFnDefinition { span: self.prev_token.span });
|
||||||
|
}
|
||||||
|
|
||||||
let span_lo = self.token.span;
|
let span_lo = self.token.span;
|
||||||
let (params, span) = if self.eat_lt() {
|
let (params, span) = if self.eat_lt() {
|
||||||
let params = self.parse_generic_params()?;
|
let params = self.parse_generic_params()?;
|
||||||
|
@ -173,7 +173,6 @@
|
|||||||
#![feature(allow_internal_unstable)]
|
#![feature(allow_internal_unstable)]
|
||||||
#![feature(cfg_sanitize)]
|
#![feature(cfg_sanitize)]
|
||||||
#![feature(const_precise_live_drops)]
|
#![feature(const_precise_live_drops)]
|
||||||
#![feature(const_ptr_write)]
|
|
||||||
#![feature(const_try)]
|
#![feature(const_try)]
|
||||||
#![feature(decl_macro)]
|
#![feature(decl_macro)]
|
||||||
#![feature(dropck_eyepatch)]
|
#![feature(dropck_eyepatch)]
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
#![feature(const_cow_is_borrowed)]
|
#![feature(const_cow_is_borrowed)]
|
||||||
#![feature(const_heap)]
|
#![feature(const_heap)]
|
||||||
#![cfg_attr(bootstrap, feature(const_mut_refs))]
|
#![cfg_attr(bootstrap, feature(const_mut_refs))]
|
||||||
#![feature(const_ptr_write)]
|
|
||||||
#![feature(const_try)]
|
#![feature(const_try)]
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
#![feature(extract_if)]
|
#![feature(extract_if)]
|
||||||
|
@ -1084,7 +1084,7 @@ pub fn select_unpredictable<T>(b: bool, true_val: T, false_val: T) -> T {
|
|||||||
/// it does not require an `unsafe` block.
|
/// it does not require an `unsafe` block.
|
||||||
/// Therefore, implementations must not require the user to uphold
|
/// Therefore, implementations must not require the user to uphold
|
||||||
/// any safety invariants.
|
/// any safety invariants.
|
||||||
#[rustc_const_unstable(feature = "const_intrinsic_forget", issue = "none")]
|
#[rustc_const_stable(feature = "const_intrinsic_forget", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_safe_intrinsic]
|
||||||
#[rustc_nounwind]
|
#[rustc_nounwind]
|
||||||
pub fn forget<T: ?Sized>(_: T);
|
pub fn forget<T: ?Sized>(_: T);
|
||||||
@ -2688,7 +2688,7 @@ pub fn select_unpredictable<T>(b: bool, true_val: T, false_val: T) -> T {
|
|||||||
/// This intrinsic can *only* be called where the pointer is a local without
|
/// This intrinsic can *only* be called where the pointer is a local without
|
||||||
/// projections (`write_via_move(ptr, x)`, not `write_via_move(*ptr, x)`) so
|
/// projections (`write_via_move(ptr, x)`, not `write_via_move(*ptr, x)`) so
|
||||||
/// that it trivially obeys runtime-MIR rules about derefs in operands.
|
/// that it trivially obeys runtime-MIR rules about derefs in operands.
|
||||||
#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
|
#[rustc_const_stable(feature = "const_ptr_write", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[rustc_nounwind]
|
#[rustc_nounwind]
|
||||||
pub fn write_via_move<T>(ptr: *mut T, value: T);
|
pub fn write_via_move<T>(ptr: *mut T, value: T);
|
||||||
|
|
||||||
@ -3525,13 +3525,13 @@ pub const fn ptr_metadata<P: ptr::Pointee<Metadata = M> + ?Sized, M>(_ptr: *cons
|
|||||||
#[doc(alias = "memset")]
|
#[doc(alias = "memset")]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_allowed_through_unstable_modules]
|
#[rustc_allowed_through_unstable_modules]
|
||||||
#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
|
#[rustc_const_stable(feature = "const_ptr_write", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||||
#[rustc_diagnostic_item = "ptr_write_bytes"]
|
#[rustc_diagnostic_item = "ptr_write_bytes"]
|
||||||
pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
|
pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
|
||||||
extern "rust-intrinsic" {
|
extern "rust-intrinsic" {
|
||||||
#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
|
#[rustc_const_stable(feature = "const_ptr_write", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[rustc_nounwind]
|
#[rustc_nounwind]
|
||||||
fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
|
fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,6 @@
|
|||||||
#![feature(const_hash)]
|
#![feature(const_hash)]
|
||||||
#![feature(const_heap)]
|
#![feature(const_heap)]
|
||||||
#![feature(const_index_range_slice_index)]
|
#![feature(const_index_range_slice_index)]
|
||||||
#![feature(const_intrinsic_forget)]
|
|
||||||
#![feature(const_ipv4)]
|
#![feature(const_ipv4)]
|
||||||
#![feature(const_ipv6)]
|
#![feature(const_ipv6)]
|
||||||
#![feature(const_likely)]
|
#![feature(const_likely)]
|
||||||
@ -138,9 +137,7 @@
|
|||||||
#![feature(const_pointer_is_aligned)]
|
#![feature(const_pointer_is_aligned)]
|
||||||
#![feature(const_ptr_is_null)]
|
#![feature(const_ptr_is_null)]
|
||||||
#![feature(const_ptr_sub_ptr)]
|
#![feature(const_ptr_sub_ptr)]
|
||||||
#![feature(const_ptr_write)]
|
|
||||||
#![feature(const_raw_ptr_comparison)]
|
#![feature(const_raw_ptr_comparison)]
|
||||||
#![feature(const_replace)]
|
|
||||||
#![feature(const_size_of_val)]
|
#![feature(const_size_of_val)]
|
||||||
#![feature(const_size_of_val_raw)]
|
#![feature(const_size_of_val_raw)]
|
||||||
#![feature(const_strict_overflow_ops)]
|
#![feature(const_strict_overflow_ops)]
|
||||||
|
@ -857,7 +857,8 @@ pub fn take<T: Default>(dest: &mut T) -> T {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[must_use = "if you don't need the old value, you can just assign the new value directly"]
|
#[must_use = "if you don't need the old value, you can just assign the new value directly"]
|
||||||
#[rustc_const_unstable(feature = "const_replace", issue = "83164")]
|
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))]
|
||||||
|
#[rustc_const_stable(feature = "const_replace", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[cfg_attr(not(test), rustc_diagnostic_item = "mem_replace")]
|
#[cfg_attr(not(test), rustc_diagnostic_item = "mem_replace")]
|
||||||
pub const fn replace<T>(dest: &mut T, src: T) -> T {
|
pub const fn replace<T>(dest: &mut T, src: T) -> T {
|
||||||
// It may be tempting to use `swap` to avoid `unsafe` here. Don't!
|
// It may be tempting to use `swap` to avoid `unsafe` here. Don't!
|
||||||
|
@ -1263,7 +1263,8 @@ macro_rules! attempt_swap_as_chunks {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_replace", issue = "83164")]
|
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))]
|
||||||
|
#[rustc_const_stable(feature = "const_replace", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[rustc_diagnostic_item = "ptr_replace"]
|
#[rustc_diagnostic_item = "ptr_replace"]
|
||||||
pub const unsafe fn replace<T>(dst: *mut T, src: T) -> T {
|
pub const unsafe fn replace<T>(dst: *mut T, src: T) -> T {
|
||||||
// SAFETY: the caller must guarantee that `dst` is valid to be
|
// SAFETY: the caller must guarantee that `dst` is valid to be
|
||||||
@ -1611,7 +1612,7 @@ macro_rules! attempt_swap_as_chunks {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
|
#[rustc_const_stable(feature = "const_ptr_write", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[rustc_diagnostic_item = "ptr_write"]
|
#[rustc_diagnostic_item = "ptr_write"]
|
||||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||||
pub const unsafe fn write<T>(dst: *mut T, src: T) {
|
pub const unsafe fn write<T>(dst: *mut T, src: T) {
|
||||||
@ -1719,7 +1720,8 @@ macro_rules! attempt_swap_as_chunks {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
|
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
|
||||||
#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
|
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_refs_to_cell))]
|
||||||
|
#[rustc_const_stable(feature = "const_ptr_write", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[rustc_diagnostic_item = "ptr_write_unaligned"]
|
#[rustc_diagnostic_item = "ptr_write_unaligned"]
|
||||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||||
pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
|
pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
|
||||||
|
@ -1449,7 +1449,7 @@ pub unsafe fn drop_in_place(self) {
|
|||||||
///
|
///
|
||||||
/// [`ptr::write`]: crate::ptr::write()
|
/// [`ptr::write`]: crate::ptr::write()
|
||||||
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
||||||
#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
|
#[rustc_const_stable(feature = "const_ptr_write", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||||
pub const unsafe fn write(self, val: T)
|
pub const unsafe fn write(self, val: T)
|
||||||
@ -1468,7 +1468,7 @@ pub unsafe fn drop_in_place(self) {
|
|||||||
/// [`ptr::write_bytes`]: crate::ptr::write_bytes()
|
/// [`ptr::write_bytes`]: crate::ptr::write_bytes()
|
||||||
#[doc(alias = "memset")]
|
#[doc(alias = "memset")]
|
||||||
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
||||||
#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
|
#[rustc_const_stable(feature = "const_ptr_write", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||||
pub const unsafe fn write_bytes(self, val: u8, count: usize)
|
pub const unsafe fn write_bytes(self, val: u8, count: usize)
|
||||||
@ -1509,7 +1509,7 @@ pub unsafe fn write_volatile(self, val: T)
|
|||||||
///
|
///
|
||||||
/// [`ptr::write_unaligned`]: crate::ptr::write_unaligned()
|
/// [`ptr::write_unaligned`]: crate::ptr::write_unaligned()
|
||||||
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
||||||
#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
|
#[rustc_const_stable(feature = "const_ptr_write", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||||
pub const unsafe fn write_unaligned(self, val: T)
|
pub const unsafe fn write_unaligned(self, val: T)
|
||||||
|
@ -1013,7 +1013,7 @@ pub unsafe fn drop_in_place(self) {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||||
#[stable(feature = "non_null_convenience", since = "1.80.0")]
|
#[stable(feature = "non_null_convenience", since = "1.80.0")]
|
||||||
#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
|
#[rustc_const_stable(feature = "const_ptr_write", since = "CURRENT_RUSTC_VERSION")]
|
||||||
pub const unsafe fn write(self, val: T)
|
pub const unsafe fn write(self, val: T)
|
||||||
where
|
where
|
||||||
T: Sized,
|
T: Sized,
|
||||||
@ -1032,7 +1032,7 @@ pub unsafe fn drop_in_place(self) {
|
|||||||
#[doc(alias = "memset")]
|
#[doc(alias = "memset")]
|
||||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||||
#[stable(feature = "non_null_convenience", since = "1.80.0")]
|
#[stable(feature = "non_null_convenience", since = "1.80.0")]
|
||||||
#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
|
#[rustc_const_stable(feature = "const_ptr_write", since = "CURRENT_RUSTC_VERSION")]
|
||||||
pub const unsafe fn write_bytes(self, val: u8, count: usize)
|
pub const unsafe fn write_bytes(self, val: u8, count: usize)
|
||||||
where
|
where
|
||||||
T: Sized,
|
T: Sized,
|
||||||
@ -1073,7 +1073,7 @@ pub unsafe fn write_volatile(self, val: T)
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||||
#[stable(feature = "non_null_convenience", since = "1.80.0")]
|
#[stable(feature = "non_null_convenience", since = "1.80.0")]
|
||||||
#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
|
#[rustc_const_stable(feature = "const_ptr_write", since = "CURRENT_RUSTC_VERSION")]
|
||||||
pub const unsafe fn write_unaligned(self, val: T)
|
pub const unsafe fn write_unaligned(self, val: T)
|
||||||
where
|
where
|
||||||
T: Sized,
|
T: Sized,
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
#![feature(const_option_ext)]
|
#![feature(const_option_ext)]
|
||||||
#![feature(const_pin)]
|
#![feature(const_pin)]
|
||||||
#![feature(const_pointer_is_aligned)]
|
#![feature(const_pointer_is_aligned)]
|
||||||
#![feature(const_ptr_write)]
|
|
||||||
#![feature(const_three_way_compare)]
|
#![feature(const_three_way_compare)]
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
|
@ -102,9 +102,24 @@ unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
|
|||||||
sys::init(argc, argv, sigpipe)
|
sys::init(argc, argv, sigpipe)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Set up the current thread to give it the right name.
|
// Set up the current thread handle to give it the right name.
|
||||||
let thread = Thread::new_main();
|
//
|
||||||
thread::set_current(thread);
|
// When code running before main uses `ReentrantLock` (for example by
|
||||||
|
// using `println!`), the thread ID can become initialized before we
|
||||||
|
// create this handle. Since `set_current` fails when the ID of the
|
||||||
|
// handle does not match the current ID, we should attempt to use the
|
||||||
|
// current thread ID here instead of unconditionally creating a new
|
||||||
|
// one. Also see #130210.
|
||||||
|
let thread = Thread::new_main(thread::current_id());
|
||||||
|
if let Err(_thread) = thread::set_current(thread) {
|
||||||
|
// `thread::current` will create a new handle if none has been set yet.
|
||||||
|
// Thus, if someone uses it before main, this call will fail. That's a
|
||||||
|
// bad idea though, as we then cannot set the main thread name here.
|
||||||
|
//
|
||||||
|
// FIXME: detect the main thread in `thread::current` and use the
|
||||||
|
// correct name there.
|
||||||
|
rtabort!("code running before main must not use thread::current");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clean up the thread-local runtime state. This *should* be run after all other
|
/// Clean up the thread-local runtime state. This *should* be run after all other
|
||||||
|
@ -110,22 +110,24 @@ pub(super) fn get_or_init() -> ThreadId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the thread handle for the current thread.
|
/// Tries to set the thread handle for the current thread. Fails if a handle was
|
||||||
///
|
/// already set or if the thread ID of `thread` would change an already-set ID.
|
||||||
/// Aborts if the handle or the ID has been set already.
|
pub(crate) fn set_current(thread: Thread) -> Result<(), Thread> {
|
||||||
pub(crate) fn set_current(thread: Thread) {
|
if CURRENT.get() != NONE {
|
||||||
if CURRENT.get() != NONE || id::get().is_some() {
|
return Err(thread);
|
||||||
// Using `panic` here can add ~3kB to the binary size. We have complete
|
|
||||||
// control over where this is called, so just abort if there is a bug.
|
|
||||||
rtabort!("thread::set_current should only be called once per thread");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
id::set(thread.id());
|
match id::get() {
|
||||||
|
Some(id) if id == thread.id() => {}
|
||||||
|
None => id::set(thread.id()),
|
||||||
|
_ => return Err(thread),
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure that `crate::rt::thread_cleanup` will be run, which will
|
// Make sure that `crate::rt::thread_cleanup` will be run, which will
|
||||||
// call `drop_current`.
|
// call `drop_current`.
|
||||||
crate::sys::thread_local::guard::enable();
|
crate::sys::thread_local::guard::enable();
|
||||||
CURRENT.set(thread.into_raw().cast_mut());
|
CURRENT.set(thread.into_raw().cast_mut());
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the id of the thread that invokes it.
|
/// Gets the id of the thread that invokes it.
|
||||||
|
@ -519,9 +519,14 @@ fn drop(&mut self) {
|
|||||||
|
|
||||||
let f = MaybeDangling::new(f);
|
let f = MaybeDangling::new(f);
|
||||||
let main = move || {
|
let main = move || {
|
||||||
// Immediately store the thread handle to avoid setting it or its ID
|
if let Err(_thread) = set_current(their_thread.clone()) {
|
||||||
// twice, which would cause an abort.
|
// Both the current thread handle and the ID should not be
|
||||||
set_current(their_thread.clone());
|
// initialized yet. Since only the C runtime and some of our
|
||||||
|
// platform code run before this, this point shouldn't be
|
||||||
|
// reachable. Use an abort to save binary size (see #123356).
|
||||||
|
rtabort!("something here is badly broken!");
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(name) = their_thread.cname() {
|
if let Some(name) = their_thread.cname() {
|
||||||
imp::Thread::set_name(name);
|
imp::Thread::set_name(name);
|
||||||
}
|
}
|
||||||
@ -1159,9 +1164,6 @@ pub fn park_timeout(dur: Duration) {
|
|||||||
pub struct ThreadId(NonZero<u64>);
|
pub struct ThreadId(NonZero<u64>);
|
||||||
|
|
||||||
impl ThreadId {
|
impl ThreadId {
|
||||||
// DO NOT rely on this value.
|
|
||||||
const MAIN_THREAD: ThreadId = ThreadId(unsafe { NonZero::new_unchecked(1) });
|
|
||||||
|
|
||||||
// Generate a new unique thread ID.
|
// Generate a new unique thread ID.
|
||||||
pub(crate) fn new() -> ThreadId {
|
pub(crate) fn new() -> ThreadId {
|
||||||
#[cold]
|
#[cold]
|
||||||
@ -1173,7 +1175,7 @@ fn exhausted() -> ! {
|
|||||||
if #[cfg(target_has_atomic = "64")] {
|
if #[cfg(target_has_atomic = "64")] {
|
||||||
use crate::sync::atomic::AtomicU64;
|
use crate::sync::atomic::AtomicU64;
|
||||||
|
|
||||||
static COUNTER: AtomicU64 = AtomicU64::new(1);
|
static COUNTER: AtomicU64 = AtomicU64::new(0);
|
||||||
|
|
||||||
let mut last = COUNTER.load(Ordering::Relaxed);
|
let mut last = COUNTER.load(Ordering::Relaxed);
|
||||||
loop {
|
loop {
|
||||||
@ -1189,7 +1191,7 @@ fn exhausted() -> ! {
|
|||||||
} else {
|
} else {
|
||||||
use crate::sync::{Mutex, PoisonError};
|
use crate::sync::{Mutex, PoisonError};
|
||||||
|
|
||||||
static COUNTER: Mutex<u64> = Mutex::new(1);
|
static COUNTER: Mutex<u64> = Mutex::new(0);
|
||||||
|
|
||||||
let mut counter = COUNTER.lock().unwrap_or_else(PoisonError::into_inner);
|
let mut counter = COUNTER.lock().unwrap_or_else(PoisonError::into_inner);
|
||||||
let Some(id) = counter.checked_add(1) else {
|
let Some(id) = counter.checked_add(1) else {
|
||||||
@ -1326,9 +1328,9 @@ pub(crate) fn new_unnamed(id: ThreadId) -> Thread {
|
|||||||
Self::new_inner(id, ThreadName::Unnamed)
|
Self::new_inner(id, ThreadName::Unnamed)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used in runtime to construct main thread
|
/// Constructs the thread handle for the main thread.
|
||||||
pub(crate) fn new_main() -> Thread {
|
pub(crate) fn new_main(id: ThreadId) -> Thread {
|
||||||
Self::new_inner(ThreadId::MAIN_THREAD, ThreadName::Main)
|
Self::new_inner(id, ThreadName::Main)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_inner(id: ThreadId, name: ThreadName) -> Thread {
|
fn new_inner(id: ThreadId, name: ThreadName) -> Thread {
|
||||||
|
@ -398,7 +398,14 @@ fn stamp(builder: &Builder<'_>, compiler: Compiler, target: TargetSelection) ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! tool_check_step {
|
macro_rules! tool_check_step {
|
||||||
($name:ident, $path:literal, $($alias:literal, )* $source_type:path $(, $default:literal )?) => {
|
(
|
||||||
|
$name:ident,
|
||||||
|
$display_name:literal,
|
||||||
|
$path:literal,
|
||||||
|
$($alias:literal, )*
|
||||||
|
$source_type:path
|
||||||
|
$(, $default:literal )?
|
||||||
|
) => {
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct $name {
|
pub struct $name {
|
||||||
pub target: TargetSelection,
|
pub target: TargetSelection,
|
||||||
@ -441,7 +448,7 @@ fn run(self, builder: &Builder<'_>) {
|
|||||||
cargo.arg("--all-targets");
|
cargo.arg("--all-targets");
|
||||||
}
|
}
|
||||||
|
|
||||||
let _guard = builder.msg_check(&concat!(stringify!($name), " artifacts").to_lowercase(), target);
|
let _guard = builder.msg_check(&format!("{} artifacts", $display_name), target);
|
||||||
run_cargo(
|
run_cargo(
|
||||||
builder,
|
builder,
|
||||||
cargo,
|
cargo,
|
||||||
@ -468,20 +475,30 @@ fn stamp(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
tool_check_step!(Rustdoc, "src/tools/rustdoc", "src/librustdoc", SourceType::InTree);
|
tool_check_step!(Rustdoc, "rustdoc", "src/tools/rustdoc", "src/librustdoc", SourceType::InTree);
|
||||||
// Clippy, miri and Rustfmt are hybrids. They are external tools, but use a git subtree instead
|
// Clippy, miri and Rustfmt are hybrids. They are external tools, but use a git subtree instead
|
||||||
// of a submodule. Since the SourceType only drives the deny-warnings
|
// of a submodule. Since the SourceType only drives the deny-warnings
|
||||||
// behavior, treat it as in-tree so that any new warnings in clippy will be
|
// behavior, treat it as in-tree so that any new warnings in clippy will be
|
||||||
// rejected.
|
// rejected.
|
||||||
tool_check_step!(Clippy, "src/tools/clippy", SourceType::InTree);
|
tool_check_step!(Clippy, "clippy", "src/tools/clippy", SourceType::InTree);
|
||||||
tool_check_step!(Miri, "src/tools/miri", SourceType::InTree);
|
tool_check_step!(Miri, "miri", "src/tools/miri", SourceType::InTree);
|
||||||
tool_check_step!(CargoMiri, "src/tools/miri/cargo-miri", SourceType::InTree);
|
tool_check_step!(CargoMiri, "cargo-miri", "src/tools/miri/cargo-miri", SourceType::InTree);
|
||||||
tool_check_step!(Rls, "src/tools/rls", SourceType::InTree);
|
tool_check_step!(Rls, "rls", "src/tools/rls", SourceType::InTree);
|
||||||
tool_check_step!(Rustfmt, "src/tools/rustfmt", SourceType::InTree);
|
tool_check_step!(Rustfmt, "rustfmt", "src/tools/rustfmt", SourceType::InTree);
|
||||||
tool_check_step!(MiroptTestTools, "src/tools/miropt-test-tools", SourceType::InTree);
|
tool_check_step!(
|
||||||
tool_check_step!(TestFloatParse, "src/etc/test-float-parse", SourceType::InTree);
|
MiroptTestTools,
|
||||||
|
"miropt-test-tools",
|
||||||
|
"src/tools/miropt-test-tools",
|
||||||
|
SourceType::InTree
|
||||||
|
);
|
||||||
|
tool_check_step!(
|
||||||
|
TestFloatParse,
|
||||||
|
"test-float-parse",
|
||||||
|
"src/etc/test-float-parse",
|
||||||
|
SourceType::InTree
|
||||||
|
);
|
||||||
|
|
||||||
tool_check_step!(Bootstrap, "src/bootstrap", SourceType::InTree, false);
|
tool_check_step!(Bootstrap, "bootstrap", "src/bootstrap", SourceType::InTree, false);
|
||||||
|
|
||||||
/// Cargo's output path for the standard library in a given stage, compiled
|
/// Cargo's output path for the standard library in a given stage, compiled
|
||||||
/// by a particular compiler for the specified target.
|
/// by a particular compiler for the specified target.
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
//@ run-pass
|
//@ run-pass
|
||||||
|
|
||||||
#![feature(const_ptr_write)]
|
|
||||||
// issue: https://github.com/rust-lang/rust/issues/69488
|
// issue: https://github.com/rust-lang/rust/issues/69488
|
||||||
// Loads of partially-initialized data could produce completely-uninitialized results.
|
// Loads of partially-initialized data could produce completely-uninitialized results.
|
||||||
// Test to make sure that we no longer do such a "deinitializing" load.
|
// Test to make sure that we no longer do such a "deinitializing" load.
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
//@ run-rustfix
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn invalid_path_separator<T>() {}
|
||||||
|
//~^ ERROR invalid path separator in function definition
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,7 @@
|
|||||||
|
//@ run-rustfix
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn invalid_path_separator::<T>() {}
|
||||||
|
//~^ ERROR invalid path separator in function definition
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,14 @@
|
|||||||
|
error: invalid path separator in function definition
|
||||||
|
--> $DIR/invalid-path-sep-in-fn-definition-issue-130791.rs:4:26
|
||||||
|
|
|
||||||
|
LL | fn invalid_path_separator::<T>() {}
|
||||||
|
| ^^
|
||||||
|
|
|
||||||
|
help: remove invalid path separator
|
||||||
|
|
|
||||||
|
LL - fn invalid_path_separator::<T>() {}
|
||||||
|
LL + fn invalid_path_separator<T>() {}
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
24
tests/ui/runtime/stdout-before-main.rs
Normal file
24
tests/ui/runtime/stdout-before-main.rs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
//@ run-pass
|
||||||
|
//@ check-run-results
|
||||||
|
//@ only-gnu
|
||||||
|
//@ only-linux
|
||||||
|
//
|
||||||
|
// Regression test for #130210.
|
||||||
|
// .init_array doesn't work everywhere, so we limit the test to just GNU/Linux.
|
||||||
|
|
||||||
|
use std::ffi::c_int;
|
||||||
|
use std::thread;
|
||||||
|
|
||||||
|
#[used]
|
||||||
|
#[link_section = ".init_array"]
|
||||||
|
static INIT: extern "C" fn(c_int, *const *const u8, *const *const u8) = {
|
||||||
|
extern "C" fn init(_argc: c_int, _argv: *const *const u8, _envp: *const *const u8) {
|
||||||
|
print!("Hello from before ");
|
||||||
|
}
|
||||||
|
|
||||||
|
init
|
||||||
|
};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("{}!", thread::current().name().unwrap());
|
||||||
|
}
|
1
tests/ui/runtime/stdout-before-main.run.stdout
Normal file
1
tests/ui/runtime/stdout-before-main.run.stdout
Normal file
@ -0,0 +1 @@
|
|||||||
|
Hello from before main!
|
Loading…
Reference in New Issue
Block a user