From 57046e1470385078c866cbe2e2d5bfb0c666d0fd Mon Sep 17 00:00:00 2001 From: binarycat Date: Sun, 2 Mar 2025 09:49:43 -0600 Subject: [PATCH 01/31] doc: clarify that consume can be called after BufReader::peek --- library/std/src/io/buffered/bufreader.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs index 8b46738ab8aee..b39bc7116424f 100644 --- a/library/std/src/io/buffered/bufreader.rs +++ b/library/std/src/io/buffered/bufreader.rs @@ -109,9 +109,13 @@ impl BufReader { /// /// `n` must be less than or equal to `capacity`. /// - /// the returned slice may be less than `n` bytes long if + /// The returned slice may be less than `n` bytes long if /// end of file is reached. /// + /// After calling this method, you may call [`consume`](BufRead::consume) + /// with a value less than or equal to `n` to advance over some or all of + /// the returned bytes. + /// /// ## Examples /// /// ```rust From 69ef2fc908f79d97c6deeee3e2a220688782a62d Mon Sep 17 00:00:00 2001 From: wieDasDing <6884440+dingxiangfei2009@users.noreply.github.com> Date: Tue, 4 Mar 2025 05:22:26 +0800 Subject: [PATCH 02/31] fix: properly escape regexes --- src/etc/lldb_batchmode.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/etc/lldb_batchmode.py b/src/etc/lldb_batchmode.py index cf88c53e085e1..5cc9bb23628f0 100644 --- a/src/etc/lldb_batchmode.py +++ b/src/etc/lldb_batchmode.py @@ -40,7 +40,7 @@ def print_debug(s): def normalize_whitespace(s): """Replace newlines, tabs, multiple spaces, etc with exactly one space""" - return re.sub("\s+", " ", s) + return re.sub(r"\s+", " ", s) def breakpoint_callback(frame, bp_loc, dict): @@ -234,7 +234,7 @@ def watchdog(): if ( command == "run" or command == "r" - or re.match("^process\s+launch.*", command) + or re.match(r"^process\s+launch.*", command) ): # Before starting to run the program, let the thread sleep a bit, so all # breakpoint added events can be processed From 638b226a6ab5c5c784955068f57ae249e0ed0f92 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Wed, 5 Mar 2025 18:14:07 -0800 Subject: [PATCH 03/31] Remove #[cfg(not(test))] gates in core These gates are unnecessary now that unit tests for `core` are in a separate package, `coretests`, instead of in the same files as the source code. They previously prevented the two `core` versions from conflicting with each other. --- ...0027-stdlib-128bit-atomic-operations.patch | 24 ++++++++--------- library/core/src/any.rs | 2 +- library/core/src/array/ascii.rs | 1 - library/core/src/bool.rs | 2 +- library/core/src/cell.rs | 4 +-- library/core/src/char/methods.rs | 2 +- library/core/src/cmp.rs | 4 +-- library/core/src/convert/mod.rs | 4 +-- library/core/src/default.rs | 2 +- library/core/src/error.rs | 2 +- library/core/src/fmt/mod.rs | 2 +- library/core/src/iter/adapters/enumerate.rs | 2 +- library/core/src/iter/sources/repeat.rs | 2 +- library/core/src/iter/traits/double_ended.rs | 2 +- library/core/src/iter/traits/iterator.rs | 10 +++---- library/core/src/lib.rs | 17 ------------ library/core/src/macros/mod.rs | 26 +++++++++---------- library/core/src/marker.rs | 6 ++--- library/core/src/mem/mod.rs | 12 ++++----- library/core/src/net/ip_addr.rs | 2 +- library/core/src/num/f128.rs | 5 +--- library/core/src/num/f16.rs | 5 +--- library/core/src/num/f32.rs | 7 ++--- library/core/src/num/f64.rs | 7 ++--- library/core/src/ops/control_flow.rs | 2 +- library/core/src/option.rs | 4 +-- library/core/src/panic/unwind_safe.rs | 4 +-- library/core/src/result.rs | 2 +- library/core/src/slice/ascii.rs | 1 - library/core/src/slice/mod.rs | 5 +--- library/core/src/str/mod.rs | 17 ++++++------ library/core/src/sync/atomic.rs | 26 +++++++++---------- library/core/src/task/wake.rs | 2 +- library/core/src/time.rs | 2 +- 34 files changed, 90 insertions(+), 127 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch b/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch index 3c81b04c0ead2..d7e3b11127c42 100644 --- a/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch +++ b/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch @@ -1,4 +1,4 @@ -From ad7ffe71baba46865f2e65266ab025920dfdc20b Mon Sep 17 00:00:00 2001 +From 5d7c709608b01301d4628d2159265936d4440b67 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 18 Feb 2021 18:45:28 +0100 Subject: [PATCH] Disable 128bit atomic operations @@ -7,11 +7,10 @@ Cranelift doesn't support them yet --- library/core/src/panic/unwind_safe.rs | 6 ----- library/core/src/sync/atomic.rs | 38 --------------------------- - library/core/tests/atomic.rs | 4 --- - 4 files changed, 4 insertions(+), 50 deletions(-) + 2 files changed, 44 deletions(-) diff --git a/library/core/src/panic/unwind_safe.rs b/library/core/src/panic/unwind_safe.rs -index 092b7cf..158cf71 100644 +index a60f0799c0e..af056fbf41f 100644 --- a/library/core/src/panic/unwind_safe.rs +++ b/library/core/src/panic/unwind_safe.rs @@ -216,9 +216,6 @@ impl RefUnwindSafe for crate::sync::atomic::AtomicI32 {} @@ -21,7 +20,7 @@ index 092b7cf..158cf71 100644 -#[cfg(target_has_atomic_load_store = "128")] -#[unstable(feature = "integer_atomics", issue = "99069")] -impl RefUnwindSafe for crate::sync::atomic::AtomicI128 {} - + #[cfg(target_has_atomic_load_store = "ptr")] #[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")] @@ -235,9 +232,6 @@ impl RefUnwindSafe for crate::sync::atomic::AtomicU32 {} @@ -31,14 +30,14 @@ index 092b7cf..158cf71 100644 -#[cfg(target_has_atomic_load_store = "128")] -#[unstable(feature = "integer_atomics", issue = "99069")] -impl RefUnwindSafe for crate::sync::atomic::AtomicU128 {} - + #[cfg(target_has_atomic_load_store = "8")] #[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")] diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs -index d9de37e..8293fce 100644 +index bf2b6d59f88..d5ccce03bbf 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs -@@ -2996,44 +2996,6 @@ atomic_int! { +@@ -3585,44 +3585,6 @@ pub const fn as_ptr(&self) -> *mut $int_type { 8, u64 AtomicU64 } @@ -54,7 +53,7 @@ index d9de37e..8293fce 100644 - unstable(feature = "integer_atomics", issue = "99069"), - rustc_const_unstable(feature = "integer_atomics", issue = "99069"), - rustc_const_unstable(feature = "integer_atomics", issue = "99069"), -- cfg_attr(not(test), rustc_diagnostic_item = "AtomicI128"), +- rustc_diagnostic_item = "AtomicI128", - "i128", - "#![feature(integer_atomics)]\n\n", - atomic_min, atomic_max, @@ -73,7 +72,7 @@ index d9de37e..8293fce 100644 - unstable(feature = "integer_atomics", issue = "99069"), - rustc_const_unstable(feature = "integer_atomics", issue = "99069"), - rustc_const_unstable(feature = "integer_atomics", issue = "99069"), -- cfg_attr(not(test), rustc_diagnostic_item = "AtomicU128"), +- rustc_diagnostic_item = "AtomicU128", - "u128", - "#![feature(integer_atomics)]\n\n", - atomic_umin, atomic_umax, @@ -83,7 +82,6 @@ index d9de37e..8293fce 100644 #[cfg(target_has_atomic_load_store = "ptr")] macro_rules! atomic_int_ptr_sized { - ( $($target_pointer_width:literal $align:literal)* ) => { $( --- -2.26.2.7.g19db9cfb68 +-- +2.48.1 diff --git a/library/core/src/any.rs b/library/core/src/any.rs index 9ed2c8e9f3ad1..10f2a11d558be 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -109,7 +109,7 @@ use crate::{fmt, hash, intrinsics}; // unsafe traits and unsafe methods (i.e., `type_id` would still be safe to call, // but we would likely want to indicate as such in documentation). #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "Any")] +#[rustc_diagnostic_item = "Any"] pub trait Any: 'static { /// Gets the `TypeId` of `self`. /// diff --git a/library/core/src/array/ascii.rs b/library/core/src/array/ascii.rs index e2faef855bc2c..792a57e3fa25c 100644 --- a/library/core/src/array/ascii.rs +++ b/library/core/src/array/ascii.rs @@ -1,6 +1,5 @@ use crate::ascii; -#[cfg(not(test))] impl [u8; N] { /// Converts this array of bytes into an array of ASCII characters, /// or returns `None` if any of the characters is non-ASCII. diff --git a/library/core/src/bool.rs b/library/core/src/bool.rs index 3c589ca5dfa7e..d525ab425e60d 100644 --- a/library/core/src/bool.rs +++ b/library/core/src/bool.rs @@ -56,7 +56,7 @@ impl bool { /// ``` #[doc(alias = "then_with")] #[stable(feature = "lazy_bool_to_option", since = "1.50.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "bool_then")] + #[rustc_diagnostic_item = "bool_then"] #[inline] pub fn then T>(self, f: F) -> Option { if self { Some(f()) } else { None } diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index cbf00106c5173..1a320b316a41a 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -304,7 +304,7 @@ pub use once::OnceCell; /// ``` /// /// See the [module-level documentation](self) for more. -#[cfg_attr(not(test), rustc_diagnostic_item = "Cell")] +#[rustc_diagnostic_item = "Cell"] #[stable(feature = "rust1", since = "1.0.0")] #[repr(transparent)] #[rustc_pub_transparent] @@ -725,7 +725,7 @@ impl Cell<[T; N]> { /// A mutable memory location with dynamically checked borrow rules /// /// See the [module-level documentation](self) for more. -#[cfg_attr(not(test), rustc_diagnostic_item = "RefCell")] +#[rustc_diagnostic_item = "RefCell"] #[stable(feature = "rust1", since = "1.0.0")] pub struct RefCell { borrow: Cell, diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index 85cc315626d4b..dc076a7cce50a 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -1178,7 +1178,7 @@ impl char { #[must_use] #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_char_is_ascii", since = "1.32.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "char_is_ascii")] + #[rustc_diagnostic_item = "char_is_ascii"] #[inline] pub const fn is_ascii(&self) -> bool { *self as u32 <= 0x7F diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index c8ced78c4d791..582138d6c9241 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -1471,7 +1471,7 @@ pub macro PartialOrd($item:item) { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "cmp_min")] +#[rustc_diagnostic_item = "cmp_min"] pub fn min(v1: T, v2: T) -> T { v1.min(v2) } @@ -1563,7 +1563,7 @@ pub fn min_by_key K, K: Ord>(v1: T, v2: T, mut f: F) -> T { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "cmp_max")] +#[rustc_diagnostic_item = "cmp_max"] pub fn max(v1: T, v2: T) -> T { v1.max(v2) } diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index e468f4f0f7e66..cfa9ae73f2d2d 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -214,7 +214,7 @@ pub const fn identity(x: T) -> T { /// is_hello(s); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "AsRef")] +#[rustc_diagnostic_item = "AsRef"] pub trait AsRef { /// Converts this type into a shared reference of the (usually inferred) input type. #[stable(feature = "rust1", since = "1.0.0")] @@ -365,7 +365,7 @@ pub trait AsRef { /// Note, however, that APIs don't need to be generic. In many cases taking a `&mut [u8]` or /// `&mut Vec`, for example, is the better choice (callers need to pass the correct type then). #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "AsMut")] +#[rustc_diagnostic_item = "AsMut"] pub trait AsMut { /// Converts this type into a mutable reference of the (usually inferred) input type. #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/default.rs b/library/core/src/default.rs index 4c30290ff263b..044997a81a9a2 100644 --- a/library/core/src/default.rs +++ b/library/core/src/default.rs @@ -101,7 +101,7 @@ use crate::ascii::Char as AsciiChar; /// bar: f32, /// } /// ``` -#[cfg_attr(not(test), rustc_diagnostic_item = "Default")] +#[rustc_diagnostic_item = "Default"] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_trivial_field_reads] pub trait Default: Sized { diff --git a/library/core/src/error.rs b/library/core/src/error.rs index 94847685ec965..bfa392003b91b 100644 --- a/library/core/src/error.rs +++ b/library/core/src/error.rs @@ -47,7 +47,7 @@ use crate::fmt::{self, Debug, Display, Formatter}; /// impl Error for ReadConfigError {} /// ``` #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "Error")] +#[rustc_diagnostic_item = "Error"] #[rustc_has_incoherent_inherent_impls] #[allow(multiple_supertrait_upcastable)] pub trait Error: Debug + Display { diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 3f60bb067d6e6..bd7566e48f82d 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -18,7 +18,7 @@ mod num; mod rt; #[stable(feature = "fmt_flags_align", since = "1.28.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "Alignment")] +#[rustc_diagnostic_item = "Alignment"] /// Possible alignments returned by `Formatter::align` #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum Alignment { diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs index ac15e3767fc09..f9c388e8564d3 100644 --- a/library/core/src/iter/adapters/enumerate.rs +++ b/library/core/src/iter/adapters/enumerate.rs @@ -14,7 +14,7 @@ use crate::ops::Try; #[derive(Clone, Debug)] #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "Enumerate")] +#[rustc_diagnostic_item = "Enumerate"] pub struct Enumerate { iter: I, count: usize, diff --git a/library/core/src/iter/sources/repeat.rs b/library/core/src/iter/sources/repeat.rs index 243f938bce2af..c4f5a483e5c2a 100644 --- a/library/core/src/iter/sources/repeat.rs +++ b/library/core/src/iter/sources/repeat.rs @@ -56,7 +56,7 @@ use crate::num::NonZero; /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "iter_repeat")] +#[rustc_diagnostic_item = "iter_repeat"] pub fn repeat(elt: T) -> Repeat { Repeat { element: elt } } diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs index 3b12678572841..7dabaece95561 100644 --- a/library/core/src/iter/traits/double_ended.rs +++ b/library/core/src/iter/traits/double_ended.rs @@ -37,7 +37,7 @@ use crate::ops::{ControlFlow, Try}; /// assert_eq!(None, iter.next_back()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "DoubleEndedIterator")] +#[rustc_diagnostic_item = "DoubleEndedIterator"] pub trait DoubleEndedIterator: Iterator { /// Removes and returns an element from the end of the iterator. /// diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 42886e90f997d..f22d03525d5f9 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -862,7 +862,7 @@ pub trait Iterator { /// Note that `iter.filter(f).next()` is equivalent to `iter.find(f)`. #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "iter_filter")] + #[rustc_diagnostic_item = "iter_filter"] fn filter

(self, predicate: P) -> Filter where Self: Sized, @@ -954,7 +954,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "enumerate_method")] + #[rustc_diagnostic_item = "enumerate_method"] fn enumerate(self) -> Enumerate where Self: Sized, @@ -1963,7 +1963,7 @@ pub trait Iterator { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] - #[cfg_attr(not(test), rustc_diagnostic_item = "iterator_collect_fn")] + #[rustc_diagnostic_item = "iterator_collect_fn"] fn collect>(self) -> B where Self: Sized, @@ -3358,7 +3358,7 @@ pub trait Iterator { /// assert_eq!(v_map, vec![1, 2, 3]); /// ``` #[stable(feature = "iter_copied", since = "1.36.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "iter_copied")] + #[rustc_diagnostic_item = "iter_copied"] fn copied<'a, T: 'a>(self) -> Copied where Self: Sized + Iterator, @@ -3406,7 +3406,7 @@ pub trait Iterator { /// assert_eq!(&[vec![23]], &faster[..]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "iter_cloned")] + #[rustc_diagnostic_item = "iter_cloned"] fn cloned<'a, T: 'a>(self) -> Cloned where Self: Sized + Iterator, diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index db68f472c42f6..620db4445fce6 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -43,18 +43,6 @@ //! which do not trigger a panic can be assured that this function is never //! called. The `lang` attribute is called `eh_personality`. -// Since core defines many fundamental lang items, all tests live in a -// separate crate, coretests (library/coretests), to avoid bizarre issues. -// -// Here we explicitly #[cfg]-out this whole crate when testing. If we don't do -// this, both the generated test artifact and the linked libtest (which -// transitively includes core) will both define the same set of lang items, -// and this will cause the E0152 "found duplicate lang item" error. See -// discussion in #50466 for details. -// -// This cfg won't affect doc tests. -#![cfg(not(test))] -// #![stable(feature = "core", since = "1.6.0")] #![doc( html_playground_url = "https://play.rust-lang.org/", @@ -64,7 +52,6 @@ )] #![doc(rust_logo)] #![doc(cfg_hide( - not(test), no_fp_fmt_parse, target_pointer_width = "16", target_pointer_width = "32", @@ -225,13 +212,9 @@ extern crate self as core; #[allow(unused)] use prelude::rust_2021::*; -#[cfg(not(test))] // See #65860 #[macro_use] mod macros; -// We don't export this through #[macro_export] for now, to avoid breakage. -// See https://github.com/rust-lang/rust/issues/82913 -#[cfg(not(test))] #[unstable(feature = "assert_matches", issue = "82775")] /// Unstable module containing the unstable `assert_matches` macro. pub mod assert_matches { diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 16200184422b9..12ec07a22c695 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -37,7 +37,7 @@ macro_rules! panic { /// ``` #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "assert_eq_macro")] +#[rustc_diagnostic_item = "assert_eq_macro"] #[allow_internal_unstable(panic_internals)] macro_rules! assert_eq { ($left:expr, $right:expr $(,)?) => { @@ -93,7 +93,7 @@ macro_rules! assert_eq { /// ``` #[macro_export] #[stable(feature = "assert_ne", since = "1.13.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "assert_ne_macro")] +#[rustc_diagnostic_item = "assert_ne_macro"] #[allow_internal_unstable(panic_internals)] macro_rules! assert_ne { ($left:expr, $right:expr $(,)?) => { @@ -331,7 +331,7 @@ macro_rules! debug_assert { /// ``` #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "debug_assert_eq_macro")] +#[rustc_diagnostic_item = "debug_assert_eq_macro"] macro_rules! debug_assert_eq { ($($arg:tt)*) => { if $crate::cfg!(debug_assertions) { @@ -361,7 +361,7 @@ macro_rules! debug_assert_eq { /// ``` #[macro_export] #[stable(feature = "assert_ne", since = "1.13.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "debug_assert_ne_macro")] +#[rustc_diagnostic_item = "debug_assert_ne_macro"] macro_rules! debug_assert_ne { ($($arg:tt)*) => { if $crate::cfg!(debug_assertions) { @@ -442,7 +442,7 @@ pub macro debug_assert_matches($($arg:tt)*) { /// ``` #[macro_export] #[stable(feature = "matches_macro", since = "1.42.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "matches_macro")] +#[rustc_diagnostic_item = "matches_macro"] macro_rules! matches { ($expression:expr, $pattern:pat $(if $guard:expr)? $(,)?) => { match $expression { @@ -617,7 +617,7 @@ macro_rules! r#try { /// ``` #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "write_macro")] +#[rustc_diagnostic_item = "write_macro"] macro_rules! write { ($dst:expr, $($arg:tt)*) => { $dst.write_fmt($crate::format_args!($($arg)*)) @@ -651,7 +651,7 @@ macro_rules! write { /// ``` #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "writeln_macro")] +#[rustc_diagnostic_item = "writeln_macro"] #[allow_internal_unstable(format_args_nl)] macro_rules! writeln { ($dst:expr $(,)?) => { @@ -718,7 +718,7 @@ macro_rules! writeln { #[rustc_builtin_macro(unreachable)] #[allow_internal_unstable(edition_panic)] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "unreachable_macro")] +#[rustc_diagnostic_item = "unreachable_macro"] macro_rules! unreachable { // Expands to either `$crate::panic::unreachable_2015` or `$crate::panic::unreachable_2021` // depending on the edition of the caller. @@ -803,7 +803,7 @@ macro_rules! unreachable { /// ``` #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "unimplemented_macro")] +#[rustc_diagnostic_item = "unimplemented_macro"] #[allow_internal_unstable(panic_internals)] macro_rules! unimplemented { () => { @@ -883,7 +883,7 @@ macro_rules! unimplemented { /// ``` #[macro_export] #[stable(feature = "todo_macro", since = "1.40.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "todo_macro")] +#[rustc_diagnostic_item = "todo_macro"] #[allow_internal_unstable(panic_internals)] macro_rules! todo { () => { @@ -995,7 +995,7 @@ pub(crate) mod builtin { /// and cannot be stored for later use. /// This is a known limitation, see [#92698](https://github.com/rust-lang/rust/issues/92698). #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "format_args_macro")] + #[rustc_diagnostic_item = "format_args_macro"] #[allow_internal_unsafe] #[allow_internal_unstable(fmt_internals)] #[rustc_builtin_macro] @@ -1342,7 +1342,7 @@ pub(crate) mod builtin { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_builtin_macro] #[macro_export] - #[cfg_attr(not(test), rustc_diagnostic_item = "include_str_macro")] + #[rustc_diagnostic_item = "include_str_macro"] macro_rules! include_str { ($file:expr $(,)?) => {{ /* compiler built-in */ }}; } @@ -1382,7 +1382,7 @@ pub(crate) mod builtin { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_builtin_macro] #[macro_export] - #[cfg_attr(not(test), rustc_diagnostic_item = "include_bytes_macro")] + #[rustc_diagnostic_item = "include_bytes_macro"] macro_rules! include_bytes { ($file:expr $(,)?) => {{ /* compiler built-in */ }}; } diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index b0571bf7247af..10c3c14afa890 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -82,7 +82,7 @@ macro marker_impls { /// [arc]: ../../std/sync/struct.Arc.html /// [ub]: ../../reference/behavior-considered-undefined.html #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "Send")] +#[rustc_diagnostic_item = "Send"] #[diagnostic::on_unimplemented( message = "`{Self}` cannot be sent between threads safely", label = "`{Self}` cannot be sent between threads safely" @@ -541,7 +541,7 @@ pub trait BikeshedGuaranteedNoDrop {} /// [transmute]: crate::mem::transmute /// [nomicon-send-and-sync]: ../../nomicon/send-and-sync.html #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "Sync")] +#[rustc_diagnostic_item = "Sync"] #[lang = "sync"] #[rustc_on_unimplemented( on( @@ -1302,7 +1302,7 @@ pub trait FnPtr: Copy + Clone { /// ``` #[rustc_builtin_macro(CoercePointee, attributes(pointee))] #[allow_internal_unstable(dispatch_from_dyn, coerce_unsized, unsize, coerce_pointee_validated)] -#[cfg_attr(not(test), rustc_diagnostic_item = "CoercePointee")] +#[rustc_diagnostic_item = "CoercePointee"] #[unstable(feature = "derive_coerce_pointee", issue = "123430")] pub macro CoercePointee($item:item) { /* compiler built-in */ diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index b9bb6d6a13f7f..fecab730a74c0 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -140,7 +140,7 @@ pub use crate::intrinsics::transmute; #[inline] #[rustc_const_stable(feature = "const_forget", since = "1.46.0")] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "mem_forget")] +#[rustc_diagnostic_item = "mem_forget"] pub const fn forget(t: T) { let _ = ManuallyDrop::new(t); } @@ -304,7 +304,7 @@ pub fn forget_unsized(t: T) { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_promotable] #[rustc_const_stable(feature = "const_mem_size_of", since = "1.24.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "mem_size_of")] +#[rustc_diagnostic_item = "mem_size_of"] pub const fn size_of() -> usize { intrinsics::size_of::() } @@ -334,7 +334,7 @@ pub const fn size_of() -> usize { #[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_size_of_val", since = "1.85.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "mem_size_of_val")] +#[rustc_diagnostic_item = "mem_size_of_val"] pub const fn size_of_val(val: &T) -> usize { // SAFETY: `val` is a reference, so it's a valid raw pointer unsafe { intrinsics::size_of_val(val) } @@ -856,7 +856,7 @@ pub fn take(dest: &mut T) -> T { #[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"] #[rustc_const_stable(feature = "const_replace", since = "1.83.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "mem_replace")] +#[rustc_diagnostic_item = "mem_replace"] pub const fn replace(dest: &mut T, src: T) -> T { // It may be tempting to use `swap` to avoid `unsafe` here. Don't! // The compiler optimizes the implementation below to two `memcpy`s @@ -936,7 +936,7 @@ pub const fn replace(dest: &mut T, src: T) -> T { /// [`RefCell`]: crate::cell::RefCell #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "mem_drop")] +#[rustc_diagnostic_item = "mem_drop"] pub fn drop(_x: T) {} /// Bitwise-copies a value. @@ -1159,7 +1159,7 @@ impl fmt::Debug for Discriminant { /// ``` #[stable(feature = "discriminant_value", since = "1.21.0")] #[rustc_const_stable(feature = "const_discriminant", since = "1.75.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "mem_discriminant")] +#[rustc_diagnostic_item = "mem_discriminant"] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const fn discriminant(v: &T) -> Discriminant { Discriminant(intrinsics::discriminant_value(v)) diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs index 8e4417ec461b8..7aa5ed60d0467 100644 --- a/library/core/src/net/ip_addr.rs +++ b/library/core/src/net/ip_addr.rs @@ -25,7 +25,7 @@ use crate::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Not}; /// assert_eq!(localhost_v4.is_ipv6(), false); /// assert_eq!(localhost_v4.is_ipv4(), true); /// ``` -#[cfg_attr(not(test), rustc_diagnostic_item = "IpAddr")] +#[rustc_diagnostic_item = "IpAddr"] #[stable(feature = "ip_addr", since = "1.7.0")] #[derive(Copy, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)] pub enum IpAddr { diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 5e45974b3d422..b17190971c3e8 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -12,11 +12,9 @@ #![unstable(feature = "f128", issue = "116909")] use crate::convert::FloatToInt; -#[cfg(not(test))] -use crate::intrinsics; -use crate::mem; use crate::num::FpCategory; use crate::panic::const_assert; +use crate::{intrinsics, mem}; /// Basic mathematical constants. #[unstable(feature = "f128", issue = "116909")] @@ -138,7 +136,6 @@ pub mod consts { pub const LN_10: f128 = 2.30258509299404568401799145468436420760110148862877297603333_f128; } -#[cfg(not(test))] impl f128 { // FIXME(f16_f128): almost all methods in this `impl` are missing examples and a const // implementation. Add these once we can run code on all platforms and have f16/f128 in CTFE. diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index e3176cd168852..d20677f43b417 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -12,11 +12,9 @@ #![unstable(feature = "f16", issue = "116909")] use crate::convert::FloatToInt; -#[cfg(not(test))] -use crate::intrinsics; -use crate::mem; use crate::num::FpCategory; use crate::panic::const_assert; +use crate::{intrinsics, mem}; /// Basic mathematical constants. #[unstable(feature = "f16", issue = "116909")] @@ -133,7 +131,6 @@ pub mod consts { pub const LN_10: f16 = 2.30258509299404568401799145468436421_f16; } -#[cfg(not(test))] impl f16 { // FIXME(f16_f128): almost all methods in this `impl` are missing examples and a const // implementation. Add these once we can run code on all platforms and have f16/f128 in CTFE. diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index de1557ccc9028..79d864e1b1966 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -12,11 +12,9 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::convert::FloatToInt; -#[cfg(not(test))] -use crate::intrinsics; -use crate::mem; use crate::num::FpCategory; use crate::panic::const_assert; +use crate::{intrinsics, mem}; /// The radix or base of the internal representation of `f32`. /// Use [`f32::RADIX`] instead. @@ -386,7 +384,6 @@ pub mod consts { pub const LN_10: f32 = 2.30258509299404568401799145468436421_f32; } -#[cfg(not(test))] impl f32 { /// The radix or base of the internal representation of `f32`. #[stable(feature = "assoc_int_consts", since = "1.43.0")] @@ -416,7 +413,7 @@ impl f32 { /// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon /// [`MANTISSA_DIGITS`]: f32::MANTISSA_DIGITS #[stable(feature = "assoc_int_consts", since = "1.43.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "f32_epsilon")] + #[rustc_diagnostic_item = "f32_epsilon"] pub const EPSILON: f32 = 1.19209290e-07_f32; /// Smallest finite `f32` value. diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 65b5f3b9af093..ca28b40bb3adc 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -12,11 +12,9 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::convert::FloatToInt; -#[cfg(not(test))] -use crate::intrinsics; -use crate::mem; use crate::num::FpCategory; use crate::panic::const_assert; +use crate::{intrinsics, mem}; /// The radix or base of the internal representation of `f64`. /// Use [`f64::RADIX`] instead. @@ -386,7 +384,6 @@ pub mod consts { pub const LN_10: f64 = 2.30258509299404568401799145468436421_f64; } -#[cfg(not(test))] impl f64 { /// The radix or base of the internal representation of `f64`. #[stable(feature = "assoc_int_consts", since = "1.43.0")] @@ -415,7 +412,7 @@ impl f64 { /// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon /// [`MANTISSA_DIGITS`]: f64::MANTISSA_DIGITS #[stable(feature = "assoc_int_consts", since = "1.43.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "f64_epsilon")] + #[rustc_diagnostic_item = "f64_epsilon"] pub const EPSILON: f64 = 2.2204460492503131e-16_f64; /// Smallest finite `f64` value. diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index 8993e14fcd379..0d910685927e0 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -79,7 +79,7 @@ use crate::{convert, ops}; /// [`Break`]: ControlFlow::Break /// [`Continue`]: ControlFlow::Continue #[stable(feature = "control_flow_enum_type", since = "1.55.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "ControlFlow")] +#[rustc_diagnostic_item = "ControlFlow"] // ControlFlow should not implement PartialOrd or Ord, per RFC 3058: // https://rust-lang.github.io/rfcs/3058-try-trait-v2.html#traits-for-controlflow #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] diff --git a/library/core/src/option.rs b/library/core/src/option.rs index a9f06b92ad5dd..75819fa6ce975 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -924,7 +924,7 @@ impl Option { #[inline] #[track_caller] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "option_expect")] + #[rustc_diagnostic_item = "option_expect"] #[rustc_allow_const_fn_unstable(const_precise_live_drops)] #[rustc_const_stable(feature = "const_option", since = "1.83.0")] pub const fn expect(self, msg: &str) -> T { @@ -969,7 +969,7 @@ impl Option { #[inline(always)] #[track_caller] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "option_unwrap")] + #[rustc_diagnostic_item = "option_unwrap"] #[rustc_allow_const_fn_unstable(const_precise_live_drops)] #[rustc_const_stable(feature = "const_option", since = "1.83.0")] pub const fn unwrap(self) -> T { diff --git a/library/core/src/panic/unwind_safe.rs b/library/core/src/panic/unwind_safe.rs index 37859212c0ee3..a60f0799c0eae 100644 --- a/library/core/src/panic/unwind_safe.rs +++ b/library/core/src/panic/unwind_safe.rs @@ -82,7 +82,7 @@ use crate::task::{Context, Poll}; /// [`AssertUnwindSafe`] wrapper struct can be used to force this trait to be /// implemented for any closed over variables passed to `catch_unwind`. #[stable(feature = "catch_unwind", since = "1.9.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "unwind_safe_trait")] +#[rustc_diagnostic_item = "unwind_safe_trait"] #[diagnostic::on_unimplemented( message = "the type `{Self}` may not be safely transferred across an unwind boundary", label = "`{Self}` may not be safely transferred across an unwind boundary" @@ -98,7 +98,7 @@ pub auto trait UnwindSafe {} /// This is a "helper marker trait" used to provide impl blocks for the /// [`UnwindSafe`] trait, for more information see that documentation. #[stable(feature = "catch_unwind", since = "1.9.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "ref_unwind_safe_trait")] +#[rustc_diagnostic_item = "ref_unwind_safe_trait"] #[diagnostic::on_unimplemented( message = "the type `{Self}` may contain interior mutability and a reference may not be safely \ transferrable across a catch_unwind boundary", diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 92b5cba153166..2506e7be765b8 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -654,7 +654,7 @@ impl Result { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "result_ok_method")] + #[rustc_diagnostic_item = "result_ok_method"] pub fn ok(self) -> Option { match self { Ok(x) => Some(x), diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 51b25fa40e3d9..91befdb8c78d9 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -7,7 +7,6 @@ use crate::fmt::{self, Write}; use crate::intrinsics::const_eval_select; use crate::{ascii, iter, ops}; -#[cfg(not(test))] impl [u8] { /// Checks if all bytes in this slice are within the ASCII range. #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index f991cc4ae2dbb..f66801d7424d8 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -97,7 +97,6 @@ enum Direction { Back, } -#[cfg(not(test))] impl [T] { /// Returns the number of elements in the slice. /// @@ -1045,7 +1044,7 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - #[cfg_attr(not(test), rustc_diagnostic_item = "slice_iter")] + #[rustc_diagnostic_item = "slice_iter"] pub fn iter(&self) -> Iter<'_, T> { Iter::new(self) } @@ -4845,7 +4844,6 @@ impl [[T; N]] { } } -#[cfg(not(test))] impl [f32] { /// Sorts the slice of floats. /// @@ -4874,7 +4872,6 @@ impl [f32] { } } -#[cfg(not(test))] impl [f64] { /// Sorts the slice of floats. /// diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 83ad10db2da45..5cc08f8a71afb 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -114,7 +114,6 @@ fn slice_error_fail_rt(s: &str, begin: usize, end: usize) -> ! { ); } -#[cfg(not(test))] impl str { /// Returns the length of `self`. /// @@ -134,7 +133,7 @@ impl str { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_str_len", since = "1.39.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "str_len")] + #[rustc_diagnostic_item = "str_len"] #[must_use] #[inline] pub const fn len(&self) -> usize { @@ -1029,7 +1028,7 @@ impl str { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - #[cfg_attr(not(test), rustc_diagnostic_item = "str_chars")] + #[rustc_diagnostic_item = "str_chars"] pub fn chars(&self) -> Chars<'_> { Chars { iter: self.as_bytes().iter() } } @@ -1160,7 +1159,7 @@ impl str { #[must_use = "this returns the split string as an iterator, \ without modifying the original"] #[stable(feature = "split_whitespace", since = "1.1.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "str_split_whitespace")] + #[rustc_diagnostic_item = "str_split_whitespace"] #[inline] pub fn split_whitespace(&self) -> SplitWhitespace<'_> { SplitWhitespace { inner: self.split(IsWhitespace).filter(IsNotEmpty) } @@ -1355,7 +1354,7 @@ impl str { /// assert!(bananas.starts_with(&['a', 'b', 'c', 'd'])); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "str_starts_with")] + #[rustc_diagnostic_item = "str_starts_with"] pub fn starts_with(&self, pat: P) -> bool { pat.is_prefix_of(self) } @@ -1380,7 +1379,7 @@ impl str { /// assert!(!bananas.ends_with("nana")); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "str_ends_with")] + #[rustc_diagnostic_item = "str_ends_with"] pub fn ends_with(&self, pat: P) -> bool where for<'a> P::Searcher<'a>: ReverseSearcher<'a>, @@ -2114,7 +2113,7 @@ impl str { #[must_use = "this returns the trimmed string as a slice, \ without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "str_trim")] + #[rustc_diagnostic_item = "str_trim"] pub fn trim(&self) -> &str { self.trim_matches(|c: char| c.is_whitespace()) } @@ -2153,7 +2152,7 @@ impl str { #[must_use = "this returns the trimmed string as a new slice, \ without modifying the original"] #[stable(feature = "trim_direction", since = "1.30.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "str_trim_start")] + #[rustc_diagnostic_item = "str_trim_start"] pub fn trim_start(&self) -> &str { self.trim_start_matches(|c: char| c.is_whitespace()) } @@ -2192,7 +2191,7 @@ impl str { #[must_use = "this returns the trimmed string as a new slice, \ without modifying the original"] #[stable(feature = "trim_direction", since = "1.30.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "str_trim_end")] + #[rustc_diagnostic_item = "str_trim_end"] pub fn trim_end(&self) -> &str { self.trim_end_matches(|c: char| c.is_whitespace()) } diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 73180bde54aa9..bf2b6d59f8824 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -294,7 +294,7 @@ unsafe impl Sync for AtomicBool {} /// loads and stores of pointers. Its size depends on the target pointer's size. #[cfg(target_has_atomic_load_store = "ptr")] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "AtomicPtr")] +#[rustc_diagnostic_item = "AtomicPtr"] #[cfg_attr(target_pointer_width = "16", repr(C, align(2)))] #[cfg_attr(target_pointer_width = "32", repr(C, align(4)))] #[cfg_attr(target_pointer_width = "64", repr(C, align(8)))] @@ -3445,7 +3445,7 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicI8"), + rustc_diagnostic_item = "AtomicI8", "i8", "", atomic_min, atomic_max, @@ -3464,7 +3464,7 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicU8"), + rustc_diagnostic_item = "AtomicU8", "u8", "", atomic_umin, atomic_umax, @@ -3483,7 +3483,7 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicI16"), + rustc_diagnostic_item = "AtomicI16", "i16", "", atomic_min, atomic_max, @@ -3502,7 +3502,7 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicU16"), + rustc_diagnostic_item = "AtomicU16", "u16", "", atomic_umin, atomic_umax, @@ -3521,7 +3521,7 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicI32"), + rustc_diagnostic_item = "AtomicI32", "i32", "", atomic_min, atomic_max, @@ -3540,7 +3540,7 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicU32"), + rustc_diagnostic_item = "AtomicU32", "u32", "", atomic_umin, atomic_umax, @@ -3559,7 +3559,7 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicI64"), + rustc_diagnostic_item = "AtomicI64", "i64", "", atomic_min, atomic_max, @@ -3578,7 +3578,7 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicU64"), + rustc_diagnostic_item = "AtomicU64", "u64", "", atomic_umin, atomic_umax, @@ -3597,7 +3597,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "99069"), rustc_const_unstable(feature = "integer_atomics", issue = "99069"), rustc_const_unstable(feature = "integer_atomics", issue = "99069"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicI128"), + rustc_diagnostic_item = "AtomicI128", "i128", "#![feature(integer_atomics)]\n\n", atomic_min, atomic_max, @@ -3616,7 +3616,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "99069"), rustc_const_unstable(feature = "integer_atomics", issue = "99069"), rustc_const_unstable(feature = "integer_atomics", issue = "99069"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicU128"), + rustc_diagnostic_item = "AtomicU128", "u128", "#![feature(integer_atomics)]\n\n", atomic_umin, atomic_umax, @@ -3639,7 +3639,7 @@ macro_rules! atomic_int_ptr_sized { stable(feature = "atomic_nand", since = "1.27.0"), rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicIsize"), + rustc_diagnostic_item = "AtomicIsize", "isize", "", atomic_min, atomic_max, @@ -3658,7 +3658,7 @@ macro_rules! atomic_int_ptr_sized { stable(feature = "atomic_nand", since = "1.27.0"), rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicUsize"), + rustc_diagnostic_item = "AtomicUsize", "usize", "", atomic_umin, atomic_umax, diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 3f57b04753a6b..9b8fefe42af60 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -402,7 +402,7 @@ impl<'a> ContextBuilder<'a> { /// [`Wake`]: ../../alloc/task/trait.Wake.html #[repr(transparent)] #[stable(feature = "futures_api", since = "1.36.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "Waker")] +#[rustc_diagnostic_item = "Waker"] pub struct Waker { waker: RawWaker, } diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 8b211b442eab6..0064876f40112 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -77,7 +77,7 @@ const DAYS_PER_WEEK: u64 = 7; /// crate to do so. #[stable(feature = "duration", since = "1.3.0")] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] -#[cfg_attr(not(test), rustc_diagnostic_item = "Duration")] +#[rustc_diagnostic_item = "Duration"] pub struct Duration { secs: u64, nanos: Nanoseconds, // Always 0 <= nanos < NANOS_PER_SEC From 769425a4eaca0dff46b22df5ab38580f5d64428f Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Thu, 14 Nov 2024 10:43:04 -0800 Subject: [PATCH 04/31] Expand `CloneToUninit` documentation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Clarify relationship to `dyn` after #133003. * Add an example of using it with `dyn` as #133003 enabled. * Add an example of implementing it. * Add links to Rust Reference for the mentioned concepts. * Mention that its method should rarely be called. * Replace parameter name `dst` with `dest` to avoids confusion between “DeSTination” and “Dynamically-Sized Type”. * Various small corrections. --- library/core/src/clone.rs | 159 +++++++++++++++++++++++++++++++------- 1 file changed, 131 insertions(+), 28 deletions(-) diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index c777dd995a656..05462cea2f5b2 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -262,34 +262,137 @@ pub struct AssertParamIsCopy { _field: crate::marker::PhantomData, } -/// A generalization of [`Clone`] to dynamically-sized types stored in arbitrary containers. +/// A generalization of [`Clone`] to [dynamically-sized types][DST] stored in arbitrary containers. /// -/// This trait is implemented for all types implementing [`Clone`], and also [slices](slice) of all -/// such types. You may also implement this trait to enable cloning trait objects and custom DSTs -/// (structures containing dynamically-sized fields). +/// This trait is implemented for all types implementing [`Clone`], [slices](slice) of all +/// such types, and other dynamically-sized types in the standard library. +/// You may also implement this trait to enable cloning custom DSTs +/// (structures containing dynamically-sized fields), or use it as a supertrait to enable +/// cloning a [trait object]. +/// +/// This trait is normally used via operations on container types which support DSTs, +/// so you should not typically need to call `.clone_to_uninit()` explicitly except when +/// implementing such a container or otherwise performing explicit management of an allocation, +/// or when implementing `CloneToUninit` itself. /// /// # Safety /// -/// Implementations must ensure that when `.clone_to_uninit(dst)` returns normally rather than -/// panicking, it always leaves `*dst` initialized as a valid value of type `Self`. +/// Implementations must ensure that when `.clone_to_uninit(dest)` returns normally rather than +/// panicking, it always leaves `*dest` initialized as a valid value of type `Self`. +/// +/// # Examples +/// +// FIXME(#126799): when `Box::clone` allows use of `CloneToUninit`, rewrite these examples with it +// since `Rc` is a distraction. +/// +/// If you are defining a trait, you can add `CloneToUninit` as a supertrait to enable cloning of +/// `dyn` values of your trait: +/// +/// ``` +/// #![feature(clone_to_uninit)] +/// use std::rc::Rc; +/// +/// trait Foo: std::fmt::Debug + std::clone::CloneToUninit { +/// fn modify(&mut self); +/// fn value(&self) -> i32; +/// } +/// +/// impl Foo for i32 { +/// fn modify(&mut self) { +/// *self *= 10; +/// } +/// fn value(&self) -> i32 { +/// *self +/// } +/// } +/// +/// let first: Rc = Rc::new(1234); +/// +/// let mut second = first.clone(); +/// Rc::make_mut(&mut second).modify(); // make_mut() will call clone_to_uninit() +/// +/// assert_eq!(first.value(), 1234); +/// assert_eq!(second.value(), 12340); +/// ``` +/// +/// The following is an example of implementing `CloneToUninit` for a custom DST. +/// (It is essentially a limited form of what `derive(CloneToUninit)` would do, +/// if such a derive macro existed.) /// -/// # See also +/// ``` +/// #![feature(clone_to_uninit)] +/// use std::clone::CloneToUninit; +/// use std::mem::offset_of; +/// use std::rc::Rc; +/// +/// #[derive(PartialEq)] +/// struct MyDst { +/// flag: bool, +/// contents: T, +/// } /// -/// * [`Clone::clone_from`] is a safe function which may be used instead when `Self` is a [`Sized`] +/// unsafe impl CloneToUninit for MyDst { +/// unsafe fn clone_to_uninit(&self, dest: *mut u8) { +/// // The offset of `self.contents` is dynamic because it depends on the alignment of T +/// // which can be dynamic (if `T = dyn SomeTrait`). Therefore, we have to obtain it +/// // dynamically by examining `self`, rather than using `offset_of!`. +/// let offset_of_contents = +/// (&raw const self.contents).byte_offset_from_unsigned(&raw const *self); +/// +/// // Since `flag` implements `Copy`, we can just copy it. +/// // We use `pointer::write()` instead of assignment because the destination must be +/// // assumed to be uninitialized, whereas an assignment assumes it is initialized. +/// dest.add(offset_of!(Self, flag)).cast::().write(self.flag); +/// +/// // Note: if `flag` owned any resources (i.e. had a `Drop` implementation), then we +/// // must prepare to drop it in case `self.contents.clone_to_uninit()` panics. +/// // In this simple case, where we have exactly one field for which `mem::needs_drop()` +/// // might be true (`contents`), we don’t need to care about cleanup or ordering. +/// self.contents.clone_to_uninit(dest.add(offset_of_contents)); +/// +/// // All fields of the struct have been initialized, therefore the struct is initialized, +/// // and we have satisfied our `unsafe impl CloneToUninit` obligations. +/// } +/// } +/// +/// fn main() { +/// // Construct MyDst<[u8; 4]>, then coerce to MyDst<[u8]>. +/// let first: Rc> = Rc::new(MyDst { +/// flag: true, +/// contents: [1, 2, 3, 4], +/// }); +/// +/// let mut second = first.clone(); +/// // make_mut() will call clone_to_uninit(). +/// for elem in Rc::make_mut(&mut second).contents.iter_mut() { +/// *elem *= 10; +/// } +/// +/// assert_eq!(first.contents, [1, 2, 3, 4]); +/// assert_eq!(second.contents, [10, 20, 30, 40]); +/// } +/// ``` +/// +/// # See Also +/// +/// * [`Clone::clone_from`] is a safe function which may be used instead when [`Self: Sized`](Sized) /// and the destination is already initialized; it may be able to reuse allocations owned by -/// the destination. +/// the destination, whereas `clone_to_uninit` cannot, since its destination is assumed to be +/// uninitialized. /// * [`ToOwned`], which allocates a new destination container. /// /// [`ToOwned`]: ../../std/borrow/trait.ToOwned.html +/// [DST]: https://doc.rust-lang.org/reference/dynamically-sized-types.html +/// [trait object]: https://doc.rust-lang.org/reference/types/trait-object.html #[unstable(feature = "clone_to_uninit", issue = "126799")] pub unsafe trait CloneToUninit { - /// Performs copy-assignment from `self` to `dst`. + /// Performs copy-assignment from `self` to `dest`. /// - /// This is analogous to `std::ptr::write(dst.cast(), self.clone())`, - /// except that `self` may be a dynamically-sized type ([`!Sized`](Sized)). + /// This is analogous to `std::ptr::write(dest.cast(), self.clone())`, + /// except that `Self` may be a dynamically-sized type ([`!Sized`](Sized)). /// - /// Before this function is called, `dst` may point to uninitialized memory. - /// After this function is called, `dst` will point to initialized memory; it will be + /// Before this function is called, `dest` may point to uninitialized memory. + /// After this function is called, `dest` will point to initialized memory; it will be /// sound to create a `&Self` reference from the pointer with the [pointer metadata] /// from `self`. /// @@ -297,8 +400,8 @@ pub unsafe trait CloneToUninit { /// /// Behavior is undefined if any of the following conditions are violated: /// - /// * `dst` must be [valid] for writes for `size_of_val(self)` bytes. - /// * `dst` must be properly aligned to `align_of_val(self)`. + /// * `dest` must be [valid] for writes for `size_of_val(self)` bytes. + /// * `dest` must be properly aligned to `align_of_val(self)`. /// /// [valid]: crate::ptr#safety /// [pointer metadata]: crate::ptr::metadata() @@ -307,11 +410,11 @@ pub unsafe trait CloneToUninit { /// /// This function may panic. (For example, it might panic if memory allocation for a clone /// of a value owned by `self` fails.) - /// If the call panics, then `*dst` should be treated as uninitialized memory; it must not be + /// If the call panics, then `*dest` should be treated as uninitialized memory; it must not be /// read or dropped, because even if it was previously valid, it may have been partially /// overwritten. /// - /// The caller may also need to take care to deallocate the allocation pointed to by `dst`, + /// The caller may also need to take care to deallocate the allocation pointed to by `dest`, /// if applicable, to avoid a memory leak, and may need to take other precautions to ensure /// soundness in the presence of unwinding. /// @@ -319,15 +422,15 @@ pub unsafe trait CloneToUninit { /// that might have already been created. (For example, if a `[Foo]` of length 3 is being /// cloned, and the second of the three calls to `Foo::clone()` unwinds, then the first `Foo` /// cloned should be dropped.) - unsafe fn clone_to_uninit(&self, dst: *mut u8); + unsafe fn clone_to_uninit(&self, dest: *mut u8); } #[unstable(feature = "clone_to_uninit", issue = "126799")] unsafe impl CloneToUninit for T { #[inline] - unsafe fn clone_to_uninit(&self, dst: *mut u8) { + unsafe fn clone_to_uninit(&self, dest: *mut u8) { // SAFETY: we're calling a specialization with the same contract - unsafe { ::clone_one(self, dst.cast::()) } + unsafe { ::clone_one(self, dest.cast::()) } } } @@ -335,10 +438,10 @@ unsafe impl CloneToUninit for T { unsafe impl CloneToUninit for [T] { #[inline] #[cfg_attr(debug_assertions, track_caller)] - unsafe fn clone_to_uninit(&self, dst: *mut u8) { - let dst: *mut [T] = dst.with_metadata_of(self); + unsafe fn clone_to_uninit(&self, dest: *mut u8) { + let dest: *mut [T] = dest.with_metadata_of(self); // SAFETY: we're calling a specialization with the same contract - unsafe { ::clone_slice(self, dst) } + unsafe { ::clone_slice(self, dest) } } } @@ -346,21 +449,21 @@ unsafe impl CloneToUninit for [T] { unsafe impl CloneToUninit for str { #[inline] #[cfg_attr(debug_assertions, track_caller)] - unsafe fn clone_to_uninit(&self, dst: *mut u8) { + unsafe fn clone_to_uninit(&self, dest: *mut u8) { // SAFETY: str is just a [u8] with UTF-8 invariant - unsafe { self.as_bytes().clone_to_uninit(dst) } + unsafe { self.as_bytes().clone_to_uninit(dest) } } } #[unstable(feature = "clone_to_uninit", issue = "126799")] unsafe impl CloneToUninit for crate::ffi::CStr { #[cfg_attr(debug_assertions, track_caller)] - unsafe fn clone_to_uninit(&self, dst: *mut u8) { + unsafe fn clone_to_uninit(&self, dest: *mut u8) { // SAFETY: For now, CStr is just a #[repr(trasnsparent)] [c_char] with some invariants. // And we can cast [c_char] to [u8] on all supported platforms (see: to_bytes_with_nul). // The pointer metadata properly preserves the length (so NUL is also copied). // See: `cstr_metadata_is_length_with_nul` in tests. - unsafe { self.to_bytes_with_nul().clone_to_uninit(dst) } + unsafe { self.to_bytes_with_nul().clone_to_uninit(dest) } } } From a312635821c84611be8e6ab84c1ef4815ba7d99e Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sun, 9 Mar 2025 14:01:01 +0100 Subject: [PATCH 05/31] expose `is_s390x_feature_detected` from `std::arch` --- library/std/src/lib.rs | 2 ++ library/std/tests/run-time-detect.rs | 30 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 938b8c6e4f41b..35ada678740fe 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -666,6 +666,8 @@ pub mod arch { pub use std_detect::is_loongarch_feature_detected; #[unstable(feature = "is_riscv_feature_detected", issue = "111192")] pub use std_detect::is_riscv_feature_detected; + #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] + pub use std_detect::is_s390x_feature_detected; #[stable(feature = "simd_x86", since = "1.27.0")] pub use std_detect::is_x86_feature_detected; #[unstable(feature = "stdarch_mips_feature_detection", issue = "111188")] diff --git a/library/std/tests/run-time-detect.rs b/library/std/tests/run-time-detect.rs index dd14c0266aa4d..e59ae2f3d7f18 100644 --- a/library/std/tests/run-time-detect.rs +++ b/library/std/tests/run-time-detect.rs @@ -8,6 +8,10 @@ all(target_arch = "aarch64", any(target_os = "linux", target_os = "android")), feature(stdarch_aarch64_feature_detection) )] +#![cfg_attr( + all(target_arch = "s390x", target_os = "linux"), + feature(stdarch_s390x_feature_detection) +)] #![cfg_attr( all(target_arch = "powerpc", target_os = "linux"), feature(stdarch_powerpc_feature_detection) @@ -132,6 +136,32 @@ fn powerpc64_linux() { // tidy-alphabetical-end } +#[test] +#[cfg(all(target_arch = "s390x", target_os = "linux"))] +fn s390x_linux() { + use std::arch::is_s390x_feature_detected; + // tidy-alphabetical-start + println!("deflate-conversion: {}", is_s390x_feature_detected!("deflate-conversion")); + println!("enhanced-sort: {}", is_s390x_feature_detected!("enhanced-sort")); + println!("guarded-storage: {}", is_s390x_feature_detected!("guarded-storage")); + println!("high-word: {}", is_s390x_feature_detected!("high-word")); + println!("nnp-assist: {}", is_s390x_feature_detected!("nnp-assist")); + println!("transactional-execution: {}", is_s390x_feature_detected!("transactional-execution")); + println!("vector-enhancements-1: {}", is_s390x_feature_detected!("vector-enhancements-1")); + println!("vector-enhancements-2: {}", is_s390x_feature_detected!("vector-enhancements-2")); + println!( + "vector-packed-decimal-enhancement-2: {}", + is_s390x_feature_detected!("vector-packed-decimal-enhancement-2") + ); + println!( + "vector-packed-decimal-enhancement: {}", + is_s390x_feature_detected!("vector-packed-decimal-enhancement") + ); + println!("vector-packed-decimal: {}", is_s390x_feature_detected!("vector-packed-decimal")); + println!("vector: {}", is_s390x_feature_detected!("vector")); + // tidy-alphabetical-end +} + #[test] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] fn x86_all() { From 55c658b242ca6bbd49eb33c01410b7fed7db4d6e Mon Sep 17 00:00:00 2001 From: LemonJ <1632798336@qq.com> Date: Mon, 10 Mar 2025 16:39:38 +0800 Subject: [PATCH 06/31] fix ptr inconsistency in Rc Arc --- library/alloc/src/rc.rs | 36 ++++++++++++++++++++++++------------ library/alloc/src/sync.rs | 34 +++++++++++++++++++++++----------- 2 files changed, 47 insertions(+), 23 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index fc1cee28d0334..6b4b5f790004d 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1327,10 +1327,13 @@ impl Rc { /// /// # Safety /// - /// The pointer must have been obtained through `Rc::into_raw`, the - /// associated `Rc` instance must be valid (i.e. the strong count must be at + /// The pointer must have been obtained through `Rc::into_raw` and must satisfy the + /// same layout requirements specified in [`Rc::from_raw_in`][from_raw_in]. + /// The associated `Rc` instance must be valid (i.e. the strong count must be at /// least 1) for the duration of this method, and `ptr` must point to a block of memory - /// allocated by the global allocator. + /// allocated by `alloc`. + /// + /// [from_raw_in]: Rc::from_raw_in /// /// # Examples /// @@ -1360,12 +1363,15 @@ impl Rc { /// /// # Safety /// - /// The pointer must have been obtained through `Rc::into_raw`, the - /// associated `Rc` instance must be valid (i.e. the strong count must be at + /// The pointer must have been obtained through `Rc::into_raw`and must satisfy the + /// same layout requirements specified in [`Rc::from_raw_in`][from_raw_in]. + /// The associated `Rc` instance must be valid (i.e. the strong count must be at /// least 1) when invoking this method, and `ptr` must point to a block of memory /// allocated by the global allocator. This method can be used to release the final `Rc` and /// backing storage, but **should not** be called after the final `Rc` has been released. /// + /// [from_raw_in]: Rc::from_raw_in + /// /// # Examples /// /// ``` @@ -1623,10 +1629,13 @@ impl Rc { /// /// # Safety /// - /// The pointer must have been obtained through `Rc::into_raw`, the - /// associated `Rc` instance must be valid (i.e. the strong count must be at + /// The pointer must have been obtained through `Rc::into_raw` and must satisfy the + /// same layout requirements specified in [`Rc::from_raw_in`][from_raw_in]. + /// The associated `Rc` instance must be valid (i.e. the strong count must be at /// least 1) for the duration of this method, and `ptr` must point to a block of memory - /// allocated by `alloc` + /// allocated by `alloc`. + /// + /// [from_raw_in]: Rc::from_raw_in /// /// # Examples /// @@ -1665,11 +1674,14 @@ impl Rc { /// /// # Safety /// - /// The pointer must have been obtained through `Rc::into_raw`, the - /// associated `Rc` instance must be valid (i.e. the strong count must be at + /// The pointer must have been obtained through `Rc::into_raw`and must satisfy the + /// same layout requirements specified in [`Rc::from_raw_in`][from_raw_in]. + /// The associated `Rc` instance must be valid (i.e. the strong count must be at /// least 1) when invoking this method, and `ptr` must point to a block of memory - /// allocated by `alloc`. This method can be used to release the final `Rc` and backing storage, - /// but **should not** be called after the final `Rc` has been released. + /// allocated by the global allocator. This method can be used to release the final `Rc` and + /// backing storage, but **should not** be called after the final `Rc` has been released. + /// + /// [from_raw_in]: Rc::from_raw_in /// /// # Examples /// diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 4999319f618e4..6bb037c57debe 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1453,11 +1453,14 @@ impl Arc { /// /// # Safety /// - /// The pointer must have been obtained through `Arc::into_raw`, and the - /// associated `Arc` instance must be valid (i.e. the strong count must be at + /// The pointer must have been obtained through `Arc::into_raw` and must satisfy the + /// same layout requirements specified in [`Arc::from_raw_in`][from_raw_in]. + /// The associated `Arc` instance must be valid (i.e. the strong count must be at /// least 1) for the duration of this method, and `ptr` must point to a block of memory /// allocated by the global allocator. /// + /// [from_raw_in]: Arc::from_raw_in + /// /// # Examples /// /// ``` @@ -1488,13 +1491,16 @@ impl Arc { /// /// # Safety /// - /// The pointer must have been obtained through `Arc::into_raw`, and the - /// associated `Arc` instance must be valid (i.e. the strong count must be at + /// The pointer must have been obtained through `Arc::into_raw` and must satisfy the + /// same layout requirements specified in [`Arc::from_raw_in`][from_raw_in]. + /// The associated `Arc` instance must be valid (i.e. the strong count must be at /// least 1) when invoking this method, and `ptr` must point to a block of memory /// allocated by the global allocator. This method can be used to release the final /// `Arc` and backing storage, but **should not** be called after the final `Arc` has been /// released. /// + /// [from_raw_in]: Arc::from_raw_in + /// /// # Examples /// /// ``` @@ -1806,10 +1812,13 @@ impl Arc { /// /// # Safety /// - /// The pointer must have been obtained through `Arc::into_raw`, and the - /// associated `Arc` instance must be valid (i.e. the strong count must be at - /// least 1) for the duration of this method,, and `ptr` must point to a block of memory - /// allocated by `alloc`. + /// The pointer must have been obtained through `Arc::into_raw` and must satisfy the + /// same layout requirements specified in [`Arc::from_raw_in`][from_raw_in]. + /// The associated `Arc` instance must be valid (i.e. the strong count must be at + /// least 1) for the duration of this method, and `ptr` must point to a block of memory + /// allocated by the global allocator. + /// + /// [from_raw_in]: Arc::from_raw_in /// /// # Examples /// @@ -1850,13 +1859,16 @@ impl Arc { /// /// # Safety /// - /// The pointer must have been obtained through `Arc::into_raw`, the - /// associated `Arc` instance must be valid (i.e. the strong count must be at + /// The pointer must have been obtained through `Arc::into_raw` and must satisfy the + /// same layout requirements specified in [`Arc::from_raw_in`][from_raw_in]. + /// The associated `Arc` instance must be valid (i.e. the strong count must be at /// least 1) when invoking this method, and `ptr` must point to a block of memory - /// allocated by `alloc`. This method can be used to release the final + /// allocated by the global allocator. This method can be used to release the final /// `Arc` and backing storage, but **should not** be called after the final `Arc` has been /// released. /// + /// [from_raw_in]: Arc::from_raw_in + /// /// # Examples /// /// ``` From fa183ad8275db2523eac80ce2b2a2acb961064ee Mon Sep 17 00:00:00 2001 From: LemonJ <1632798336@qq.com> Date: Mon, 10 Mar 2025 16:46:18 +0800 Subject: [PATCH 07/31] fix copy typo --- library/alloc/src/rc.rs | 4 ++-- library/alloc/src/sync.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 6b4b5f790004d..619d9f258e342 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1331,7 +1331,7 @@ impl Rc { /// same layout requirements specified in [`Rc::from_raw_in`][from_raw_in]. /// The associated `Rc` instance must be valid (i.e. the strong count must be at /// least 1) for the duration of this method, and `ptr` must point to a block of memory - /// allocated by `alloc`. + /// allocated by the global allocator. /// /// [from_raw_in]: Rc::from_raw_in /// @@ -1678,7 +1678,7 @@ impl Rc { /// same layout requirements specified in [`Rc::from_raw_in`][from_raw_in]. /// The associated `Rc` instance must be valid (i.e. the strong count must be at /// least 1) when invoking this method, and `ptr` must point to a block of memory - /// allocated by the global allocator. This method can be used to release the final `Rc` and + /// allocated by `alloc`. This method can be used to release the final `Rc` and /// backing storage, but **should not** be called after the final `Rc` has been released. /// /// [from_raw_in]: Rc::from_raw_in diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 6bb037c57debe..104cb35c23b65 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1816,7 +1816,7 @@ impl Arc { /// same layout requirements specified in [`Arc::from_raw_in`][from_raw_in]. /// The associated `Arc` instance must be valid (i.e. the strong count must be at /// least 1) for the duration of this method, and `ptr` must point to a block of memory - /// allocated by the global allocator. + /// allocated by `alloc`. /// /// [from_raw_in]: Arc::from_raw_in /// @@ -1863,7 +1863,7 @@ impl Arc { /// same layout requirements specified in [`Arc::from_raw_in`][from_raw_in]. /// The associated `Arc` instance must be valid (i.e. the strong count must be at /// least 1) when invoking this method, and `ptr` must point to a block of memory - /// allocated by the global allocator. This method can be used to release the final + /// allocated by `alloc`. This method can be used to release the final /// `Arc` and backing storage, but **should not** be called after the final `Arc` has been /// released. /// From 48a54d026d632ac88ce08dee1462c31ed1071ca5 Mon Sep 17 00:00:00 2001 From: LemonJ <1632798336@qq.com> Date: Mon, 10 Mar 2025 22:08:30 +0800 Subject: [PATCH 08/31] add missing doc for intrinsic --- library/core/src/intrinsics/mod.rs | 31 +++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 6af647b137dac..4fa6df9f5525a 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -1630,10 +1630,14 @@ pub fn ptr_mask(_ptr: *const T, _mask: usize) -> *const T; /// a size of `count` * `size_of::()` and an alignment of /// `min_align_of::()` /// -/// The volatile parameter is set to `true`, so it will not be optimized out -/// unless size is equal to zero. -/// /// This intrinsic does not have a stable counterpart. +/// # Safety +/// +/// The safety requirements are consistent with [`copy_nonoverlapping`] +/// while the read and write behaviors are volatile, +/// which means it will not be optimized out unless size is equal to zero. +/// +/// [`copy_nonoverlapping`]: ptr::copy_nonoverlapping #[rustc_intrinsic] #[rustc_nounwind] pub unsafe fn volatile_copy_nonoverlapping_memory(_dst: *mut T, _src: *const T, _count: usize); @@ -1652,10 +1656,13 @@ pub unsafe fn volatile_copy_memory(_dst: *mut T, _src: *const T, _count: usiz /// size of `count * size_of::()` and an alignment of /// `min_align_of::()`. /// -/// The volatile parameter is set to `true`, so it will not be optimized out -/// unless size is equal to zero. -/// /// This intrinsic does not have a stable counterpart. +/// # Safety +/// +/// The safety requirements are consistent with [`write_bytes`] while the write behavior is volatile, +/// which means it will not be optimized out unless size is equal to zero. +/// +/// [`write_bytes`]: ptr::write_bytes #[rustc_intrinsic] #[rustc_nounwind] pub unsafe fn volatile_set_memory(_dst: *mut T, _val: u8, _count: usize); @@ -3197,8 +3204,18 @@ pub const fn is_val_statically_known(_arg: T) -> bool { /// The stabilized form of this intrinsic is [`crate::mem::swap`]. /// /// # Safety +/// Behavior is undefined if any of the following conditions are violated: +/// +/// * Both `x` and `y` must be [valid] for both reads and writes. /// -/// `x` and `y` are readable and writable as `T`, and non-overlapping. +/// * Both `x` and `y` must be properly aligned. +/// +/// * The region of memory beginning at `x` must *not* overlap with the region of memory +/// beginning at `y`. +/// +/// * The memory pointed by `x` and `y` must contain correct value of type `T`. +/// +/// [valid]: crate::ptr#safety #[rustc_nounwind] #[inline] #[rustc_intrinsic] From 2cc999d0d4721655036b8cd89534eb3872d085cc Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Mon, 10 Mar 2025 13:54:07 -0700 Subject: [PATCH 09/31] Rewrite comments about dropping and leaking. --- library/core/src/clone.rs | 42 ++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index 05462cea2f5b2..f6f4e2079156e 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -336,19 +336,29 @@ pub struct AssertParamIsCopy { /// // The offset of `self.contents` is dynamic because it depends on the alignment of T /// // which can be dynamic (if `T = dyn SomeTrait`). Therefore, we have to obtain it /// // dynamically by examining `self`, rather than using `offset_of!`. -/// let offset_of_contents = -/// (&raw const self.contents).byte_offset_from_unsigned(&raw const *self); -/// -/// // Since `flag` implements `Copy`, we can just copy it. -/// // We use `pointer::write()` instead of assignment because the destination must be -/// // assumed to be uninitialized, whereas an assignment assumes it is initialized. -/// dest.add(offset_of!(Self, flag)).cast::().write(self.flag); -/// -/// // Note: if `flag` owned any resources (i.e. had a `Drop` implementation), then we -/// // must prepare to drop it in case `self.contents.clone_to_uninit()` panics. -/// // In this simple case, where we have exactly one field for which `mem::needs_drop()` -/// // might be true (`contents`), we don’t need to care about cleanup or ordering. -/// self.contents.clone_to_uninit(dest.add(offset_of_contents)); +/// // +/// // SAFETY: `self` by definition points somewhere before `&self.contents` in the same +/// // allocation. +/// let offset_of_contents = unsafe { +/// (&raw const self.contents).byte_offset_from_unsigned(self) +/// }; +/// +/// // Clone each field of `self` into `dest`. +/// // +/// // Since `flag` is `Sized`, we could also clone it as +/// // dest.add(offset_of!(Self, flag)).cast::().write(self.flag.clone()); +/// // Since it is `Copy` (and therefore does not have a destructor), we could even write +/// // *dest.add(offset_of!(Self, flag)) = self.flag; +/// // but that must not be used for types with destructors, since it would read the place +/// // in order to drop the old value. We have chosen to do neither of those, to demonstrate +/// // the most general pattern. +/// // +/// // SAFETY: The caller must provide a `dest` such that these offsets are valid +/// // to write to. +/// unsafe { +/// self.flag.clone_to_uninit(dest.add(offset_of!(Self, flag))); +/// self.contents.clone_to_uninit(dest.add(offset_of_contents)); +/// } /// /// // All fields of the struct have been initialized, therefore the struct is initialized, /// // and we have satisfied our `unsafe impl CloneToUninit` obligations. @@ -370,6 +380,7 @@ pub struct AssertParamIsCopy { /// /// assert_eq!(first.contents, [1, 2, 3, 4]); /// assert_eq!(second.contents, [10, 20, 30, 40]); +/// assert_eq!(second.flag, true); /// } /// ``` /// @@ -414,9 +425,8 @@ pub unsafe trait CloneToUninit { /// read or dropped, because even if it was previously valid, it may have been partially /// overwritten. /// - /// The caller may also need to take care to deallocate the allocation pointed to by `dest`, - /// if applicable, to avoid a memory leak, and may need to take other precautions to ensure - /// soundness in the presence of unwinding. + /// The caller may wish to to take care to deallocate the allocation pointed to by `dest`, + /// if applicable, to avoid a memory leak (but this is not a requirement). /// /// Implementors should avoid leaking values by, upon unwinding, dropping all component values /// that might have already been created. (For example, if a `[Foo]` of length 3 is being From 96814ae55fd6201159ca00d79b79d9aae54cba0a Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Mon, 10 Mar 2025 13:54:07 -0700 Subject: [PATCH 10/31] Rewrite example to not deal with `Copy` at all. It also now demonstrates how to avoid memory leaks. --- library/core/src/clone.rs | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index f6f4e2079156e..e0ac0bfc5289f 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -327,7 +327,7 @@ pub struct AssertParamIsCopy { /// /// #[derive(PartialEq)] /// struct MyDst { -/// flag: bool, +/// label: String, /// contents: T, /// } /// @@ -343,24 +343,26 @@ pub struct AssertParamIsCopy { /// (&raw const self.contents).byte_offset_from_unsigned(self) /// }; /// -/// // Clone each field of `self` into `dest`. -/// // -/// // Since `flag` is `Sized`, we could also clone it as -/// // dest.add(offset_of!(Self, flag)).cast::().write(self.flag.clone()); -/// // Since it is `Copy` (and therefore does not have a destructor), we could even write -/// // *dest.add(offset_of!(Self, flag)) = self.flag; -/// // but that must not be used for types with destructors, since it would read the place -/// // in order to drop the old value. We have chosen to do neither of those, to demonstrate -/// // the most general pattern. -/// // -/// // SAFETY: The caller must provide a `dest` such that these offsets are valid +/// // Clone the *sized* fields of `self` (just one, in this example). +/// // (By cloning this first and storing it temporarily in a local variable, we avoid +/// // leaking it in case of any panic, using the ordinary automatic cleanup of local +/// // variables. Such a leak would be sound, but undesirable.) +/// let label = self.label.clone(); +/// +/// // SAFETY: The caller must provide a `dest` such that these field offsets are valid /// // to write to. /// unsafe { -/// self.flag.clone_to_uninit(dest.add(offset_of!(Self, flag))); +/// // Clone the unsized field directly from `self` to `dest`. /// self.contents.clone_to_uninit(dest.add(offset_of_contents)); -/// } /// -/// // All fields of the struct have been initialized, therefore the struct is initialized, +/// // Now write all the sized fields. +/// // +/// // Note that we only do this once all of the clone() and clone_to_uninit() calls +/// // have completed, and therefore we know that there are no more possible panics; +/// // this ensures no memory leaks in case of panic. +/// dest.add(offset_of!(Self, label)).cast::().write(label); +/// } +/// // All fields of the struct have been initialized; therefore, the struct is initialized, /// // and we have satisfied our `unsafe impl CloneToUninit` obligations. /// } /// } @@ -368,7 +370,7 @@ pub struct AssertParamIsCopy { /// fn main() { /// // Construct MyDst<[u8; 4]>, then coerce to MyDst<[u8]>. /// let first: Rc> = Rc::new(MyDst { -/// flag: true, +/// label: String::from("hello"), /// contents: [1, 2, 3, 4], /// }); /// @@ -380,7 +382,7 @@ pub struct AssertParamIsCopy { /// /// assert_eq!(first.contents, [1, 2, 3, 4]); /// assert_eq!(second.contents, [10, 20, 30, 40]); -/// assert_eq!(second.flag, true); +/// assert_eq!(second.label, "hello"); /// } /// ``` /// From 58d4395c1ac791dba1da4ca3149a5809693edb7d Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Mon, 10 Mar 2025 16:01:20 -0700 Subject: [PATCH 11/31] Expand and organize `offset_of!` documentation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Give example of how to get the offset of an unsized tail field (prompted by discussion ). * Specify the return type. * Add section headings. * Reduce “Visibility is respected…”, to a single sentence. --- library/core/src/mem/mod.rs | 62 ++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index caab7a6ddb52f..1ebe3f977fdd7 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1249,42 +1249,60 @@ impl SizedTypeProperties for T {} /// Expands to the offset in bytes of a field from the beginning of the given type. /// -/// Structs, enums, unions and tuples are supported. +/// The type may be a `struct`, `enum`, `union`, or tuple. /// -/// Nested field accesses may be used, but not array indexes. +/// The field may be a nested field (`field1.field2`), but not an array index. +/// The field must be visible to the call site. +/// +/// The offset is returned as a [`usize`]. /// /// If the nightly-only feature `offset_of_enum` is enabled, -/// variants may be traversed as if they were fields. +/// `enum` variants may be traversed as if they were fields. /// Variants themselves do not have an offset. /// -/// Visibility is respected - all types and fields must be visible to the call site: -/// -/// ``` -/// mod nested { -/// #[repr(C)] -/// pub struct Struct { -/// private: u8, -/// } -/// } +/// # Offsets of, and in, dynamically sized types /// -/// // assert_eq!(mem::offset_of!(nested::Struct, private), 0); -/// // ^^^ error[E0616]: field `private` of struct `Struct` is private -/// ``` +/// The field’s type must be [`Sized`], but it may be located in a [dynamically sized] container. +/// If the field type is dynamically sized, then you cannot use `offset_of!` (since the field's +/// alignment, and therefore its offset, may also be dynamic) and must take the offset from an +/// actual pointer to the container instead. /// -/// Only [`Sized`] fields are supported, but the container may be unsized: /// ``` /// # use core::mem; +/// # use core::fmt::Debug; /// #[repr(C)] -/// pub struct Struct { +/// pub struct Struct { /// a: u8, -/// b: [u8], +/// b: T, /// } /// -/// assert_eq!(mem::offset_of!(Struct, a), 0); // OK -/// // assert_eq!(mem::offset_of!(Struct, b), 1); -/// // ^^^ error[E0277]: doesn't have a size known at compile-time +/// #[derive(Debug)] +/// #[repr(C, align(4))] +/// struct Align4(u32); +/// +/// assert_eq!(mem::offset_of!(Struct, a), 0); // OK — Sized field +/// assert_eq!(mem::offset_of!(Struct, b), 4); // OK — not DST +/// +/// // assert_eq!(mem::offset_of!(Struct, b), 1); +/// // ^^^ error[E0277]: ... cannot be known at compilation time +/// +/// // To obtain the offset of a !Sized field, examine a concrete value +/// // instead of using offset_of!. +/// let value: Struct = Struct { a: 1, b: Align4(2) }; +/// let ref_unsized: &Struct = &value; +/// let offset_of_b = unsafe { +/// (&raw const ref_unsized.b).byte_offset_from_unsigned(ref_unsized) +/// }; +/// assert_eq!(offset_of_b, 4); /// ``` /// +/// If you need to obtain the offset of a field of a `!Sized` type, then, since the offset may +/// depend on the particular value being stored (in particular, `dyn Trait` values have a +/// dynamically-determined alignment), you must retrieve the offset from a specific reference +/// or pointer, and so you cannot use `offset_of!` to work without one. +/// +/// # Layout is subject to change +/// /// Note that type layout is, in general, [subject to change and /// platform-specific](https://doc.rust-lang.org/reference/type-layout.html). If /// layout stability is required, consider using an [explicit `repr` attribute]. @@ -1358,6 +1376,8 @@ impl SizedTypeProperties for T {} /// /// assert_eq!(mem::offset_of!(Option<&u8>, Some.0), 0); /// ``` +/// +/// [dynamically sized]: https://doc.rust-lang.org/reference/dynamically-sized-types.html #[stable(feature = "offset_of", since = "1.77.0")] #[allow_internal_unstable(builtin_syntax)] pub macro offset_of($Container:ty, $($fields:expr)+ $(,)?) { From 8f3254714762438639010efd90a721a133e23cec Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Mon, 10 Mar 2025 17:27:30 -0700 Subject: [PATCH 12/31] Move `offset_of_enum` documentation to unstable book; add `offset_of_slice`. --- library/core/src/mem/mod.rs | 26 ++++++---------- .../src/language-features/offset-of-enum.md | 29 ++++++++++++++++++ .../src/language-features/offset-of-slice.md | 30 +++++++++++++++++++ 3 files changed, 68 insertions(+), 17 deletions(-) create mode 100644 src/doc/unstable-book/src/language-features/offset-of-enum.md create mode 100644 src/doc/unstable-book/src/language-features/offset-of-slice.md diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 1ebe3f977fdd7..caf973c53882d 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1256,10 +1256,6 @@ impl SizedTypeProperties for T {} /// /// The offset is returned as a [`usize`]. /// -/// If the nightly-only feature `offset_of_enum` is enabled, -/// `enum` variants may be traversed as if they were fields. -/// Variants themselves do not have an offset. -/// /// # Offsets of, and in, dynamically sized types /// /// The field’s type must be [`Sized`], but it may be located in a [dynamically sized] container. @@ -1338,11 +1334,16 @@ impl SizedTypeProperties for T {} /// /// [explicit `repr` attribute]: https://doc.rust-lang.org/reference/type-layout.html#representations /// +/// # Unstable features +/// +/// The following unstable features expand the functionality of `offset_of!`: +/// +/// * [`offset_of_enum`] — allows `enum` variants to be traversed as if they were fields. +/// * [`offset_of_slice`] — allows getting the offset of a field of type `[T]`. +/// /// # Examples /// /// ``` -/// #![feature(offset_of_enum)] -/// /// use std::mem; /// #[repr(C)] /// struct FieldStruct { @@ -1364,20 +1365,11 @@ impl SizedTypeProperties for T {} /// struct NestedB(u8); /// /// assert_eq!(mem::offset_of!(NestedA, b.0), 0); -/// -/// #[repr(u8)] -/// enum Enum { -/// A(u8, u16), -/// B { one: u8, two: u16 }, -/// } -/// -/// assert_eq!(mem::offset_of!(Enum, A.0), 1); -/// assert_eq!(mem::offset_of!(Enum, B.two), 2); -/// -/// assert_eq!(mem::offset_of!(Option<&u8>, Some.0), 0); /// ``` /// /// [dynamically sized]: https://doc.rust-lang.org/reference/dynamically-sized-types.html +/// [`offset_of_enum`]: https://doc.rust-lang.org/nightly/unstable-book/language-features/offset-of-enum.html +/// [`offset_of_slice`]: https://doc.rust-lang.org/nightly/unstable-book/language-features/offset-of-slice.html #[stable(feature = "offset_of", since = "1.77.0")] #[allow_internal_unstable(builtin_syntax)] pub macro offset_of($Container:ty, $($fields:expr)+ $(,)?) { diff --git a/src/doc/unstable-book/src/language-features/offset-of-enum.md b/src/doc/unstable-book/src/language-features/offset-of-enum.md new file mode 100644 index 0000000000000..1960d6299eb00 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/offset-of-enum.md @@ -0,0 +1,29 @@ +# `offset_of_slice` + +The tracking issue for this feature is: [#120141] + +[#120141]: https://github.com/rust-lang/rust/issues/120141 + +------------------------ + +When the `offset_of_enum` feature is enabled, the [`offset_of!`] macro may be used to obtain the +offsets of fields of `enum`s; to express this, `enum` variants may be traversed as if they were +fields. Variants themselves do not have an offset, so they cannot appear as the last path component. + +```rust +#![feature(offset_of_enum)] +use std::mem; + +#[repr(u8)] +enum Enum { + A(u8, u16), + B { one: u8, two: u16 }, +} + +assert_eq!(mem::offset_of!(Enum, A.0), 1); +assert_eq!(mem::offset_of!(Enum, B.two), 2); + +assert_eq!(mem::offset_of!(Option<&u8>, Some.0), 0); +``` + +[`offset_of!`]: ../../std/mem/macro.offset_of.html diff --git a/src/doc/unstable-book/src/language-features/offset-of-slice.md b/src/doc/unstable-book/src/language-features/offset-of-slice.md new file mode 100644 index 0000000000000..c887fa07f67e1 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/offset-of-slice.md @@ -0,0 +1,30 @@ +# `offset_of_slice` + +The tracking issue for this feature is: [#126151] + +[#126151]: https://github.com/rust-lang/rust/issues/126151 + +------------------------ + +When the `offset_of_slice` feature is enabled, the [`offset_of!`] macro may be used to determine +the offset of fields whose type is `[T]`, that is, a slice of dynamic size. + +In general, fields whose type is dynamically sized do not have statically known offsets because +they do not have statically known alignments. However, `[T]` has the same alignment as `T`, so +it specifically may be allowed. + +```rust +#![feature(offset_of_slice)] + +#[repr(C)] +pub struct Struct { + head: u32, + tail: [u8], +} + +fn main() { + assert_eq!(std::mem::offset_of!(Struct, tail), 4); +} +``` + +[`offset_of!`]: ../../std/mem/macro.offset_of.html From 3c74d02319ea8ebbfd16f70f3154ce0aef87ae5c Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Mon, 10 Mar 2025 18:22:28 -0700 Subject: [PATCH 13/31] debug-assert that the size_hint is well-formed in `collect` --- library/core/src/iter/traits/iterator.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 42886e90f997d..25cb4795b4da6 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -1968,6 +1968,15 @@ pub trait Iterator { where Self: Sized, { + // This is too aggressive to turn on for everything all the time, but PR#137908 + // accidentally noticed that some rustc iterators had malformed `size_hint`s, + // so this will help catch such things in debug-assertions-std runners, + // even if users won't actually ever see it. + if cfg!(debug_assertions) { + let hint = self.size_hint(); + assert!(hint.1.is_none_or(|high| high >= hint.0), "Malformed size_hint {hint:?}"); + } + FromIterator::from_iter(self) } From d2ff65807c5babc8066e789b60092c45cfef32c0 Mon Sep 17 00:00:00 2001 From: ClearLove <98693523+DiuDiu777@users.noreply.github.com> Date: Thu, 13 Mar 2025 11:33:55 +0800 Subject: [PATCH 14/31] Update library/core/src/intrinsics/mod.rs Co-authored-by: Thom Chiovoloni --- library/core/src/intrinsics/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 4fa6df9f5525a..8055c7c0bc25f 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -3213,7 +3213,7 @@ pub const fn is_val_statically_known(_arg: T) -> bool { /// * The region of memory beginning at `x` must *not* overlap with the region of memory /// beginning at `y`. /// -/// * The memory pointed by `x` and `y` must contain correct value of type `T`. +/// * The memory pointed by `x` and `y` must both contain values of type `T`. /// /// [valid]: crate::ptr#safety #[rustc_nounwind] From 6a0199021548bc42a5aa1d41cd69499afaba448a Mon Sep 17 00:00:00 2001 From: ClearLove <98693523+DiuDiu777@users.noreply.github.com> Date: Thu, 13 Mar 2025 11:34:06 +0800 Subject: [PATCH 15/31] Update library/core/src/intrinsics/mod.rs Co-authored-by: Thom Chiovoloni --- library/core/src/intrinsics/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 8055c7c0bc25f..be2cfd3f3edb7 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -1660,7 +1660,7 @@ pub unsafe fn volatile_copy_memory(_dst: *mut T, _src: *const T, _count: usiz /// # Safety /// /// The safety requirements are consistent with [`write_bytes`] while the write behavior is volatile, -/// which means it will not be optimized out unless size is equal to zero. +/// which means it will not be optimized out unless `_count` or `size_of::()` is equal to zero. /// /// [`write_bytes`]: ptr::write_bytes #[rustc_intrinsic] From 2f824ea429cf09a9816baa3d4b55c551896838fe Mon Sep 17 00:00:00 2001 From: ClearLove <98693523+DiuDiu777@users.noreply.github.com> Date: Thu, 13 Mar 2025 11:34:18 +0800 Subject: [PATCH 16/31] Update library/core/src/intrinsics/mod.rs Co-authored-by: Thom Chiovoloni --- library/core/src/intrinsics/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index be2cfd3f3edb7..ce8c8c8946ef1 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -1635,7 +1635,7 @@ pub fn ptr_mask(_ptr: *const T, _mask: usize) -> *const T; /// /// The safety requirements are consistent with [`copy_nonoverlapping`] /// while the read and write behaviors are volatile, -/// which means it will not be optimized out unless size is equal to zero. +/// which means it will not be optimized out unless `_count` or `size_of::()` is equal to zero. /// /// [`copy_nonoverlapping`]: ptr::copy_nonoverlapping #[rustc_intrinsic] From ad74285275e5981e326801dddd625a4df243d6ea Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 16 Feb 2025 23:24:29 +0530 Subject: [PATCH 17/31] add exclude to config.toml --- config.example.toml | 4 +++ src/bootstrap/src/core/config/config.rs | 38 ++++++++++++++----------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/config.example.toml b/config.example.toml index c3d2ad094ceba..0700a31710995 100644 --- a/config.example.toml +++ b/config.example.toml @@ -446,6 +446,10 @@ # a specific version. #ccache = false +# List of paths to exclude from the build and test processes. +# For example, exclude = ["tests/ui", "src/tools/tidy"]. +#exclude = [] + # ============================================================================= # General install configuration options # ============================================================================= diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index a07c40bdc83e0..18624a7c78f15 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -959,6 +959,7 @@ define_config! { jobs: Option = "jobs", compiletest_diff_tool: Option = "compiletest-diff-tool", ccache: Option = "ccache", + exclude: Option> = "exclude", } } @@ -1397,22 +1398,6 @@ impl Config { "flags.exclude" = ?flags.exclude ); - config.skip = flags - .skip - .into_iter() - .chain(flags.exclude) - .map(|p| { - // Never return top-level path here as it would break `--skip` - // logic on rustc's internal test framework which is utilized - // by compiletest. - if cfg!(windows) { - PathBuf::from(p.to_str().unwrap().replace('/', "\\")) - } else { - p - } - }) - .collect(); - #[cfg(feature = "tracing")] span!( target: "CONFIG_HANDLING", @@ -1658,8 +1643,29 @@ impl Config { jobs, compiletest_diff_tool, mut ccache, + exclude, } = toml.build.unwrap_or_default(); + let mut paths: Vec = flags.skip.into_iter().chain(flags.exclude).collect(); + + if let Some(exclude) = exclude { + paths.extend(exclude); + } + + config.skip = paths + .into_iter() + .map(|p| { + // Never return top-level path here as it would break `--skip` + // logic on rustc's internal test framework which is utilized + // by compiletest. + if cfg!(windows) { + PathBuf::from(p.to_str().unwrap().replace('/', "\\")) + } else { + p + } + }) + .collect(); + config.jobs = Some(threads_from_config(flags.jobs.unwrap_or(jobs.unwrap_or(0)))); if let Some(file_build) = build { From 7d1537e4251caa7e08bea7ad41b2f1e3ad38a29d Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 17 Feb 2025 01:28:39 +0530 Subject: [PATCH 18/31] add test for exclude feature --- src/bootstrap/src/core/config/tests.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs index eff5e0337428c..27968bea31869 100644 --- a/src/bootstrap/src/core/config/tests.rs +++ b/src/bootstrap/src/core/config/tests.rs @@ -515,3 +515,17 @@ fn test_explicit_stage() { assert!(!config.explicit_stage_from_config); assert!(!config.is_explicit_stage()); } + +#[test] +fn test_exclude() { + let config = parse("build.exclude=[\"test/codegen\"]"); + + let first_excluded = config + .skip + .first() + .expect("Expected at least one excluded path") + .to_str() + .expect("Failed to convert excluded path to string"); + + assert_eq!(first_excluded, "test/codegen"); +} From 22571da9f8fa91f96edc4809f05a15a5b38a0d84 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 17 Feb 2025 01:34:32 +0530 Subject: [PATCH 19/31] Add change info to change tracker --- src/bootstrap/src/utils/change_tracker.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 8036c59210867..f8478725c4cd0 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -380,4 +380,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Warning, summary: "Removed `src/tools/rls` tool as it was deprecated long time ago.", }, + ChangeInfo { + change_id: 137147, + severity: ChangeSeverity::Info, + summary: "New option `build.exclude` that adds support for excluding test.", + }, ]; From 9d5f0742a999c177fea10da93a77d5d8b797710d Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Wed, 5 Mar 2025 03:07:01 +0530 Subject: [PATCH 20/31] make test platform agnostic --- src/bootstrap/src/core/config/tests.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs index 27968bea31869..217df313c58a6 100644 --- a/src/bootstrap/src/core/config/tests.rs +++ b/src/bootstrap/src/core/config/tests.rs @@ -518,7 +518,9 @@ fn test_explicit_stage() { #[test] fn test_exclude() { - let config = parse("build.exclude=[\"test/codegen\"]"); + use std::path::MAIN_SEPARATOR; + let exclude_path = format!("test{}codegen", MAIN_SEPARATOR); + let config = parse(&format!("build.exclude=[\"{}\"]", exclude_path)); let first_excluded = config .skip @@ -527,5 +529,5 @@ fn test_exclude() { .to_str() .expect("Failed to convert excluded path to string"); - assert_eq!(first_excluded, "test/codegen"); + assert_eq!(first_excluded, exclude_path); } From c6ecd8c95c84cd45e4de8abb767093d0f9aec670 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 9 Mar 2025 16:29:42 +0530 Subject: [PATCH 21/31] update the test_exclude to not use paths with path separators --- src/bootstrap/src/core/config/tests.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs index 217df313c58a6..c7b6f3681b891 100644 --- a/src/bootstrap/src/core/config/tests.rs +++ b/src/bootstrap/src/core/config/tests.rs @@ -518,8 +518,7 @@ fn test_explicit_stage() { #[test] fn test_exclude() { - use std::path::MAIN_SEPARATOR; - let exclude_path = format!("test{}codegen", MAIN_SEPARATOR); + let exclude_path = "compiler"; let config = parse(&format!("build.exclude=[\"{}\"]", exclude_path)); let first_excluded = config From b9e00b32e32da846de8147288e539f5d77f2d63f Mon Sep 17 00:00:00 2001 From: klensy Date: Thu, 13 Mar 2025 19:53:01 +0300 Subject: [PATCH 22/31] bump html5ever to 0.28 see https://github.com/servo/html5ever/pull/548 --- Cargo.lock | 8 ++++---- src/tools/linkchecker/Cargo.toml | 2 +- src/tools/linkchecker/main.rs | 24 ++++++++++++------------ 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 942f8f43935bd..8da9cd22824df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1548,9 +1548,9 @@ dependencies = [ [[package]] name = "html5ever" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c13771afe0e6e846f1e67d038d4cb29998a6779f93c809212e4e9c32efd244d4" +checksum = "0ff6858c1f7e2a470c5403091866fa95b36fe0dbac5d771f932c15e5ff1ee501" dependencies = [ "log", "mac", @@ -2134,9 +2134,9 @@ checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" [[package]] name = "markup5ever" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16ce3abbeba692c8b8441d036ef91aea6df8da2c6b6e21c7e14d3c18e526be45" +checksum = "d581ff8be69d08a2efa23a959d81aa22b739073f749f067348bd4f4ba4b69195" dependencies = [ "log", "phf", diff --git a/src/tools/linkchecker/Cargo.toml b/src/tools/linkchecker/Cargo.toml index f1be6e9e749d4..43b77bf374e01 100644 --- a/src/tools/linkchecker/Cargo.toml +++ b/src/tools/linkchecker/Cargo.toml @@ -9,4 +9,4 @@ path = "main.rs" [dependencies] regex = "1" -html5ever = "0.27.0" +html5ever = "0.28.0" diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 19340b5d07a11..84cba3f8c4473 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -16,7 +16,7 @@ //! A few exceptions are allowed as there's known bugs in rustdoc, but this //! should catch the majority of "broken link" cases. -use std::cell::RefCell; +use std::cell::{Cell, RefCell}; use std::collections::{HashMap, HashSet}; use std::io::ErrorKind; use std::path::{Component, Path, PathBuf}; @@ -544,7 +544,7 @@ fn parse_html(source: &str, sink: Sink) -> Sink { let mut input = BufferQueue::default(); input.push_back(tendril.try_reinterpret().unwrap()); - let mut tok = Tokenizer::new(sink, TokenizerOpts::default()); + let tok = Tokenizer::new(sink, TokenizerOpts::default()); let _ = tok.feed(&mut input); assert!(input.is_empty()); tok.end(); @@ -554,8 +554,8 @@ fn parse_html(source: &str, sink: Sink) -> Sink { #[derive(Default)] struct AttrCollector { attr_name: &'static [u8], - base: Option, - found_attrs: Vec<(u64, String)>, + base: Cell>, + found_attrs: RefCell>, /// Tracks whether or not it is inside a