diff --git a/library/Cargo.lock b/library/Cargo.lock index 8f174f284724f..ac8740605144a 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -85,6 +85,7 @@ version = "0.0.0" dependencies = [ "rand", "rand_xorshift", + "regex", ] [[package]] @@ -157,9 +158,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.170" +version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" dependencies = [ "rustc-std-workspace-core", ] @@ -303,6 +304,31 @@ dependencies = [ "rand_core", ] +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + [[package]] name = "rustc-demangle" version = "0.1.24" diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index b7ba4505006ef..cd78f948b47c7 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -8,7 +8,7 @@ repository = "https://github.com/rust-lang/rust.git" description = "The Rust core allocation and collections library" autotests = false autobenches = false -edition = "2021" +edition = "2024" [lib] test = false diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index fc1cee28d0334..619d9f258e342 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1327,11 +1327,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) for the duration of this method, and `ptr` must point to a block of memory /// allocated by the global allocator. /// + /// [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 `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 /// /// # Examples /// diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 4999319f618e4..104cb35c23b65 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,11 +1812,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 - /// least 1) for the duration of this method,, and `ptr` must point to a block of memory + /// 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 `alloc`. /// + /// [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 /// `Arc` and backing storage, but **should not** be called after the final `Arc` has been /// released. /// + /// [from_raw_in]: Arc::from_raw_in + /// /// # Examples /// /// ``` diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml index 011876761a95c..0bd15254e8547 100644 --- a/library/core/Cargo.toml +++ b/library/core/Cargo.toml @@ -9,7 +9,7 @@ autobenches = false # If you update this, be sure to update it in a bunch of other places too! # As of 2024, it was src/tools/opt-dist, the core-no-fp-fmt-parse test and # the version of the prelude imported in core/lib.rs. -edition = "2021" +edition = "2024" [lib] test = false 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 10e9e40db1fda..39c37b7090d61 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -1180,7 +1180,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/clone.rs b/library/core/src/clone.rs index c777dd995a656..e0ac0bfc5289f 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -262,34 +262,150 @@ 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 { +/// label: String, +/// 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!`. +/// // +/// // 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 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 { +/// // Clone the unsized field directly from `self` to `dest`. +/// self.contents.clone_to_uninit(dest.add(offset_of_contents)); +/// +/// // 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. +/// } +/// } +/// +/// fn main() { +/// // Construct MyDst<[u8; 4]>, then coerce to MyDst<[u8]>. +/// let first: Rc> = Rc::new(MyDst { +/// label: String::from("hello"), +/// 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]); +/// assert_eq!(second.label, "hello"); +/// } +/// ``` +/// +/// # 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 +413,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,27 +423,26 @@ 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`, - /// 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 /// 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 +450,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 +461,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) } } } diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index b29251b4b436c..25bd17d5802fd 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -1481,7 +1481,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) } @@ -1573,7 +1573,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 43fd54f881dae..e1b10e1074d27 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 e0dc632df7051..b13c7ee5aa28b 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 { @@ -2771,7 +2771,14 @@ impl Display for char { #[stable(feature = "rust1", since = "1.0.0")] impl Pointer for *const T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { - pointer_fmt_inner(self.expose_provenance(), f) + if <::Metadata as core::unit::IsUnit>::is_unit() { + pointer_fmt_inner(self.expose_provenance(), f) + } else { + f.debug_struct("Pointer") + .field_with("addr", |f| pointer_fmt_inner(self.expose_provenance(), f)) + .field("metadata", &core::ptr::metadata(*self)) + .finish() + } } } diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index c4444f4d6a2b1..c7ca4d71c9cf4 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -94,6 +94,7 @@ pub unsafe fn drop_in_place(to_drop: *mut T) { // memory, which is not valid for either `&` or `&mut`. /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange` method by passing @@ -103,6 +104,7 @@ pub unsafe fn drop_in_place(to_drop: *mut T) { #[rustc_nounwind] pub unsafe fn atomic_cxchg_relaxed_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange` method by passing @@ -112,6 +114,7 @@ pub unsafe fn atomic_cxchg_relaxed_relaxed(dst: *mut T, old: T, src: T) #[rustc_nounwind] pub unsafe fn atomic_cxchg_relaxed_acquire(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange` method by passing @@ -121,6 +124,7 @@ pub unsafe fn atomic_cxchg_relaxed_acquire(dst: *mut T, old: T, src: T) #[rustc_nounwind] pub unsafe fn atomic_cxchg_relaxed_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange` method by passing @@ -130,6 +134,7 @@ pub unsafe fn atomic_cxchg_relaxed_seqcst(dst: *mut T, old: T, src: T) #[rustc_nounwind] pub unsafe fn atomic_cxchg_acquire_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange` method by passing @@ -139,6 +144,7 @@ pub unsafe fn atomic_cxchg_acquire_relaxed(dst: *mut T, old: T, src: T) #[rustc_nounwind] pub unsafe fn atomic_cxchg_acquire_acquire(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange` method by passing @@ -148,6 +154,7 @@ pub unsafe fn atomic_cxchg_acquire_acquire(dst: *mut T, old: T, src: T) #[rustc_nounwind] pub unsafe fn atomic_cxchg_acquire_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange` method by passing @@ -157,6 +164,7 @@ pub unsafe fn atomic_cxchg_acquire_seqcst(dst: *mut T, old: T, src: T) #[rustc_nounwind] pub unsafe fn atomic_cxchg_release_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange` method by passing @@ -166,6 +174,7 @@ pub unsafe fn atomic_cxchg_release_relaxed(dst: *mut T, old: T, src: T) #[rustc_nounwind] pub unsafe fn atomic_cxchg_release_acquire(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange` method by passing @@ -175,6 +184,7 @@ pub unsafe fn atomic_cxchg_release_acquire(dst: *mut T, old: T, src: T) #[rustc_nounwind] pub unsafe fn atomic_cxchg_release_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange` method by passing @@ -184,6 +194,7 @@ pub unsafe fn atomic_cxchg_release_seqcst(dst: *mut T, old: T, src: T) #[rustc_nounwind] pub unsafe fn atomic_cxchg_acqrel_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange` method by passing @@ -193,6 +204,7 @@ pub unsafe fn atomic_cxchg_acqrel_relaxed(dst: *mut T, old: T, src: T) #[rustc_nounwind] pub unsafe fn atomic_cxchg_acqrel_acquire(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange` method by passing @@ -202,6 +214,7 @@ pub unsafe fn atomic_cxchg_acqrel_acquire(dst: *mut T, old: T, src: T) #[rustc_nounwind] pub unsafe fn atomic_cxchg_acqrel_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange` method by passing @@ -211,6 +224,7 @@ pub unsafe fn atomic_cxchg_acqrel_seqcst(dst: *mut T, old: T, src: T) - #[rustc_nounwind] pub unsafe fn atomic_cxchg_seqcst_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange` method by passing @@ -220,6 +234,7 @@ pub unsafe fn atomic_cxchg_seqcst_relaxed(dst: *mut T, old: T, src: T) #[rustc_nounwind] pub unsafe fn atomic_cxchg_seqcst_acquire(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange` method by passing @@ -230,6 +245,7 @@ pub unsafe fn atomic_cxchg_seqcst_acquire(dst: *mut T, old: T, src: T) pub unsafe fn atomic_cxchg_seqcst_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange_weak` method by passing @@ -243,6 +259,7 @@ pub unsafe fn atomic_cxchgweak_relaxed_relaxed( _src: T, ) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange_weak` method by passing @@ -256,6 +273,7 @@ pub unsafe fn atomic_cxchgweak_relaxed_acquire( _src: T, ) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange_weak` method by passing @@ -265,6 +283,7 @@ pub unsafe fn atomic_cxchgweak_relaxed_acquire( #[rustc_nounwind] pub unsafe fn atomic_cxchgweak_relaxed_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange_weak` method by passing @@ -278,6 +297,7 @@ pub unsafe fn atomic_cxchgweak_acquire_relaxed( _src: T, ) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange_weak` method by passing @@ -291,6 +311,7 @@ pub unsafe fn atomic_cxchgweak_acquire_acquire( _src: T, ) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange_weak` method by passing @@ -300,6 +321,7 @@ pub unsafe fn atomic_cxchgweak_acquire_acquire( #[rustc_nounwind] pub unsafe fn atomic_cxchgweak_acquire_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange_weak` method by passing @@ -313,6 +335,7 @@ pub unsafe fn atomic_cxchgweak_release_relaxed( _src: T, ) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange_weak` method by passing @@ -326,6 +349,7 @@ pub unsafe fn atomic_cxchgweak_release_acquire( _src: T, ) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange_weak` method by passing @@ -335,6 +359,7 @@ pub unsafe fn atomic_cxchgweak_release_acquire( #[rustc_nounwind] pub unsafe fn atomic_cxchgweak_release_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange_weak` method by passing @@ -344,6 +369,7 @@ pub unsafe fn atomic_cxchgweak_release_seqcst(dst: *mut T, old: T, src: #[rustc_nounwind] pub unsafe fn atomic_cxchgweak_acqrel_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange_weak` method by passing @@ -353,6 +379,7 @@ pub unsafe fn atomic_cxchgweak_acqrel_relaxed(dst: *mut T, old: T, src: #[rustc_nounwind] pub unsafe fn atomic_cxchgweak_acqrel_acquire(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange_weak` method by passing @@ -362,6 +389,7 @@ pub unsafe fn atomic_cxchgweak_acqrel_acquire(dst: *mut T, old: T, src: #[rustc_nounwind] pub unsafe fn atomic_cxchgweak_acqrel_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange_weak` method by passing @@ -371,6 +399,7 @@ pub unsafe fn atomic_cxchgweak_acqrel_seqcst(dst: *mut T, old: T, src: #[rustc_nounwind] pub unsafe fn atomic_cxchgweak_seqcst_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange_weak` method by passing @@ -380,6 +409,7 @@ pub unsafe fn atomic_cxchgweak_seqcst_relaxed(dst: *mut T, old: T, src: #[rustc_nounwind] pub unsafe fn atomic_cxchgweak_seqcst_acquire(dst: *mut T, old: T, src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `compare_exchange_weak` method by passing @@ -390,6 +420,7 @@ pub unsafe fn atomic_cxchgweak_seqcst_acquire(dst: *mut T, old: T, src: pub unsafe fn atomic_cxchgweak_seqcst_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); /// Loads the current value of the pointer. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `load` method by passing @@ -398,6 +429,7 @@ pub unsafe fn atomic_cxchgweak_seqcst_seqcst(dst: *mut T, old: T, src: #[rustc_nounwind] pub unsafe fn atomic_load_seqcst(src: *const T) -> T; /// Loads the current value of the pointer. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `load` method by passing @@ -406,6 +438,7 @@ pub unsafe fn atomic_load_seqcst(src: *const T) -> T; #[rustc_nounwind] pub unsafe fn atomic_load_acquire(src: *const T) -> T; /// Loads the current value of the pointer. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `load` method by passing @@ -421,6 +454,7 @@ pub unsafe fn atomic_load_relaxed(src: *const T) -> T; pub unsafe fn atomic_load_unordered(src: *const T) -> T; /// Stores the value at the specified memory location. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `store` method by passing @@ -429,6 +463,7 @@ pub unsafe fn atomic_load_unordered(src: *const T) -> T; #[rustc_nounwind] pub unsafe fn atomic_store_seqcst(dst: *mut T, val: T); /// Stores the value at the specified memory location. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `store` method by passing @@ -437,6 +472,7 @@ pub unsafe fn atomic_store_seqcst(dst: *mut T, val: T); #[rustc_nounwind] pub unsafe fn atomic_store_release(dst: *mut T, val: T); /// Stores the value at the specified memory location. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `store` method by passing @@ -452,6 +488,7 @@ pub unsafe fn atomic_store_relaxed(dst: *mut T, val: T); pub unsafe fn atomic_store_unordered(dst: *mut T, val: T); /// Stores the value at the specified memory location, returning the old value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `swap` method by passing @@ -460,6 +497,7 @@ pub unsafe fn atomic_store_unordered(dst: *mut T, val: T); #[rustc_nounwind] pub unsafe fn atomic_xchg_seqcst(dst: *mut T, src: T) -> T; /// Stores the value at the specified memory location, returning the old value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `swap` method by passing @@ -468,6 +506,7 @@ pub unsafe fn atomic_xchg_seqcst(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_xchg_acquire(dst: *mut T, src: T) -> T; /// Stores the value at the specified memory location, returning the old value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `swap` method by passing @@ -476,6 +515,7 @@ pub unsafe fn atomic_xchg_acquire(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_xchg_release(dst: *mut T, src: T) -> T; /// Stores the value at the specified memory location, returning the old value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `swap` method by passing @@ -484,6 +524,7 @@ pub unsafe fn atomic_xchg_release(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_xchg_acqrel(dst: *mut T, src: T) -> T; /// Stores the value at the specified memory location, returning the old value. +/// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `swap` method by passing @@ -493,6 +534,9 @@ pub unsafe fn atomic_xchg_acqrel(dst: *mut T, src: T) -> T; pub unsafe fn atomic_xchg_relaxed(dst: *mut T, src: T) -> T; /// Adds to the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_add` method by passing @@ -501,6 +545,9 @@ pub unsafe fn atomic_xchg_relaxed(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_xadd_seqcst(dst: *mut T, src: T) -> T; /// Adds to the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_add` method by passing @@ -509,6 +556,9 @@ pub unsafe fn atomic_xadd_seqcst(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_xadd_acquire(dst: *mut T, src: T) -> T; /// Adds to the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_add` method by passing @@ -517,6 +567,9 @@ pub unsafe fn atomic_xadd_acquire(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_xadd_release(dst: *mut T, src: T) -> T; /// Adds to the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_add` method by passing @@ -525,6 +578,9 @@ pub unsafe fn atomic_xadd_release(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_xadd_acqrel(dst: *mut T, src: T) -> T; /// Adds to the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_add` method by passing @@ -534,6 +590,9 @@ pub unsafe fn atomic_xadd_acqrel(dst: *mut T, src: T) -> T; pub unsafe fn atomic_xadd_relaxed(dst: *mut T, src: T) -> T; /// Subtract from the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_sub` method by passing @@ -542,6 +601,9 @@ pub unsafe fn atomic_xadd_relaxed(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_xsub_seqcst(dst: *mut T, src: T) -> T; /// Subtract from the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_sub` method by passing @@ -550,6 +612,9 @@ pub unsafe fn atomic_xsub_seqcst(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_xsub_acquire(dst: *mut T, src: T) -> T; /// Subtract from the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_sub` method by passing @@ -558,6 +623,9 @@ pub unsafe fn atomic_xsub_acquire(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_xsub_release(dst: *mut T, src: T) -> T; /// Subtract from the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_sub` method by passing @@ -566,6 +634,9 @@ pub unsafe fn atomic_xsub_release(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_xsub_acqrel(dst: *mut T, src: T) -> T; /// Subtract from the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_sub` method by passing @@ -575,6 +646,9 @@ pub unsafe fn atomic_xsub_acqrel(dst: *mut T, src: T) -> T; pub unsafe fn atomic_xsub_relaxed(dst: *mut T, src: T) -> T; /// Bitwise and with the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_and` method by passing @@ -583,6 +657,9 @@ pub unsafe fn atomic_xsub_relaxed(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_and_seqcst(dst: *mut T, src: T) -> T; /// Bitwise and with the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_and` method by passing @@ -591,6 +668,9 @@ pub unsafe fn atomic_and_seqcst(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_and_acquire(dst: *mut T, src: T) -> T; /// Bitwise and with the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_and` method by passing @@ -599,6 +679,9 @@ pub unsafe fn atomic_and_acquire(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_and_release(dst: *mut T, src: T) -> T; /// Bitwise and with the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_and` method by passing @@ -607,6 +690,9 @@ pub unsafe fn atomic_and_release(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_and_acqrel(dst: *mut T, src: T) -> T; /// Bitwise and with the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_and` method by passing @@ -616,6 +702,9 @@ pub unsafe fn atomic_and_acqrel(dst: *mut T, src: T) -> T; pub unsafe fn atomic_and_relaxed(dst: *mut T, src: T) -> T; /// Bitwise nand with the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`AtomicBool`] type via the `fetch_nand` method by passing @@ -624,6 +713,9 @@ pub unsafe fn atomic_and_relaxed(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_nand_seqcst(dst: *mut T, src: T) -> T; /// Bitwise nand with the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`AtomicBool`] type via the `fetch_nand` method by passing @@ -632,6 +724,9 @@ pub unsafe fn atomic_nand_seqcst(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_nand_acquire(dst: *mut T, src: T) -> T; /// Bitwise nand with the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`AtomicBool`] type via the `fetch_nand` method by passing @@ -640,6 +735,9 @@ pub unsafe fn atomic_nand_acquire(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_nand_release(dst: *mut T, src: T) -> T; /// Bitwise nand with the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`AtomicBool`] type via the `fetch_nand` method by passing @@ -648,6 +746,9 @@ pub unsafe fn atomic_nand_release(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_nand_acqrel(dst: *mut T, src: T) -> T; /// Bitwise nand with the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`AtomicBool`] type via the `fetch_nand` method by passing @@ -657,6 +758,9 @@ pub unsafe fn atomic_nand_acqrel(dst: *mut T, src: T) -> T; pub unsafe fn atomic_nand_relaxed(dst: *mut T, src: T) -> T; /// Bitwise or with the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_or` method by passing @@ -665,6 +769,9 @@ pub unsafe fn atomic_nand_relaxed(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_or_seqcst(dst: *mut T, src: T) -> T; /// Bitwise or with the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_or` method by passing @@ -673,6 +780,9 @@ pub unsafe fn atomic_or_seqcst(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_or_acquire(dst: *mut T, src: T) -> T; /// Bitwise or with the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_or` method by passing @@ -681,6 +791,9 @@ pub unsafe fn atomic_or_acquire(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_or_release(dst: *mut T, src: T) -> T; /// Bitwise or with the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_or` method by passing @@ -689,6 +802,9 @@ pub unsafe fn atomic_or_release(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_or_acqrel(dst: *mut T, src: T) -> T; /// Bitwise or with the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_or` method by passing @@ -698,6 +814,9 @@ pub unsafe fn atomic_or_acqrel(dst: *mut T, src: T) -> T; pub unsafe fn atomic_or_relaxed(dst: *mut T, src: T) -> T; /// Bitwise xor with the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_xor` method by passing @@ -706,6 +825,9 @@ pub unsafe fn atomic_or_relaxed(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_xor_seqcst(dst: *mut T, src: T) -> T; /// Bitwise xor with the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_xor` method by passing @@ -714,6 +836,9 @@ pub unsafe fn atomic_xor_seqcst(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_xor_acquire(dst: *mut T, src: T) -> T; /// Bitwise xor with the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_xor` method by passing @@ -722,6 +847,9 @@ pub unsafe fn atomic_xor_acquire(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_xor_release(dst: *mut T, src: T) -> T; /// Bitwise xor with the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_xor` method by passing @@ -730,6 +858,9 @@ pub unsafe fn atomic_xor_release(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_xor_acqrel(dst: *mut T, src: T) -> T; /// Bitwise xor with the current value, returning the previous value. +/// `T` must be an integer or pointer type. +/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new +/// value stored at `*dst` will have the provenance of the old value stored there. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_xor` method by passing @@ -739,6 +870,7 @@ pub unsafe fn atomic_xor_acqrel(dst: *mut T, src: T) -> T; pub unsafe fn atomic_xor_relaxed(dst: *mut T, src: T) -> T; /// Maximum with the current value using a signed comparison. +/// `T` must be a signed integer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] signed integer types via the `fetch_max` method by passing @@ -747,6 +879,7 @@ pub unsafe fn atomic_xor_relaxed(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_max_seqcst(dst: *mut T, src: T) -> T; /// Maximum with the current value using a signed comparison. +/// `T` must be a signed integer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] signed integer types via the `fetch_max` method by passing @@ -755,6 +888,7 @@ pub unsafe fn atomic_max_seqcst(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_max_acquire(dst: *mut T, src: T) -> T; /// Maximum with the current value using a signed comparison. +/// `T` must be a signed integer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] signed integer types via the `fetch_max` method by passing @@ -763,6 +897,7 @@ pub unsafe fn atomic_max_acquire(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_max_release(dst: *mut T, src: T) -> T; /// Maximum with the current value using a signed comparison. +/// `T` must be a signed integer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] signed integer types via the `fetch_max` method by passing @@ -770,7 +905,8 @@ pub unsafe fn atomic_max_release(dst: *mut T, src: T) -> T; #[rustc_intrinsic] #[rustc_nounwind] pub unsafe fn atomic_max_acqrel(dst: *mut T, src: T) -> T; -/// Maximum with the current value. +/// Maximum with the current value using a signed comparison. +/// `T` must be a signed integer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] signed integer types via the `fetch_max` method by passing @@ -780,6 +916,7 @@ pub unsafe fn atomic_max_acqrel(dst: *mut T, src: T) -> T; pub unsafe fn atomic_max_relaxed(dst: *mut T, src: T) -> T; /// Minimum with the current value using a signed comparison. +/// `T` must be a signed integer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] signed integer types via the `fetch_min` method by passing @@ -788,6 +925,7 @@ pub unsafe fn atomic_max_relaxed(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_min_seqcst(dst: *mut T, src: T) -> T; /// Minimum with the current value using a signed comparison. +/// `T` must be a signed integer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] signed integer types via the `fetch_min` method by passing @@ -796,6 +934,7 @@ pub unsafe fn atomic_min_seqcst(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_min_acquire(dst: *mut T, src: T) -> T; /// Minimum with the current value using a signed comparison. +/// `T` must be a signed integer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] signed integer types via the `fetch_min` method by passing @@ -804,6 +943,7 @@ pub unsafe fn atomic_min_acquire(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_min_release(dst: *mut T, src: T) -> T; /// Minimum with the current value using a signed comparison. +/// `T` must be a signed integer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] signed integer types via the `fetch_min` method by passing @@ -812,6 +952,7 @@ pub unsafe fn atomic_min_release(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_min_acqrel(dst: *mut T, src: T) -> T; /// Minimum with the current value using a signed comparison. +/// `T` must be a signed integer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] signed integer types via the `fetch_min` method by passing @@ -821,6 +962,7 @@ pub unsafe fn atomic_min_acqrel(dst: *mut T, src: T) -> T; pub unsafe fn atomic_min_relaxed(dst: *mut T, src: T) -> T; /// Minimum with the current value using an unsigned comparison. +/// `T` must be an unsigned integer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] unsigned integer types via the `fetch_min` method by passing @@ -829,6 +971,7 @@ pub unsafe fn atomic_min_relaxed(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_umin_seqcst(dst: *mut T, src: T) -> T; /// Minimum with the current value using an unsigned comparison. +/// `T` must be an unsigned integer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] unsigned integer types via the `fetch_min` method by passing @@ -837,6 +980,7 @@ pub unsafe fn atomic_umin_seqcst(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_umin_acquire(dst: *mut T, src: T) -> T; /// Minimum with the current value using an unsigned comparison. +/// `T` must be an unsigned integer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] unsigned integer types via the `fetch_min` method by passing @@ -845,6 +989,7 @@ pub unsafe fn atomic_umin_acquire(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_umin_release(dst: *mut T, src: T) -> T; /// Minimum with the current value using an unsigned comparison. +/// `T` must be an unsigned integer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] unsigned integer types via the `fetch_min` method by passing @@ -853,6 +998,7 @@ pub unsafe fn atomic_umin_release(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_umin_acqrel(dst: *mut T, src: T) -> T; /// Minimum with the current value using an unsigned comparison. +/// `T` must be an unsigned integer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] unsigned integer types via the `fetch_min` method by passing @@ -862,6 +1008,7 @@ pub unsafe fn atomic_umin_acqrel(dst: *mut T, src: T) -> T; pub unsafe fn atomic_umin_relaxed(dst: *mut T, src: T) -> T; /// Maximum with the current value using an unsigned comparison. +/// `T` must be an unsigned integer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] unsigned integer types via the `fetch_max` method by passing @@ -870,6 +1017,7 @@ pub unsafe fn atomic_umin_relaxed(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_umax_seqcst(dst: *mut T, src: T) -> T; /// Maximum with the current value using an unsigned comparison. +/// `T` must be an unsigned integer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] unsigned integer types via the `fetch_max` method by passing @@ -878,6 +1026,7 @@ pub unsafe fn atomic_umax_seqcst(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_umax_acquire(dst: *mut T, src: T) -> T; /// Maximum with the current value using an unsigned comparison. +/// `T` must be an unsigned integer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] unsigned integer types via the `fetch_max` method by passing @@ -886,6 +1035,7 @@ pub unsafe fn atomic_umax_acquire(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_umax_release(dst: *mut T, src: T) -> T; /// Maximum with the current value using an unsigned comparison. +/// `T` must be an unsigned integer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] unsigned integer types via the `fetch_max` method by passing @@ -894,6 +1044,7 @@ pub unsafe fn atomic_umax_release(dst: *mut T, src: T) -> T; #[rustc_nounwind] pub unsafe fn atomic_umax_acqrel(dst: *mut T, src: T) -> T; /// Maximum with the current value using an unsigned comparison. +/// `T` must be an unsigned integer type. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] unsigned integer types via the `fetch_max` method by passing @@ -1627,10 +1778,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 `_count` or `size_of::()` 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); @@ -1649,10 +1804,13 @@ pub unsafe fn volatile_copy_memory(dst: *mut T, src: *const T, count: usize); /// 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 `_count` or `size_of::()` 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); @@ -3194,8 +3352,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 both contain values of type `T`. +/// +/// [valid]: crate::ptr#safety #[rustc_nounwind] #[inline] #[rustc_intrinsic] @@ -3344,7 +3512,6 @@ pub unsafe fn vtable_size(_ptr: *const ()) -> usize; // function used to have a dummy body, but no longer has since // https://github.com/rust-lang/rust/pull/137489 has been merged). // #[requires(ub_checks::can_dereference(_ptr as *const [usize; 3]))] -// #[requires(ub_checks::can_dereference(_ptr as *const [usize; 3]))] pub unsafe fn vtable_align(_ptr: *const ()) -> usize; /// The size of a type in bytes. 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 10ae43ac3fcd5..075da02285449 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, @@ -1972,11 +1972,20 @@ 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, { + // 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) } @@ -3367,7 +3376,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, @@ -3415,7 +3424,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 0e250193cace8..74e301dc132a9 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", @@ -228,15 +215,11 @@ extern crate self as core; #[prelude_import] #[allow(unused)] -use prelude::rust_2021::*; +use prelude::rust_2024::*; -#[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 a527a2ea5aada..fa0d882181a51 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 e234f105b0b76..68011310d2cad 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" @@ -465,9 +465,13 @@ impl Copy for &T {} /// Notably, this doesn't include all trivially-destructible types for semver /// reasons. /// -/// Bikeshed name for now. +/// Bikeshed name for now. This trait does not do anything other than reflect the +/// set of types that are allowed within unions for field validity. #[unstable(feature = "bikeshed_guaranteed_no_drop", issue = "none")] #[lang = "bikeshed_guaranteed_no_drop"] +#[rustc_deny_explicit_impl] +#[rustc_do_not_implement_via_object] +#[doc(hidden)] pub trait BikeshedGuaranteedNoDrop {} /// Types for which it is safe to share references between threads. @@ -541,7 +545,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( @@ -1301,7 +1305,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 4900d5e0c0ac1..a1fe1e9e2b5d4 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -142,7 +142,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); } @@ -302,7 +302,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::() } @@ -330,7 +330,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) } @@ -850,7 +850,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 @@ -860,8 +860,13 @@ pub const fn replace(dest: &mut T, src: T) -> T { // such that the old value is not duplicated. Nothing is dropped and // nothing here can panic. unsafe { - let result = ptr::read(dest); - ptr::write(dest, src); + // Ideally we wouldn't use the intrinsics here, but going through the + // `ptr` methods introduces two unnecessary UbChecks, so until we can + // remove those for pointers that come from references, this uses the + // intrinsics instead so this stays very cheap in MIR (and debug). + + let result = crate::intrinsics::read_via_copy(dest); + crate::intrinsics::write_via_move(dest, src); result } } @@ -930,7 +935,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. @@ -1153,7 +1158,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)) @@ -1253,42 +1258,56 @@ 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. -/// -/// Nested field accesses may be used, but not array indexes. +/// The type may be a `struct`, `enum`, `union`, or tuple. /// -/// If the nightly-only feature `offset_of_enum` is enabled, -/// variants may be traversed as if they were fields. -/// Variants themselves do not have an offset. +/// The field may be a nested field (`field1.field2`), but not an array index. +/// The field must be visible to the call site. /// -/// Visibility is respected - all types and fields must be visible to the call site: +/// The offset is returned as a [`usize`]. /// -/// ``` -/// 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]. @@ -1324,11 +1343,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 { @@ -1350,18 +1374,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/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/net/socket_addr.rs b/library/core/src/net/socket_addr.rs index 57f47e66e81e7..21753d0092497 100644 --- a/library/core/src/net/socket_addr.rs +++ b/library/core/src/net/socket_addr.rs @@ -8,11 +8,15 @@ use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr}; /// as possibly some version-dependent additional information. See [`SocketAddrV4`]'s and /// [`SocketAddrV6`]'s respective documentation for more details. /// -/// The size of a `SocketAddr` instance may vary depending on the target operating -/// system. -/// /// [IP address]: IpAddr /// +/// # Portability +/// +/// `SocketAddr` is intended to be a portable representation of socket addresses and is likely not +/// the same as the internal socket address type used by the target operating system's API. Like all +/// `repr(Rust)` structs, however, its exact layout remains undefined and should not be relied upon +/// between builds. +/// /// # Examples /// /// ``` @@ -42,13 +46,16 @@ pub enum SocketAddr { /// /// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses. /// -/// The size of a `SocketAddrV4` struct may vary depending on the target operating -/// system. Do not assume that this type has the same memory layout as the underlying -/// system representation. -/// /// [IETF RFC 793]: https://tools.ietf.org/html/rfc793 /// [`IPv4` address]: Ipv4Addr /// +/// # Portability +/// +/// `SocketAddrV4` is intended to be a portable representation of socket addresses and is likely not +/// the same as the internal socket address type used by the target operating system's API. Like all +/// `repr(Rust)` structs, however, its exact layout remains undefined and should not be relied upon +/// between builds. +/// /// # Textual representation /// /// `SocketAddrV4` provides a [`FromStr`](crate::str::FromStr) implementation. @@ -84,13 +91,16 @@ pub struct SocketAddrV4 { /// /// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses. /// -/// The size of a `SocketAddrV6` struct may vary depending on the target operating -/// system. Do not assume that this type has the same memory layout as the underlying -/// system representation. -/// /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3 /// [`IPv6` address]: Ipv6Addr /// +/// # Portability +/// +/// `SocketAddrV6` is intended to be a portable representation of socket addresses and is likely not +/// the same as the internal socket address type used by the target operating system's API. Like all +/// `repr(Rust)` structs, however, its exact layout remains undefined and should not be relied upon +/// between builds. +/// /// # Textual representation /// /// `SocketAddrV6` provides a [`FromStr`](crate::str::FromStr) implementation, diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 9a1db8f289a75..325fa4b357ed8 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -14,15 +14,14 @@ use safety::requires; use crate::convert::FloatToInt; -#[cfg(not(test))] -use crate::intrinsics; #[cfg(kani)] use crate::kani; -use crate::mem; use crate::num::FpCategory; use crate::panic::const_assert; #[allow(unused_imports)] use crate::ub_checks::float_to_int_in_range; +use crate::{intrinsics, mem}; + /// Basic mathematical constants. #[unstable(feature = "f128", issue = "116909")] pub mod consts { @@ -143,7 +142,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 d33e7255f416d..9583742322659 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -14,15 +14,14 @@ use safety::requires; use crate::convert::FloatToInt; -#[cfg(not(test))] -use crate::intrinsics; #[cfg(kani)] use crate::kani; -use crate::mem; use crate::num::FpCategory; use crate::panic::const_assert; #[allow(unused_imports)] use crate::ub_checks::float_to_int_in_range; +use crate::{intrinsics, mem}; + /// Basic mathematical constants. #[unstable(feature = "f16", issue = "116909")] pub mod consts { @@ -138,7 +137,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 33b84535fb62a..39897fbf1da9c 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -14,15 +14,13 @@ use safety::requires; use crate::convert::FloatToInt; -#[cfg(not(test))] -use crate::intrinsics; #[cfg(kani)] use crate::kani; -use crate::mem; use crate::num::FpCategory; use crate::panic::const_assert; #[allow(unused_imports)] use crate::ub_checks::float_to_int_in_range; +use crate::{intrinsics, mem}; /// The radix or base of the internal representation of `f32`. /// Use [`f32::RADIX`] instead. @@ -392,7 +390,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")] @@ -422,7 +419,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 759869d1bb98d..f54ba1a0a6d9f 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -14,15 +14,13 @@ use safety::requires; use crate::convert::FloatToInt; -#[cfg(not(test))] -use crate::intrinsics; #[cfg(kani)] use crate::kani; -use crate::mem; use crate::num::FpCategory; use crate::panic::const_assert; #[allow(unused_imports)] use crate::ub_checks::float_to_int_in_range; +use crate::{intrinsics, mem}; /// The radix or base of the internal representation of `f64`. /// Use [`f64::RADIX`] instead. @@ -392,7 +390,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")] @@ -421,7 +418,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 d74d8519ecb41..cbf46937f7991 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/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index a2dfd6e4d5830..8f7d644dbbf39 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -197,7 +197,6 @@ impl *const T { /// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API. /// /// [`with_exposed_provenance`]: with_exposed_provenance - #[must_use] #[inline(always)] #[stable(feature = "exposed_provenance", since = "1.84.0")] pub fn expose_provenance(self) -> usize { diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index 4870750638957..9c5da306e27a7 100644 --- a/library/core/src/ptr/metadata.rs +++ b/library/core/src/ptr/metadata.rs @@ -61,6 +61,8 @@ pub trait Pointee { // NOTE: Keep trait bounds in `static_assert_expected_bounds_for_metadata` // in `library/core/src/ptr/metadata.rs` // in sync with those here: + // NOTE: The metadata of `dyn Trait + 'a` is `DynMetadata` + // so a `'static` bound must not be added. type Metadata: fmt::Debug + Copy + Send + Sync + Ord + Hash + Unpin + Freeze; } diff --git a/library/core/src/result.rs b/library/core/src/result.rs index ee98a47523fef..48ab9267f216c 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 936df493cf1c6..b14348ba986ab 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -9,7 +9,6 @@ use crate::intrinsics::const_eval_select; use crate::kani; 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/cmp.rs b/library/core/src/slice/cmp.rs index 804bdfcbb4fc7..da85f42926e6b 100644 --- a/library/core/src/slice/cmp.rs +++ b/library/core/src/slice/cmp.rs @@ -282,4 +282,4 @@ macro_rules! impl_slice_contains { }; } -impl_slice_contains!(u16, u32, u64, i16, i32, i64, f32, f64, usize, isize); +impl_slice_contains!(u16, u32, u64, i16, i32, i64, f32, f64, usize, isize, char); diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 3570d8d087660..2c699ee9fdd4c 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) } @@ -4844,7 +4843,6 @@ impl [[T; N]] { } } -#[cfg(not(test))] impl [f32] { /// Sorts the slice of floats. /// @@ -4873,7 +4871,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/str/pattern.rs b/library/core/src/str/pattern.rs index 1380b849917cf..a85bc95e73d3c 100644 --- a/library/core/src/str/pattern.rs +++ b/library/core/src/str/pattern.rs @@ -649,21 +649,21 @@ where impl MultiCharEq for [char; N] { #[inline] fn matches(&mut self, c: char) -> bool { - self.iter().any(|&m| m == c) + self.contains(&c) } } impl MultiCharEq for &[char; N] { #[inline] fn matches(&mut self, c: char) -> bool { - self.iter().any(|&m| m == c) + self.contains(&c) } } impl MultiCharEq for &[char] { #[inline] fn matches(&mut self, c: char) -> bool { - self.iter().any(|&m| m == c) + self.contains(&c) } } diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 54a65c8459e96..88bee62203101 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -295,7 +295,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)))] @@ -3446,7 +3446,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, @@ -3465,7 +3465,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, @@ -3484,7 +3484,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, @@ -3503,7 +3503,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, @@ -3522,7 +3522,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, @@ -3541,7 +3541,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, @@ -3560,7 +3560,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, @@ -3579,7 +3579,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, @@ -3598,7 +3598,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, @@ -3617,7 +3617,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, @@ -3640,7 +3640,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, @@ -3659,7 +3659,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 766adc15e6e7b..c0d67cc51edf5 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -89,7 +89,7 @@ impl Invariant for Nanoseconds { /// 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"] #[derive(Invariant)] pub struct Duration { secs: u64, diff --git a/library/core/src/unit.rs b/library/core/src/unit.rs index d656005f3d42d..d54816c444bc4 100644 --- a/library/core/src/unit.rs +++ b/library/core/src/unit.rs @@ -17,3 +17,19 @@ impl FromIterator<()> for () { iter.into_iter().for_each(|()| {}) } } + +pub(crate) trait IsUnit { + fn is_unit() -> bool; +} + +impl IsUnit for T { + default fn is_unit() -> bool { + false + } +} + +impl IsUnit for () { + fn is_unit() -> bool { + true + } +} diff --git a/library/coretests/Cargo.toml b/library/coretests/Cargo.toml index e44f01d347b3d..88a7e159c956b 100644 --- a/library/coretests/Cargo.toml +++ b/library/coretests/Cargo.toml @@ -25,3 +25,4 @@ test = true [dev-dependencies] rand = { version = "0.9.0", default-features = false } rand_xorshift = { version = "0.4.0", default-features = false } +regex = { version = "1.11.1", default-features = false } diff --git a/library/coretests/tests/fmt/mod.rs b/library/coretests/tests/fmt/mod.rs index 025c69c4f6236..cb185dae9de35 100644 --- a/library/coretests/tests/fmt/mod.rs +++ b/library/coretests/tests/fmt/mod.rs @@ -15,8 +15,39 @@ fn test_format_flags() { fn test_pointer_formats_data_pointer() { let b: &[u8] = b""; let s: &str = ""; - assert_eq!(format!("{s:p}"), format!("{:p}", s.as_ptr())); - assert_eq!(format!("{b:p}"), format!("{:p}", b.as_ptr())); + assert_eq!(format!("{s:p}"), format!("{:p}", s as *const _)); + assert_eq!(format!("{b:p}"), format!("{:p}", b as *const _)); +} + +#[test] +fn test_fmt_debug_of_raw_pointers() { + use core::fmt::Debug; + + fn check_fmt(t: T, expected: &str) { + use std::sync::LazyLock; + + use regex::Regex; + + static ADDR_REGEX: LazyLock = + LazyLock::new(|| Regex::new(r"0x[0-9a-fA-F]+").unwrap()); + + let formatted = format!("{:?}", t); + let normalized = ADDR_REGEX.replace_all(&formatted, "$$HEX"); + + assert_eq!(normalized, expected); + } + + let plain = &mut 100; + check_fmt(plain as *mut i32, "$HEX"); + check_fmt(plain as *const i32, "$HEX"); + + let slice = &mut [200, 300, 400][..]; + check_fmt(slice as *mut [i32], "Pointer { addr: $HEX, metadata: 3 }"); + check_fmt(slice as *const [i32], "Pointer { addr: $HEX, metadata: 3 }"); + + let vtable = &mut 500 as &mut dyn Debug; + check_fmt(vtable as *mut dyn Debug, "Pointer { addr: $HEX, metadata: DynMetadata($HEX) }"); + check_fmt(vtable as *const dyn Debug, "Pointer { addr: $HEX, metadata: DynMetadata($HEX) }"); } #[test] diff --git a/library/panic_abort/Cargo.toml b/library/panic_abort/Cargo.toml index a9d1f53761cbf..6f43ac4809a32 100644 --- a/library/panic_abort/Cargo.toml +++ b/library/panic_abort/Cargo.toml @@ -4,7 +4,7 @@ version = "0.0.0" license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/rust.git" description = "Implementation of Rust panics via process aborts" -edition = "2021" +edition = "2024" [lib] test = false diff --git a/library/panic_unwind/Cargo.toml b/library/panic_unwind/Cargo.toml index c2abb79192e9f..d176434e06ba1 100644 --- a/library/panic_unwind/Cargo.toml +++ b/library/panic_unwind/Cargo.toml @@ -4,7 +4,7 @@ version = "0.0.0" license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/rust.git" description = "Implementation of Rust panics via stack unwinding" -edition = "2021" +edition = "2024" [lib] test = false diff --git a/library/proc_macro/Cargo.toml b/library/proc_macro/Cargo.toml index e54a50aa15c61..72cb4e4166f8e 100644 --- a/library/proc_macro/Cargo.toml +++ b/library/proc_macro/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "proc_macro" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] std = { path = "../std" } diff --git a/library/profiler_builtins/Cargo.toml b/library/profiler_builtins/Cargo.toml index 230e8051602e4..e075a38daea11 100644 --- a/library/profiler_builtins/Cargo.toml +++ b/library/profiler_builtins/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "profiler_builtins" version = "0.0.0" -edition = "2021" +edition = "2024" [lib] test = false diff --git a/library/rustc-std-workspace-alloc/Cargo.toml b/library/rustc-std-workspace-alloc/Cargo.toml index 049ca3e46b57d..5a177808d1bd8 100644 --- a/library/rustc-std-workspace-alloc/Cargo.toml +++ b/library/rustc-std-workspace-alloc/Cargo.toml @@ -5,7 +5,7 @@ license = 'MIT OR Apache-2.0' description = """ Hack for the compiler's own build system """ -edition = "2021" +edition = "2024" [lib] path = "lib.rs" diff --git a/library/rustc-std-workspace-core/Cargo.toml b/library/rustc-std-workspace-core/Cargo.toml index ff5cfcbd64144..9315c08a4d199 100644 --- a/library/rustc-std-workspace-core/Cargo.toml +++ b/library/rustc-std-workspace-core/Cargo.toml @@ -5,7 +5,7 @@ license = 'MIT OR Apache-2.0' description = """ Hack for the compiler's own build system """ -edition = "2021" +edition = "2024" [lib] path = "lib.rs" diff --git a/library/rustc-std-workspace-std/Cargo.toml b/library/rustc-std-workspace-std/Cargo.toml index 3a1dc2a02b557..f70994e1f8868 100644 --- a/library/rustc-std-workspace-std/Cargo.toml +++ b/library/rustc-std-workspace-std/Cargo.toml @@ -5,7 +5,7 @@ license = 'MIT OR Apache-2.0' description = """ Hack for the compiler's own build system """ -edition = "2021" +edition = "2024" [lib] path = "lib.rs" diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 79001a1969e48..56e98850e1208 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -6,7 +6,7 @@ version = "0.0.0" license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/rust.git" description = "The Rust Standard Library" -edition = "2021" +edition = "2024" autobenches = false [lib] @@ -36,7 +36,7 @@ miniz_oxide = { version = "0.8.0", optional = true, default-features = false } addr2line = { version = "0.24.0", optional = true, default-features = false } [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies] -libc = { version = "0.2.170", default-features = false, features = [ +libc = { version = "0.2.171", default-features = false, features = [ 'rustc-dep-of-std', ], public = true } diff --git a/library/std/build.rs b/library/std/build.rs index cedfd7406a1aa..a0cfbc4685ee5 100644 --- a/library/std/build.rs +++ b/library/std/build.rs @@ -42,6 +42,7 @@ fn main() { || target_os == "fuchsia" || (target_vendor == "fortanix" && target_env == "sgx") || target_os == "hermit" + || target_os == "trusty" || target_os == "l4re" || target_os == "redox" || target_os == "haiku" diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index ff4a4b35ce450..2487f5a2a503f 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -208,20 +208,32 @@ use crate::ops::Index; /// # Usage in `const` and `static` /// /// As explained above, `HashMap` is randomly seeded: each `HashMap` instance uses a different seed, -/// which means that `HashMap::new` cannot be used in const context. To construct a `HashMap` in the -/// initializer of a `const` or `static` item, you will have to use a different hasher that does not -/// involve a random seed, as demonstrated in the following example. **A `HashMap` constructed this -/// way is not resistant against HashDoS!** +/// which means that `HashMap::new` normally cannot be used in a `const` or `static` initializer. /// +/// However, if you need to use a `HashMap` in a `const` or `static` initializer while retaining +/// random seed generation, you can wrap the `HashMap` in [`LazyLock`]. +/// +/// Alternatively, you can construct a `HashMap` in a `const` or `static` initializer using a different +/// hasher that does not rely on a random seed. **Be aware that a `HashMap` created this way is not +/// resistant to HashDoS attacks!** +/// +/// [`LazyLock`]: crate::sync::LazyLock /// ```rust /// use std::collections::HashMap; /// use std::hash::{BuildHasherDefault, DefaultHasher}; -/// use std::sync::Mutex; +/// use std::sync::{LazyLock, Mutex}; /// -/// const EMPTY_MAP: HashMap, BuildHasherDefault> = +/// // HashMaps with a fixed, non-random hasher +/// const NONRANDOM_EMPTY_MAP: HashMap, BuildHasherDefault> = /// HashMap::with_hasher(BuildHasherDefault::new()); -/// static MAP: Mutex, BuildHasherDefault>> = +/// static NONRANDOM_MAP: Mutex, BuildHasherDefault>> = /// Mutex::new(HashMap::with_hasher(BuildHasherDefault::new())); +/// +/// // HashMaps using LazyLock to retain random seeding +/// const RANDOM_EMPTY_MAP: LazyLock>> = +/// LazyLock::new(HashMap::new); +/// static RANDOM_MAP: LazyLock>>> = +/// LazyLock::new(|| Mutex::new(HashMap::new())); /// ``` #[cfg_attr(not(test), rustc_diagnostic_item = "HashMap")] @@ -1278,69 +1290,6 @@ where } } -impl HashMap -where - S: BuildHasher, -{ - /// Creates a raw entry builder for the `HashMap`. - /// - /// Raw entries provide the lowest level of control for searching and - /// manipulating a map. They must be manually initialized with a hash and - /// then manually searched. After this, insertions into a vacant entry - /// still require an owned key to be provided. - /// - /// Raw entries are useful for such exotic situations as: - /// - /// * Hash memoization - /// * Deferring the creation of an owned key until it is known to be required - /// * Using a search key that doesn't work with the Borrow trait - /// * Using custom comparison logic without newtype wrappers - /// - /// Because raw entries provide much more low-level control, it's much easier - /// to put the `HashMap` into an inconsistent state which, while memory-safe, - /// will cause the map to produce seemingly random results. Higher-level and - /// more foolproof APIs like `entry` should be preferred when possible. - /// - /// In particular, the hash used to initialize the raw entry must still be - /// consistent with the hash of the key that is ultimately stored in the entry. - /// This is because implementations of `HashMap` may need to recompute hashes - /// when resizing, at which point only the keys are available. - /// - /// Raw entries give mutable access to the keys. This must not be used - /// to modify how the key would compare or hash, as the map will not re-evaluate - /// where the key should go, meaning the keys may become "lost" if their - /// location does not reflect their state. For instance, if you change a key - /// so that the map now contains keys which compare equal, search may start - /// acting erratically, with two keys randomly masking each other. Implementations - /// are free to assume this doesn't happen (within the limits of memory-safety). - #[inline] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn raw_entry_mut(&mut self) -> RawEntryBuilderMut<'_, K, V, S> { - RawEntryBuilderMut { map: self } - } - - /// Creates a raw immutable entry builder for the `HashMap`. - /// - /// Raw entries provide the lowest level of control for searching and - /// manipulating a map. They must be manually initialized with a hash and - /// then manually searched. - /// - /// This is useful for - /// * Hash memoization - /// * Using a search key that doesn't work with the Borrow trait - /// * Using custom comparison logic without newtype wrappers - /// - /// Unless you are in such a situation, higher-level and more foolproof APIs like - /// `get` should be preferred. - /// - /// Immutable raw entries have very limited use; you might instead want `raw_entry_mut`. - #[inline] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn raw_entry(&self) -> RawEntryBuilder<'_, K, V, S> { - RawEntryBuilder { map: self } - } -} - #[stable(feature = "rust1", since = "1.0.0")] impl Clone for HashMap where @@ -1828,404 +1777,6 @@ impl Default for IntoValues { } } -/// A builder for computing where in a HashMap a key-value pair would be stored. -/// -/// See the [`HashMap::raw_entry_mut`] docs for usage examples. -#[unstable(feature = "hash_raw_entry", issue = "56167")] -pub struct RawEntryBuilderMut<'a, K: 'a, V: 'a, S: 'a> { - map: &'a mut HashMap, -} - -/// A view into a single entry in a map, which may either be vacant or occupied. -/// -/// This is a lower-level version of [`Entry`]. -/// -/// This `enum` is constructed through the [`raw_entry_mut`] method on [`HashMap`], -/// then calling one of the methods of that [`RawEntryBuilderMut`]. -/// -/// [`raw_entry_mut`]: HashMap::raw_entry_mut -#[unstable(feature = "hash_raw_entry", issue = "56167")] -pub enum RawEntryMut<'a, K: 'a, V: 'a, S: 'a> { - /// An occupied entry. - Occupied(RawOccupiedEntryMut<'a, K, V, S>), - /// A vacant entry. - Vacant(RawVacantEntryMut<'a, K, V, S>), -} - -/// A view into an occupied entry in a `HashMap`. -/// It is part of the [`RawEntryMut`] enum. -#[unstable(feature = "hash_raw_entry", issue = "56167")] -pub struct RawOccupiedEntryMut<'a, K: 'a, V: 'a, S: 'a> { - base: base::RawOccupiedEntryMut<'a, K, V, S>, -} - -/// A view into a vacant entry in a `HashMap`. -/// It is part of the [`RawEntryMut`] enum. -#[unstable(feature = "hash_raw_entry", issue = "56167")] -pub struct RawVacantEntryMut<'a, K: 'a, V: 'a, S: 'a> { - base: base::RawVacantEntryMut<'a, K, V, S>, -} - -/// A builder for computing where in a HashMap a key-value pair would be stored. -/// -/// See the [`HashMap::raw_entry`] docs for usage examples. -#[unstable(feature = "hash_raw_entry", issue = "56167")] -pub struct RawEntryBuilder<'a, K: 'a, V: 'a, S: 'a> { - map: &'a HashMap, -} - -impl<'a, K, V, S> RawEntryBuilderMut<'a, K, V, S> -where - S: BuildHasher, -{ - /// Creates a `RawEntryMut` from the given key. - #[inline] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn from_key(self, k: &Q) -> RawEntryMut<'a, K, V, S> - where - K: Borrow, - Q: Hash + Eq, - { - map_raw_entry(self.map.base.raw_entry_mut().from_key(k)) - } - - /// Creates a `RawEntryMut` from the given key and its hash. - #[inline] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn from_key_hashed_nocheck(self, hash: u64, k: &Q) -> RawEntryMut<'a, K, V, S> - where - K: Borrow, - Q: Eq, - { - map_raw_entry(self.map.base.raw_entry_mut().from_key_hashed_nocheck(hash, k)) - } - - /// Creates a `RawEntryMut` from the given hash. - #[inline] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn from_hash(self, hash: u64, is_match: F) -> RawEntryMut<'a, K, V, S> - where - for<'b> F: FnMut(&'b K) -> bool, - { - map_raw_entry(self.map.base.raw_entry_mut().from_hash(hash, is_match)) - } -} - -impl<'a, K, V, S> RawEntryBuilder<'a, K, V, S> -where - S: BuildHasher, -{ - /// Access an entry by key. - #[inline] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn from_key(self, k: &Q) -> Option<(&'a K, &'a V)> - where - K: Borrow, - Q: Hash + Eq, - { - self.map.base.raw_entry().from_key(k) - } - - /// Access an entry by a key and its hash. - #[inline] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn from_key_hashed_nocheck(self, hash: u64, k: &Q) -> Option<(&'a K, &'a V)> - where - K: Borrow, - Q: Hash + Eq, - { - self.map.base.raw_entry().from_key_hashed_nocheck(hash, k) - } - - /// Access an entry by hash. - #[inline] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn from_hash(self, hash: u64, is_match: F) -> Option<(&'a K, &'a V)> - where - F: FnMut(&K) -> bool, - { - self.map.base.raw_entry().from_hash(hash, is_match) - } -} - -impl<'a, K, V, S> RawEntryMut<'a, K, V, S> { - /// Ensures a value is in the entry by inserting the default if empty, and returns - /// mutable references to the key and value in the entry. - /// - /// # Examples - /// - /// ``` - /// #![feature(hash_raw_entry)] - /// use std::collections::HashMap; - /// - /// let mut map: HashMap<&str, u32> = HashMap::new(); - /// - /// map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 3); - /// assert_eq!(map["poneyland"], 3); - /// - /// *map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 10).1 *= 2; - /// assert_eq!(map["poneyland"], 6); - /// ``` - #[inline] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn or_insert(self, default_key: K, default_val: V) -> (&'a mut K, &'a mut V) - where - K: Hash, - S: BuildHasher, - { - match self { - RawEntryMut::Occupied(entry) => entry.into_key_value(), - RawEntryMut::Vacant(entry) => entry.insert(default_key, default_val), - } - } - - /// Ensures a value is in the entry by inserting the result of the default function if empty, - /// and returns mutable references to the key and value in the entry. - /// - /// # Examples - /// - /// ``` - /// #![feature(hash_raw_entry)] - /// use std::collections::HashMap; - /// - /// let mut map: HashMap<&str, String> = HashMap::new(); - /// - /// map.raw_entry_mut().from_key("poneyland").or_insert_with(|| { - /// ("poneyland", "hoho".to_string()) - /// }); - /// - /// assert_eq!(map["poneyland"], "hoho".to_string()); - /// ``` - #[inline] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn or_insert_with(self, default: F) -> (&'a mut K, &'a mut V) - where - F: FnOnce() -> (K, V), - K: Hash, - S: BuildHasher, - { - match self { - RawEntryMut::Occupied(entry) => entry.into_key_value(), - RawEntryMut::Vacant(entry) => { - let (k, v) = default(); - entry.insert(k, v) - } - } - } - - /// Provides in-place mutable access to an occupied entry before any - /// potential inserts into the map. - /// - /// # Examples - /// - /// ``` - /// #![feature(hash_raw_entry)] - /// use std::collections::HashMap; - /// - /// let mut map: HashMap<&str, u32> = HashMap::new(); - /// - /// map.raw_entry_mut() - /// .from_key("poneyland") - /// .and_modify(|_k, v| { *v += 1 }) - /// .or_insert("poneyland", 42); - /// assert_eq!(map["poneyland"], 42); - /// - /// map.raw_entry_mut() - /// .from_key("poneyland") - /// .and_modify(|_k, v| { *v += 1 }) - /// .or_insert("poneyland", 0); - /// assert_eq!(map["poneyland"], 43); - /// ``` - #[inline] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn and_modify(self, f: F) -> Self - where - F: FnOnce(&mut K, &mut V), - { - match self { - RawEntryMut::Occupied(mut entry) => { - { - let (k, v) = entry.get_key_value_mut(); - f(k, v); - } - RawEntryMut::Occupied(entry) - } - RawEntryMut::Vacant(entry) => RawEntryMut::Vacant(entry), - } - } -} - -impl<'a, K, V, S> RawOccupiedEntryMut<'a, K, V, S> { - /// Gets a reference to the key in the entry. - #[inline] - #[must_use] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn key(&self) -> &K { - self.base.key() - } - - /// Gets a mutable reference to the key in the entry. - #[inline] - #[must_use] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn key_mut(&mut self) -> &mut K { - self.base.key_mut() - } - - /// Converts the entry into a mutable reference to the key in the entry - /// with a lifetime bound to the map itself. - #[inline] - #[must_use = "`self` will be dropped if the result is not used"] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn into_key(self) -> &'a mut K { - self.base.into_key() - } - - /// Gets a reference to the value in the entry. - #[inline] - #[must_use] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn get(&self) -> &V { - self.base.get() - } - - /// Converts the `OccupiedEntry` into a mutable reference to the value in the entry - /// with a lifetime bound to the map itself. - #[inline] - #[must_use = "`self` will be dropped if the result is not used"] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn into_mut(self) -> &'a mut V { - self.base.into_mut() - } - - /// Gets a mutable reference to the value in the entry. - #[inline] - #[must_use] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn get_mut(&mut self) -> &mut V { - self.base.get_mut() - } - - /// Gets a reference to the key and value in the entry. - #[inline] - #[must_use] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn get_key_value(&mut self) -> (&K, &V) { - self.base.get_key_value() - } - - /// Gets a mutable reference to the key and value in the entry. - #[inline] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn get_key_value_mut(&mut self) -> (&mut K, &mut V) { - self.base.get_key_value_mut() - } - - /// Converts the `OccupiedEntry` into a mutable reference to the key and value in the entry - /// with a lifetime bound to the map itself. - #[inline] - #[must_use = "`self` will be dropped if the result is not used"] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn into_key_value(self) -> (&'a mut K, &'a mut V) { - self.base.into_key_value() - } - - /// Sets the value of the entry, and returns the entry's old value. - #[inline] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn insert(&mut self, value: V) -> V { - self.base.insert(value) - } - - /// Sets the value of the entry, and returns the entry's old value. - #[inline] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn insert_key(&mut self, key: K) -> K { - self.base.insert_key(key) - } - - /// Takes the value out of the entry, and returns it. - #[inline] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn remove(self) -> V { - self.base.remove() - } - - /// Take the ownership of the key and value from the map. - #[inline] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn remove_entry(self) -> (K, V) { - self.base.remove_entry() - } -} - -impl<'a, K, V, S> RawVacantEntryMut<'a, K, V, S> { - /// Sets the value of the entry with the `VacantEntry`'s key, - /// and returns a mutable reference to it. - #[inline] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn insert(self, key: K, value: V) -> (&'a mut K, &'a mut V) - where - K: Hash, - S: BuildHasher, - { - self.base.insert(key, value) - } - - /// Sets the value of the entry with the VacantEntry's key, - /// and returns a mutable reference to it. - #[inline] - #[unstable(feature = "hash_raw_entry", issue = "56167")] - pub fn insert_hashed_nocheck(self, hash: u64, key: K, value: V) -> (&'a mut K, &'a mut V) - where - K: Hash, - S: BuildHasher, - { - self.base.insert_hashed_nocheck(hash, key, value) - } -} - -#[unstable(feature = "hash_raw_entry", issue = "56167")] -impl Debug for RawEntryBuilderMut<'_, K, V, S> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("RawEntryBuilder").finish_non_exhaustive() - } -} - -#[unstable(feature = "hash_raw_entry", issue = "56167")] -impl Debug for RawEntryMut<'_, K, V, S> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - RawEntryMut::Vacant(ref v) => f.debug_tuple("RawEntry").field(v).finish(), - RawEntryMut::Occupied(ref o) => f.debug_tuple("RawEntry").field(o).finish(), - } - } -} - -#[unstable(feature = "hash_raw_entry", issue = "56167")] -impl Debug for RawOccupiedEntryMut<'_, K, V, S> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("RawOccupiedEntryMut") - .field("key", self.key()) - .field("value", self.get()) - .finish_non_exhaustive() - } -} - -#[unstable(feature = "hash_raw_entry", issue = "56167")] -impl Debug for RawVacantEntryMut<'_, K, V, S> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("RawVacantEntryMut").finish_non_exhaustive() - } -} - -#[unstable(feature = "hash_raw_entry", issue = "56167")] -impl Debug for RawEntryBuilder<'_, K, V, S> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("RawEntryBuilder").finish_non_exhaustive() - } -} - /// A view into a single entry in a map, which may either be vacant or occupied. /// /// This `enum` is constructed from the [`entry`] method on [`HashMap`]. @@ -3298,16 +2849,6 @@ pub(super) fn map_try_reserve_error(err: hashbrown::TryReserveError) -> TryReser } } -#[inline] -fn map_raw_entry<'a, K: 'a, V: 'a, S: 'a>( - raw: base::RawEntryMut<'a, K, V, S>, -) -> RawEntryMut<'a, K, V, S> { - match raw { - base::RawEntryMut::Occupied(base) => RawEntryMut::Occupied(RawOccupiedEntryMut { base }), - base::RawEntryMut::Vacant(base) => RawEntryMut::Vacant(RawVacantEntryMut { base }), - } -} - #[allow(dead_code)] fn assert_covariance() { fn map_key<'new>(v: HashMap<&'static str, u8>) -> HashMap<&'new str, u8> { diff --git a/library/std/src/collections/hash/map/tests.rs b/library/std/src/collections/hash/map/tests.rs index a275488a55602..9f7df20a1d7e4 100644 --- a/library/std/src/collections/hash/map/tests.rs +++ b/library/std/src/collections/hash/map/tests.rs @@ -852,99 +852,6 @@ fn test_try_reserve() { } } -#[test] -fn test_raw_entry() { - use super::RawEntryMut::{Occupied, Vacant}; - - let xs = [(1i32, 10i32), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)]; - - let mut map: HashMap<_, _> = xs.iter().cloned().collect(); - - let compute_hash = |map: &HashMap, k: i32| -> u64 { - use core::hash::{BuildHasher, Hash, Hasher}; - - let mut hasher = map.hasher().build_hasher(); - k.hash(&mut hasher); - hasher.finish() - }; - - // Existing key (insert) - match map.raw_entry_mut().from_key(&1) { - Vacant(_) => unreachable!(), - Occupied(mut view) => { - assert_eq!(view.get(), &10); - assert_eq!(view.insert(100), 10); - } - } - let hash1 = compute_hash(&map, 1); - assert_eq!(map.raw_entry().from_key(&1).unwrap(), (&1, &100)); - assert_eq!(map.raw_entry().from_hash(hash1, |k| *k == 1).unwrap(), (&1, &100)); - assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash1, &1).unwrap(), (&1, &100)); - assert_eq!(map.len(), 6); - - // Existing key (update) - match map.raw_entry_mut().from_key(&2) { - Vacant(_) => unreachable!(), - Occupied(mut view) => { - let v = view.get_mut(); - let new_v = (*v) * 10; - *v = new_v; - } - } - let hash2 = compute_hash(&map, 2); - assert_eq!(map.raw_entry().from_key(&2).unwrap(), (&2, &200)); - assert_eq!(map.raw_entry().from_hash(hash2, |k| *k == 2).unwrap(), (&2, &200)); - assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash2, &2).unwrap(), (&2, &200)); - assert_eq!(map.len(), 6); - - // Existing key (take) - let hash3 = compute_hash(&map, 3); - match map.raw_entry_mut().from_key_hashed_nocheck(hash3, &3) { - Vacant(_) => unreachable!(), - Occupied(view) => { - assert_eq!(view.remove_entry(), (3, 30)); - } - } - assert_eq!(map.raw_entry().from_key(&3), None); - assert_eq!(map.raw_entry().from_hash(hash3, |k| *k == 3), None); - assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash3, &3), None); - assert_eq!(map.len(), 5); - - // Nonexistent key (insert) - match map.raw_entry_mut().from_key(&10) { - Occupied(_) => unreachable!(), - Vacant(view) => { - assert_eq!(view.insert(10, 1000), (&mut 10, &mut 1000)); - } - } - assert_eq!(map.raw_entry().from_key(&10).unwrap(), (&10, &1000)); - assert_eq!(map.len(), 6); - - // Ensure all lookup methods produce equivalent results. - for k in 0..12 { - let hash = compute_hash(&map, k); - let v = map.get(&k).cloned(); - let kv = v.as_ref().map(|v| (&k, v)); - - assert_eq!(map.raw_entry().from_key(&k), kv); - assert_eq!(map.raw_entry().from_hash(hash, |q| *q == k), kv); - assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &k), kv); - - match map.raw_entry_mut().from_key(&k) { - Occupied(mut o) => assert_eq!(Some(o.get_key_value()), kv), - Vacant(_) => assert_eq!(v, None), - } - match map.raw_entry_mut().from_key_hashed_nocheck(hash, &k) { - Occupied(mut o) => assert_eq!(Some(o.get_key_value()), kv), - Vacant(_) => assert_eq!(v, None), - } - match map.raw_entry_mut().from_hash(hash, |q| *q == k) { - Occupied(mut o) => assert_eq!(Some(o.get_key_value()), kv), - Vacant(_) => assert_eq!(v, None), - } - } -} - mod test_extract_if { use super::*; use crate::panic::{AssertUnwindSafe, catch_unwind}; diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 46b5860123fc1..f9a360585e852 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -14,7 +14,8 @@ target_os = "emscripten", target_os = "wasi", target_env = "sgx", - target_os = "xous" + target_os = "xous", + target_os = "trusty", )) ))] mod tests; diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs index 697fb5974a3dd..40441dc057d0d 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 diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 5aa048c4cbc85..8472f90305007 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -373,8 +373,8 @@ pub enum ErrorKind { TooManyLinks, /// A filename was invalid. /// - /// This error can also cause if it exceeded the filename length limit. - #[unstable(feature = "io_error_more", issue = "86442")] + /// This error can also occur if a length limit for a name was exceeded. + #[stable(feature = "io_error_invalid_filename", since = "CURRENT_RUSTC_VERSION")] InvalidFilename, /// Program argument list too long. /// diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs index f64f034cce779..fd962b0415c7d 100644 --- a/library/std/src/io/tests.rs +++ b/library/std/src/io/tests.rs @@ -811,13 +811,17 @@ fn read_to_end_error() { } #[test] -// Miri does not support signalling OOM -#[cfg_attr(miri, ignore)] -// 64-bit only to be sure the allocator will fail fast on an impossible to satisfy size -#[cfg(target_pointer_width = "64")] fn try_oom_error() { - let mut v = Vec::::new(); - let reserve_err = v.try_reserve(isize::MAX as usize - 1).unwrap_err(); + use alloc::alloc::Layout; + use alloc::collections::{TryReserveError, TryReserveErrorKind}; + + // We simulate a `Vec::try_reserve` error rather than attempting a huge size for real. This way + // we're not subject to the whims of optimization that might skip the actual allocation, and it + // also works for 32-bit targets and miri that might not OOM at all. + let layout = Layout::new::(); + let kind = TryReserveErrorKind::AllocError { layout, non_exhaustive: () }; + let reserve_err = TryReserveError::from(kind); + let io_err = io::Error::from(reserve_err); assert_eq!(io::ErrorKind::OutOfMemory, io_err.kind()); } diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs index 5ac3dbc3e9852..c07c391892d80 100644 --- a/library/std/src/keyword_docs.rs +++ b/library/std/src/keyword_docs.rs @@ -1064,7 +1064,7 @@ mod move_keyword {} /// ```rust,compile_fail,E0502 /// let mut v = vec![0, 1]; /// let mut_ref_v = &mut v; -/// ##[allow(unused)] +/// # #[allow(unused)] /// let ref_v = &v; /// mut_ref_v.push(2); /// ``` diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 104637496276e..101a7565ca6b7 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -174,7 +174,9 @@ //! //! - after-main use of thread-locals, which also affects additional features: //! - [`thread::current()`] -//! - before-main stdio file descriptors are not guaranteed to be open on unix platforms +//! - under UNIX, before main, file descriptors 0, 1, and 2 may be unchanged +//! (they are guaranteed to be open during main, +//! and are opened to /dev/null O_RDWR if they weren't open on program start) //! //! //! [I/O]: io @@ -667,6 +669,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/src/macros.rs b/library/std/src/macros.rs index e0f9f0bb5cee4..f008d42804c08 100644 --- a/library/std/src/macros.rs +++ b/library/std/src/macros.rs @@ -41,7 +41,7 @@ macro_rules! panic { /// Use `print!` only for the primary output of your program. Use /// [`eprint!`] instead to print error and progress messages. /// -/// See [the formatting documentation in `std::fmt`](../std/fmt/index.html) +/// See the formatting documentation in [`std::fmt`](crate::fmt) /// for details of the macro argument syntax. /// /// [flush]: crate::io::Write::flush @@ -106,7 +106,7 @@ macro_rules! print { /// Use `println!` only for the primary output of your program. Use /// [`eprintln!`] instead to print error and progress messages. /// -/// See [the formatting documentation in `std::fmt`](../std/fmt/index.html) +/// See the formatting documentation in [`std::fmt`](crate::fmt) /// for details of the macro argument syntax. /// /// [`std::fmt`]: crate::fmt @@ -156,7 +156,7 @@ macro_rules! println { /// [`io::stderr`]: crate::io::stderr /// [`io::stdout`]: crate::io::stdout /// -/// See [the formatting documentation in `std::fmt`](../std/fmt/index.html) +/// See the formatting documentation in [`std::fmt`](crate::fmt) /// for details of the macro argument syntax. /// /// # Panics @@ -190,7 +190,7 @@ macro_rules! eprint { /// Use `eprintln!` only for error and progress messages. Use `println!` /// instead for the primary output of your program. /// -/// See [the formatting documentation in `std::fmt`](../std/fmt/index.html) +/// See the formatting documentation in [`std::fmt`](crate::fmt) /// for details of the macro argument syntax. /// /// [`io::stderr`]: crate::io::stderr diff --git a/library/std/src/net/tcp.rs b/library/std/src/net/tcp.rs index 9b68f872955c0..6a95142640726 100644 --- a/library/std/src/net/tcp.rs +++ b/library/std/src/net/tcp.rs @@ -5,7 +5,8 @@ not(any( target_os = "emscripten", all(target_os = "wasi", target_env = "p1"), - target_os = "xous" + target_os = "xous", + target_os = "trusty", )) ))] mod tests; diff --git a/library/std/src/net/udp.rs b/library/std/src/net/udp.rs index 3eb798ad34aaa..a97b3299774bb 100644 --- a/library/std/src/net/udp.rs +++ b/library/std/src/net/udp.rs @@ -4,7 +4,8 @@ target_os = "emscripten", all(target_os = "wasi", target_env = "p1"), target_env = "sgx", - target_os = "xous" + target_os = "xous", + target_os = "trusty", )) ))] mod tests; diff --git a/library/std/src/os/fd/mod.rs b/library/std/src/os/fd/mod.rs index 35de4860fe249..95cf4932e6e2c 100644 --- a/library/std/src/os/fd/mod.rs +++ b/library/std/src/os/fd/mod.rs @@ -13,6 +13,7 @@ mod raw; mod owned; // Implementations for `AsRawFd` etc. for network types. +#[cfg(not(target_os = "trusty"))] mod net; #[cfg(test)] diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index 5cec11ecccf1c..701cf82335757 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -4,12 +4,20 @@ #![deny(unsafe_op_in_unsafe_fn)] use super::raw::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; +#[cfg(not(target_os = "trusty"))] +use crate::fs; use crate::marker::PhantomData; use crate::mem::ManuallyDrop; -#[cfg(not(any(target_arch = "wasm32", target_env = "sgx", target_os = "hermit")))] +#[cfg(not(any( + target_arch = "wasm32", + target_env = "sgx", + target_os = "hermit", + target_os = "trusty" +)))] use crate::sys::cvt; +#[cfg(not(target_os = "trusty"))] use crate::sys_common::{AsInner, FromInner, IntoInner}; -use crate::{fmt, fs, io}; +use crate::{fmt, io}; type ValidRawFd = core::num::niche_types::NotAllOnes; @@ -87,7 +95,7 @@ impl OwnedFd { impl BorrowedFd<'_> { /// Creates a new `OwnedFd` instance that shares the same underlying file /// description as the existing `BorrowedFd` instance. - #[cfg(not(any(target_arch = "wasm32", target_os = "hermit")))] + #[cfg(not(any(target_arch = "wasm32", target_os = "hermit", target_os = "trusty")))] #[stable(feature = "io_safety", since = "1.63.0")] pub fn try_clone_to_owned(&self) -> crate::io::Result { // We want to atomically duplicate this file descriptor and set the @@ -110,7 +118,7 @@ impl BorrowedFd<'_> { /// Creates a new `OwnedFd` instance that shares the same underlying file /// description as the existing `BorrowedFd` instance. - #[cfg(any(target_arch = "wasm32", target_os = "hermit"))] + #[cfg(any(target_arch = "wasm32", target_os = "hermit", target_os = "trusty"))] #[stable(feature = "io_safety", since = "1.63.0")] pub fn try_clone_to_owned(&self) -> crate::io::Result { Err(crate::io::Error::UNSUPPORTED_PLATFORM) @@ -280,6 +288,7 @@ impl AsFd for OwnedFd { } #[stable(feature = "io_safety", since = "1.63.0")] +#[cfg(not(target_os = "trusty"))] impl AsFd for fs::File { #[inline] fn as_fd(&self) -> BorrowedFd<'_> { @@ -288,6 +297,7 @@ impl AsFd for fs::File { } #[stable(feature = "io_safety", since = "1.63.0")] +#[cfg(not(target_os = "trusty"))] impl From for OwnedFd { /// Takes ownership of a [`File`](fs::File)'s underlying file descriptor. #[inline] @@ -297,6 +307,7 @@ impl From for OwnedFd { } #[stable(feature = "io_safety", since = "1.63.0")] +#[cfg(not(target_os = "trusty"))] impl From for fs::File { /// Returns a [`File`](fs::File) that takes ownership of the given /// file descriptor. @@ -307,6 +318,7 @@ impl From for fs::File { } #[stable(feature = "io_safety", since = "1.63.0")] +#[cfg(not(target_os = "trusty"))] impl AsFd for crate::net::TcpStream { #[inline] fn as_fd(&self) -> BorrowedFd<'_> { @@ -315,6 +327,7 @@ impl AsFd for crate::net::TcpStream { } #[stable(feature = "io_safety", since = "1.63.0")] +#[cfg(not(target_os = "trusty"))] impl From for OwnedFd { /// Takes ownership of a [`TcpStream`](crate::net::TcpStream)'s socket file descriptor. #[inline] @@ -324,6 +337,7 @@ impl From for OwnedFd { } #[stable(feature = "io_safety", since = "1.63.0")] +#[cfg(not(target_os = "trusty"))] impl From for crate::net::TcpStream { #[inline] fn from(owned_fd: OwnedFd) -> Self { @@ -334,6 +348,7 @@ impl From for crate::net::TcpStream { } #[stable(feature = "io_safety", since = "1.63.0")] +#[cfg(not(target_os = "trusty"))] impl AsFd for crate::net::TcpListener { #[inline] fn as_fd(&self) -> BorrowedFd<'_> { @@ -342,6 +357,7 @@ impl AsFd for crate::net::TcpListener { } #[stable(feature = "io_safety", since = "1.63.0")] +#[cfg(not(target_os = "trusty"))] impl From for OwnedFd { /// Takes ownership of a [`TcpListener`](crate::net::TcpListener)'s socket file descriptor. #[inline] @@ -351,6 +367,7 @@ impl From for OwnedFd { } #[stable(feature = "io_safety", since = "1.63.0")] +#[cfg(not(target_os = "trusty"))] impl From for crate::net::TcpListener { #[inline] fn from(owned_fd: OwnedFd) -> Self { @@ -361,6 +378,7 @@ impl From for crate::net::TcpListener { } #[stable(feature = "io_safety", since = "1.63.0")] +#[cfg(not(target_os = "trusty"))] impl AsFd for crate::net::UdpSocket { #[inline] fn as_fd(&self) -> BorrowedFd<'_> { @@ -369,6 +387,7 @@ impl AsFd for crate::net::UdpSocket { } #[stable(feature = "io_safety", since = "1.63.0")] +#[cfg(not(target_os = "trusty"))] impl From for OwnedFd { /// Takes ownership of a [`UdpSocket`](crate::net::UdpSocket)'s file descriptor. #[inline] @@ -378,6 +397,7 @@ impl From for OwnedFd { } #[stable(feature = "io_safety", since = "1.63.0")] +#[cfg(not(target_os = "trusty"))] impl From for crate::net::UdpSocket { #[inline] fn from(owned_fd: OwnedFd) -> Self { diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs index 03dff94350dad..083ac6e3fe6b1 100644 --- a/library/std/src/os/fd/raw.rs +++ b/library/std/src/os/fd/raw.rs @@ -5,6 +5,9 @@ #[cfg(target_os = "hermit")] use hermit_abi as libc; +#[cfg(not(target_os = "trusty"))] +use crate::fs; +use crate::io; #[cfg(target_os = "hermit")] use crate::os::hermit::io::OwnedFd; #[cfg(not(target_os = "hermit"))] @@ -15,8 +18,8 @@ use crate::os::unix::io::AsFd; use crate::os::unix::io::OwnedFd; #[cfg(target_os = "wasi")] use crate::os::wasi::io::OwnedFd; +#[cfg(not(target_os = "trusty"))] use crate::sys_common::{AsInner, IntoInner}; -use crate::{fs, io}; /// Raw file descriptors. #[stable(feature = "rust1", since = "1.0.0")] @@ -161,6 +164,7 @@ impl FromRawFd for RawFd { } #[stable(feature = "rust1", since = "1.0.0")] +#[cfg(not(target_os = "trusty"))] impl AsRawFd for fs::File { #[inline] fn as_raw_fd(&self) -> RawFd { @@ -168,6 +172,7 @@ impl AsRawFd for fs::File { } } #[stable(feature = "from_raw_os", since = "1.1.0")] +#[cfg(not(target_os = "trusty"))] impl FromRawFd for fs::File { #[inline] unsafe fn from_raw_fd(fd: RawFd) -> fs::File { @@ -175,6 +180,7 @@ impl FromRawFd for fs::File { } } #[stable(feature = "into_raw_os", since = "1.4.0")] +#[cfg(not(target_os = "trusty"))] impl IntoRawFd for fs::File { #[inline] fn into_raw_fd(self) -> RawFd { @@ -183,6 +189,7 @@ impl IntoRawFd for fs::File { } #[stable(feature = "asraw_stdio", since = "1.21.0")] +#[cfg(not(target_os = "trusty"))] impl AsRawFd for io::Stdin { #[inline] fn as_raw_fd(&self) -> RawFd { @@ -207,6 +214,7 @@ impl AsRawFd for io::Stderr { } #[stable(feature = "asraw_stdio_locks", since = "1.35.0")] +#[cfg(not(target_os = "trusty"))] impl<'a> AsRawFd for io::StdinLock<'a> { #[inline] fn as_raw_fd(&self) -> RawFd { diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs index e28a1c3e6d5f4..58cbecd30e538 100644 --- a/library/std/src/os/mod.rs +++ b/library/std/src/os/mod.rs @@ -169,6 +169,8 @@ pub mod rtems; pub mod solaris; #[cfg(target_os = "solid_asp3")] pub mod solid; +#[cfg(target_os = "trusty")] +pub mod trusty; #[cfg(target_os = "uefi")] pub mod uefi; #[cfg(target_os = "vita")] @@ -178,7 +180,7 @@ pub mod vxworks; #[cfg(target_os = "xous")] pub mod xous; -#[cfg(any(unix, target_os = "hermit", target_os = "wasi", doc))] +#[cfg(any(unix, target_os = "hermit", target_os = "trusty", target_os = "wasi", doc))] pub mod fd; #[cfg(any(target_os = "linux", target_os = "android", doc))] diff --git a/library/std/src/os/trusty/io/mod.rs b/library/std/src/os/trusty/io/mod.rs new file mode 100644 index 0000000000000..4cfd448305b65 --- /dev/null +++ b/library/std/src/os/trusty/io/mod.rs @@ -0,0 +1,4 @@ +#![stable(feature = "os_fd", since = "1.66.0")] + +#[stable(feature = "os_fd", since = "1.66.0")] +pub use crate::os::fd::*; diff --git a/library/std/src/os/trusty/mod.rs b/library/std/src/os/trusty/mod.rs new file mode 100644 index 0000000000000..cc67c92d7ff47 --- /dev/null +++ b/library/std/src/os/trusty/mod.rs @@ -0,0 +1,3 @@ +#![stable(feature = "rust1", since = "1.0.0")] + +pub mod io; diff --git a/library/std/src/os/unix/fs.rs b/library/std/src/os/unix/fs.rs index 04a45fd035a55..0427feb29550f 100644 --- a/library/std/src/os/unix/fs.rs +++ b/library/std/src/os/unix/fs.rs @@ -276,63 +276,89 @@ impl FileExt for fs::File { } /// Unix-specific extensions to [`fs::Permissions`]. +/// +/// # Examples +/// +/// ```no_run +/// use std::fs::{File, Permissions}; +/// use std::io::{ErrorKind, Result as IoResult}; +/// use std::os::unix::fs::PermissionsExt; +/// +/// fn main() -> IoResult<()> { +/// let name = "test_file_for_permissions"; +/// +/// // make sure file does not exist +/// let _ = std::fs::remove_file(name); +/// assert_eq!( +/// File::open(name).unwrap_err().kind(), +/// ErrorKind::NotFound, +/// "file already exists" +/// ); +/// +/// // full read/write/execute mode bits for owner of file +/// // that we want to add to existing mode bits +/// let my_mode = 0o700; +/// +/// // create new file with specified permissions +/// { +/// let file = File::create(name)?; +/// let mut permissions = file.metadata()?.permissions(); +/// eprintln!("Current permissions: {:o}", permissions.mode()); +/// +/// // make sure new permissions are not already set +/// assert!( +/// permissions.mode() & my_mode != my_mode, +/// "permissions already set" +/// ); +/// +/// // either use `set_mode` to change an existing Permissions struct +/// permissions.set_mode(permissions.mode() | my_mode); +/// +/// // or use `from_mode` to construct a new Permissions struct +/// permissions = Permissions::from_mode(permissions.mode() | my_mode); +/// +/// // write new permissions to file +/// file.set_permissions(permissions)?; +/// } +/// +/// let permissions = File::open(name)?.metadata()?.permissions(); +/// eprintln!("New permissions: {:o}", permissions.mode()); +/// +/// // assert new permissions were set +/// assert_eq!( +/// permissions.mode() & my_mode, +/// my_mode, +/// "new permissions not set" +/// ); +/// Ok(()) +/// } +/// ``` +/// +/// ```no_run +/// use std::fs::Permissions; +/// use std::os::unix::fs::PermissionsExt; +/// +/// // read/write for owner and read for others +/// let my_mode = 0o644; +/// let mut permissions = Permissions::from_mode(my_mode); +/// assert_eq!(permissions.mode(), my_mode); +/// +/// // read/write/execute for owner +/// let other_mode = 0o700; +/// permissions.set_mode(other_mode); +/// assert_eq!(permissions.mode(), other_mode); +/// ``` #[stable(feature = "fs_ext", since = "1.1.0")] pub trait PermissionsExt { - /// Returns the underlying raw `st_mode` bits that contain the standard - /// Unix permissions for this file. - /// - /// # Examples - /// - /// ```no_run - /// use std::fs::File; - /// use std::os::unix::fs::PermissionsExt; - /// - /// fn main() -> std::io::Result<()> { - /// let f = File::create("foo.txt")?; - /// let metadata = f.metadata()?; - /// let permissions = metadata.permissions(); - /// - /// println!("permissions: {:o}", permissions.mode()); - /// Ok(()) - /// } - /// ``` + /// Returns the mode permission bits #[stable(feature = "fs_ext", since = "1.1.0")] fn mode(&self) -> u32; - /// Sets the underlying raw bits for this set of permissions. - /// - /// # Examples - /// - /// ```no_run - /// use std::fs::File; - /// use std::os::unix::fs::PermissionsExt; - /// - /// fn main() -> std::io::Result<()> { - /// let f = File::create("foo.txt")?; - /// let metadata = f.metadata()?; - /// let mut permissions = metadata.permissions(); - /// - /// permissions.set_mode(0o644); // Read/write for owner and read for others. - /// assert_eq!(permissions.mode(), 0o644); - /// Ok(()) - /// } - /// ``` + /// Sets the mode permission bits. #[stable(feature = "fs_ext", since = "1.1.0")] fn set_mode(&mut self, mode: u32); - /// Creates a new instance of `Permissions` from the given set of Unix - /// permission bits. - /// - /// # Examples - /// - /// ``` - /// use std::fs::Permissions; - /// use std::os::unix::fs::PermissionsExt; - /// - /// // Read/write for owner and read for others. - /// let permissions = Permissions::from_mode(0o644); - /// assert_eq!(permissions.mode(), 0o644); - /// ``` + /// Creates a new instance from the given mode permission bits. #[stable(feature = "fs_ext", since = "1.1.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "permissions_from_mode")] fn from_mode(mode: u32) -> Self; diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs index fa65a7c51bfa0..a084f452e55d0 100644 --- a/library/std/src/os/windows/process.rs +++ b/library/std/src/os/windows/process.rs @@ -531,7 +531,7 @@ impl<'a> ProcThreadAttributeListBuilder<'a> { /// pub Y: i16, /// } /// - /// extern "system" { + /// unsafe extern "system" { /// fn CreatePipe( /// hreadpipe: *mut HANDLE, /// hwritepipe: *mut HANDLE, diff --git a/library/std/src/path.rs b/library/std/src/path.rs index f9f3b488f0d03..980213be7ea90 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -294,11 +294,6 @@ where } } -// Detect scheme on Redox -pub(crate) fn has_redox_scheme(s: &[u8]) -> bool { - cfg!(target_os = "redox") && s.contains(&b':') -} - //////////////////////////////////////////////////////////////////////////////// // Cross-platform, iterator-independent parsing //////////////////////////////////////////////////////////////////////////////// @@ -2834,8 +2829,7 @@ impl Path { Components { path: self.as_u8_slice(), prefix, - has_physical_root: has_physical_root(self.as_u8_slice(), prefix) - || has_redox_scheme(self.as_u8_slice()), + has_physical_root: has_physical_root(self.as_u8_slice(), prefix), front: State::Prefix, back: State::Body, } diff --git a/library/std/src/process.rs b/library/std/src/process.rs index bdd4844b6511a..37762c65f6556 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -154,7 +154,8 @@ target_os = "emscripten", target_os = "wasi", target_env = "sgx", - target_os = "xous" + target_os = "xous", + target_os = "trusty", )) ))] mod tests; diff --git a/library/std/src/sys/alloc/mod.rs b/library/std/src/sys/alloc/mod.rs index 2c0b533a5703f..8489e17c971d9 100644 --- a/library/std/src/sys/alloc/mod.rs +++ b/library/std/src/sys/alloc/mod.rs @@ -72,6 +72,7 @@ cfg_if::cfg_if! { target_family = "unix", target_os = "wasi", target_os = "teeos", + target_os = "trusty", ))] { mod unix; } else if #[cfg(target_os = "windows")] { diff --git a/library/std/src/sys/pal/mod.rs b/library/std/src/sys/pal/mod.rs index 9be018c8a5312..fbefc62ac88eb 100644 --- a/library/std/src/sys/pal/mod.rs +++ b/library/std/src/sys/pal/mod.rs @@ -37,6 +37,9 @@ cfg_if::cfg_if! { } else if #[cfg(target_os = "hermit")] { mod hermit; pub use self::hermit::*; + } else if #[cfg(target_os = "trusty")] { + mod trusty; + pub use self::trusty::*; } else if #[cfg(all(target_os = "wasi", target_env = "p2"))] { mod wasip2; pub use self::wasip2::*; diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs index 301e3299c0572..3fe6dee3d6f4f 100644 --- a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs +++ b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs @@ -6,7 +6,7 @@ use super::super::mem::{is_enclave_range, is_user_range}; use crate::arch::asm; use crate::cell::UnsafeCell; use crate::convert::TryInto; -use crate::mem::{self, ManuallyDrop}; +use crate::mem::{self, ManuallyDrop, MaybeUninit}; use crate::ops::{CoerceUnsized, Deref, DerefMut, Index, IndexMut}; use crate::pin::PinCoerceUnsized; use crate::ptr::{self, NonNull}; @@ -209,6 +209,45 @@ impl NewUserRef> for NonNull> { } } +/// A type which can a destination for safely copying from userspace. +/// +/// # Safety +/// +/// Requires that `T` and `Self` have identical layouts. +#[unstable(feature = "sgx_platform", issue = "56975")] +pub unsafe trait UserSafeCopyDestination { + /// Returns a pointer for writing to the value. + fn as_mut_ptr(&mut self) -> *mut T; +} + +#[unstable(feature = "sgx_platform", issue = "56975")] +unsafe impl UserSafeCopyDestination for T { + fn as_mut_ptr(&mut self) -> *mut T { + self as _ + } +} + +#[unstable(feature = "sgx_platform", issue = "56975")] +unsafe impl UserSafeCopyDestination<[T]> for [T] { + fn as_mut_ptr(&mut self) -> *mut [T] { + self as _ + } +} + +#[unstable(feature = "sgx_platform", issue = "56975")] +unsafe impl UserSafeCopyDestination for MaybeUninit { + fn as_mut_ptr(&mut self) -> *mut T { + self as *mut Self as _ + } +} + +#[unstable(feature = "sgx_platform", issue = "56975")] +unsafe impl UserSafeCopyDestination<[T]> for [MaybeUninit] { + fn as_mut_ptr(&mut self) -> *mut [T] { + self as *mut Self as _ + } +} + #[unstable(feature = "sgx_platform", issue = "56975")] impl User where @@ -544,12 +583,12 @@ where /// # Panics /// This function panics if the destination doesn't have the same size as /// the source. This can happen for dynamically-sized types such as slices. - pub fn copy_to_enclave(&self, dest: &mut T) { + pub fn copy_to_enclave>(&self, dest: &mut U) { unsafe { assert_eq!(size_of_val(dest), size_of_val(&*self.0.get())); copy_from_userspace( self.0.get() as *const T as *const u8, - dest as *mut T as *mut u8, + dest.as_mut_ptr() as *mut u8, size_of_val(dest), ); } @@ -639,25 +678,18 @@ where unsafe { (*self.0.get()).len() } } - /// Copies the value from user memory and place it into `dest`. Afterwards, - /// `dest` will contain exactly `self.len()` elements. - /// - /// # Panics - /// This function panics if the destination doesn't have the same size as - /// the source. This can happen for dynamically-sized types such as slices. - pub fn copy_to_enclave_vec(&self, dest: &mut Vec) { - if let Some(missing) = self.len().checked_sub(dest.capacity()) { - dest.reserve(missing) - } + /// Copies the value from user memory and appends it to `dest`. + pub fn append_to_enclave_vec(&self, dest: &mut Vec) { + dest.reserve(self.len()); + self.copy_to_enclave(&mut dest.spare_capacity_mut()[..self.len()]); // SAFETY: We reserve enough space above. - unsafe { dest.set_len(self.len()) }; - self.copy_to_enclave(&mut dest[..]); + unsafe { dest.set_len(dest.len() + self.len()) }; } /// Copies the value from user memory into a vector in enclave memory. pub fn to_enclave(&self) -> Vec { let mut ret = Vec::with_capacity(self.len()); - self.copy_to_enclave_vec(&mut ret); + self.append_to_enclave_vec(&mut ret); ret } diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs b/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs index 90b9b59471a52..cbdaf439b2847 100644 --- a/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs +++ b/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs @@ -1,5 +1,7 @@ use crate::cmp; -use crate::io::{Error as IoError, ErrorKind, IoSlice, IoSliceMut, Result as IoResult}; +use crate::io::{ + BorrowedCursor, Error as IoError, ErrorKind, IoSlice, IoSliceMut, Result as IoResult, +}; use crate::random::{DefaultRandomSource, Random}; use crate::time::{Duration, Instant}; @@ -36,6 +38,19 @@ pub fn read(fd: Fd, bufs: &mut [IoSliceMut<'_>]) -> IoResult { } } +/// Usercall `read` with an uninitialized buffer. See the ABI documentation for +/// more information. +#[unstable(feature = "sgx_platform", issue = "56975")] +pub fn read_buf(fd: Fd, mut buf: BorrowedCursor<'_>) -> IoResult<()> { + unsafe { + let mut userbuf = alloc::User::<[u8]>::uninitialized(buf.capacity()); + let len = raw::read(fd, userbuf.as_mut_ptr().cast(), userbuf.len()).from_sgx_result()?; + userbuf[..len].copy_to_enclave(&mut buf.as_mut()[..len]); + buf.advance_unchecked(len); + Ok(()) + } +} + /// Usercall `read_alloc`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] pub fn read_alloc(fd: Fd) -> IoResult> { diff --git a/library/std/src/sys/pal/sgx/fd.rs b/library/std/src/sys/pal/sgx/fd.rs index 3bb3189a1d127..399f6a1648984 100644 --- a/library/std/src/sys/pal/sgx/fd.rs +++ b/library/std/src/sys/pal/sgx/fd.rs @@ -29,7 +29,7 @@ impl FileDesc { } pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> { - crate::io::default_read_buf(|b| self.read(b), buf) + usercalls::read_buf(self.fd, buf) } pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { diff --git a/library/std/src/sys/pal/trusty/mod.rs b/library/std/src/sys/pal/trusty/mod.rs new file mode 100644 index 0000000000000..7034b643d8e8e --- /dev/null +++ b/library/std/src/sys/pal/trusty/mod.rs @@ -0,0 +1,21 @@ +//! System bindings for the Trusty OS. + +#[path = "../unsupported/args.rs"] +pub mod args; +#[path = "../unsupported/common.rs"] +#[deny(unsafe_op_in_unsafe_fn)] +mod common; +#[path = "../unsupported/env.rs"] +pub mod env; +#[path = "../unsupported/os.rs"] +pub mod os; +#[path = "../unsupported/pipe.rs"] +pub mod pipe; +#[path = "../unsupported/process.rs"] +pub mod process; +#[path = "../unsupported/thread.rs"] +pub mod thread; +#[path = "../unsupported/time.rs"] +pub mod time; + +pub use common::*; diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs index 0a2a8f5ef67be..60c33c637d762 100644 --- a/library/std/src/sys/pal/uefi/helpers.rs +++ b/library/std/src/sys/pal/uefi/helpers.rs @@ -216,6 +216,60 @@ pub(crate) fn device_path_to_text(path: NonNull) -> io::R Err(io::const_error!(io::ErrorKind::NotFound, "no device path to text protocol found")) } +fn device_node_to_text(path: NonNull) -> io::Result { + fn node_to_text( + protocol: NonNull, + path: NonNull, + ) -> io::Result { + let path_ptr: *mut r_efi::efi::Char16 = unsafe { + ((*protocol.as_ptr()).convert_device_node_to_text)( + path.as_ptr(), + // DisplayOnly + r_efi::efi::Boolean::FALSE, + // AllowShortcuts + r_efi::efi::Boolean::FALSE, + ) + }; + + let path = os_string_from_raw(path_ptr) + .ok_or(io::const_error!(io::ErrorKind::InvalidData, "Invalid path"))?; + + if let Some(boot_services) = crate::os::uefi::env::boot_services() { + let boot_services: NonNull = boot_services.cast(); + unsafe { + ((*boot_services.as_ptr()).free_pool)(path_ptr.cast()); + } + } + + Ok(path) + } + + static LAST_VALID_HANDLE: AtomicPtr = + AtomicPtr::new(crate::ptr::null_mut()); + + if let Some(handle) = NonNull::new(LAST_VALID_HANDLE.load(Ordering::Acquire)) { + if let Ok(protocol) = open_protocol::( + handle, + device_path_to_text::PROTOCOL_GUID, + ) { + return node_to_text(protocol, path); + } + } + + let device_path_to_text_handles = locate_handles(device_path_to_text::PROTOCOL_GUID)?; + for handle in device_path_to_text_handles { + if let Ok(protocol) = open_protocol::( + handle, + device_path_to_text::PROTOCOL_GUID, + ) { + LAST_VALID_HANDLE.store(handle.as_ptr(), Ordering::Release); + return node_to_text(protocol, path); + } + } + + Err(io::const_error!(io::ErrorKind::NotFound, "No device path to text protocol found")) +} + /// Gets RuntimeServices. pub(crate) fn runtime_services() -> Option> { let system_table: NonNull = @@ -319,6 +373,11 @@ impl<'a> BorrowedDevicePath<'a> { pub(crate) fn to_text(&self) -> io::Result { device_path_to_text(self.protocol) } + + #[expect(dead_code)] + pub(crate) const fn iter(&'a self) -> DevicePathIterator<'a> { + DevicePathIterator::new(DevicePathNode::new(self.protocol)) + } } impl<'a> crate::fmt::Debug for BorrowedDevicePath<'a> { @@ -330,6 +389,126 @@ impl<'a> crate::fmt::Debug for BorrowedDevicePath<'a> { } } +pub(crate) struct DevicePathIterator<'a>(Option>); + +impl<'a> DevicePathIterator<'a> { + const fn new(node: DevicePathNode<'a>) -> Self { + if node.is_end() { Self(None) } else { Self(Some(node)) } + } +} + +impl<'a> Iterator for DevicePathIterator<'a> { + type Item = DevicePathNode<'a>; + + fn next(&mut self) -> Option { + let cur_node = self.0?; + + let next_node = unsafe { cur_node.next_node() }; + self.0 = if next_node.is_end() { None } else { Some(next_node) }; + + Some(cur_node) + } +} + +#[derive(Copy, Clone)] +pub(crate) struct DevicePathNode<'a> { + protocol: NonNull, + phantom: PhantomData<&'a r_efi::protocols::device_path::Protocol>, +} + +impl<'a> DevicePathNode<'a> { + pub(crate) const fn new(protocol: NonNull) -> Self { + Self { protocol, phantom: PhantomData } + } + + pub(crate) const fn length(&self) -> u16 { + let len = unsafe { (*self.protocol.as_ptr()).length }; + u16::from_le_bytes(len) + } + + pub(crate) const fn node_type(&self) -> u8 { + unsafe { (*self.protocol.as_ptr()).r#type } + } + + pub(crate) const fn sub_type(&self) -> u8 { + unsafe { (*self.protocol.as_ptr()).sub_type } + } + + pub(crate) fn data(&self) -> &[u8] { + let length: usize = self.length().into(); + + // Some nodes do not have any special data + if length > 4 { + let raw_ptr: *const u8 = self.protocol.as_ptr().cast(); + let data = unsafe { raw_ptr.add(4) }; + unsafe { crate::slice::from_raw_parts(data, length - 4) } + } else { + &[] + } + } + + pub(crate) const fn is_end(&self) -> bool { + self.node_type() == r_efi::protocols::device_path::TYPE_END + && self.sub_type() == r_efi::protocols::device_path::End::SUBTYPE_ENTIRE + } + + #[expect(dead_code)] + pub(crate) const fn is_end_instance(&self) -> bool { + self.node_type() == r_efi::protocols::device_path::TYPE_END + && self.sub_type() == r_efi::protocols::device_path::End::SUBTYPE_INSTANCE + } + + pub(crate) unsafe fn next_node(&self) -> Self { + let node = unsafe { + self.protocol + .cast::() + .add(self.length().into()) + .cast::() + }; + Self::new(node) + } + + #[expect(dead_code)] + pub(crate) fn to_path(&'a self) -> BorrowedDevicePath<'a> { + BorrowedDevicePath::new(self.protocol) + } + + pub(crate) fn to_text(&self) -> io::Result { + device_node_to_text(self.protocol) + } +} + +impl<'a> PartialEq for DevicePathNode<'a> { + fn eq(&self, other: &Self) -> bool { + let self_len = self.length(); + let other_len = other.length(); + + self_len == other_len + && unsafe { + compiler_builtins::mem::memcmp( + self.protocol.as_ptr().cast(), + other.protocol.as_ptr().cast(), + usize::from(self_len), + ) == 0 + } + } +} + +impl<'a> crate::fmt::Debug for DevicePathNode<'a> { + fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result { + match self.to_text() { + Ok(p) => p.fmt(f), + Err(_) => f + .debug_struct("DevicePathNode") + .field("type", &self.node_type()) + .field("sub_type", &self.sub_type()) + .field("length", &self.length()) + .field("specific_device_path_data", &self.data()) + .finish(), + } + } +} + pub(crate) struct OwnedProtocol { guid: r_efi::efi::Guid, handle: NonNull, diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs index 3a238d160cb57..91f55fcd32bb5 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/pal/unix/os.rs @@ -484,7 +484,12 @@ pub fn current_exe() -> io::Result { } } -#[cfg(any(target_os = "redox", target_os = "rtems"))] +#[cfg(target_os = "redox")] +pub fn current_exe() -> io::Result { + crate::fs::read_to_string("/scheme/sys/exe").map(PathBuf::from) +} + +#[cfg(target_os = "rtems")] pub fn current_exe() -> io::Result { crate::fs::read_to_string("sys:exe").map(PathBuf::from) } diff --git a/library/std/src/sys/pal/unix/process/process_common.rs b/library/std/src/sys/pal/unix/process/process_common.rs index 0ea9db211b311..dd41921f263e6 100644 --- a/library/std/src/sys/pal/unix/process/process_common.rs +++ b/library/std/src/sys/pal/unix/process/process_common.rs @@ -19,8 +19,6 @@ use crate::{fmt, io, ptr}; cfg_if::cfg_if! { if #[cfg(target_os = "fuchsia")] { // fuchsia doesn't have /dev/null - } else if #[cfg(target_os = "redox")] { - const DEV_NULL: &CStr = c"null:"; } else if #[cfg(target_os = "vxworks")] { const DEV_NULL: &CStr = c"/null"; } else { diff --git a/library/std/src/sys/path/unix.rs b/library/std/src/sys/path/unix.rs index 361e99964f18c..faa2616a6320d 100644 --- a/library/std/src/sys/path/unix.rs +++ b/library/std/src/sys/path/unix.rs @@ -62,10 +62,7 @@ pub(crate) fn absolute(path: &Path) -> io::Result { } pub(crate) fn is_absolute(path: &Path) -> bool { - if cfg!(target_os = "redox") { - // FIXME: Allow Redox prefixes - path.has_root() || crate::path::has_redox_scheme(path.as_u8_slice()) - } else if cfg!(any(unix, target_os = "hermit", target_os = "wasi")) { + if cfg!(any(unix, target_os = "hermit", target_os = "wasi")) { path.has_root() } else { path.has_root() && path.prefix().is_some() diff --git a/library/std/src/sys/random/mod.rs b/library/std/src/sys/random/mod.rs index f42351deb92c0..870039602bcf0 100644 --- a/library/std/src/sys/random/mod.rs +++ b/library/std/src/sys/random/mod.rs @@ -60,6 +60,9 @@ cfg_if::cfg_if! { } else if #[cfg(target_os = "teeos")] { mod teeos; pub use teeos::fill_bytes; + } else if #[cfg(target_os = "trusty")] { + mod trusty; + pub use trusty::fill_bytes; } else if #[cfg(target_os = "uefi")] { mod uefi; pub use uefi::fill_bytes; diff --git a/library/std/src/sys/random/trusty.rs b/library/std/src/sys/random/trusty.rs new file mode 100644 index 0000000000000..da6ca3eea2426 --- /dev/null +++ b/library/std/src/sys/random/trusty.rs @@ -0,0 +1,7 @@ +extern "C" { + fn trusty_rng_secure_rand(randomBuffer: *mut core::ffi::c_void, randomBufferLen: libc::size_t); +} + +pub fn fill_bytes(bytes: &mut [u8]) { + unsafe { trusty_rng_secure_rand(bytes.as_mut_ptr().cast(), bytes.len()) } +} diff --git a/library/std/src/sys/stdio/mod.rs b/library/std/src/sys/stdio/mod.rs index 2a9167bfe966c..336d4c8527db3 100644 --- a/library/std/src/sys/stdio/mod.rs +++ b/library/std/src/sys/stdio/mod.rs @@ -19,6 +19,9 @@ cfg_if::cfg_if! { } else if #[cfg(target_os = "teeos")] { mod teeos; pub use teeos::*; + } else if #[cfg(target_os = "trusty")] { + mod trusty; + pub use trusty::*; } else if #[cfg(target_os = "uefi")] { mod uefi; pub use uefi::*; diff --git a/library/std/src/sys/stdio/sgx.rs b/library/std/src/sys/stdio/sgx.rs index 03d754cb2173f..1894c098d1851 100644 --- a/library/std/src/sys/stdio/sgx.rs +++ b/library/std/src/sys/stdio/sgx.rs @@ -1,6 +1,6 @@ use fortanix_sgx_abi as abi; -use crate::io; +use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::sys::fd::FileDesc; pub struct Stdin(()); @@ -24,6 +24,19 @@ impl io::Read for Stdin { fn read(&mut self, buf: &mut [u8]) -> io::Result { with_std_fd(abi::FD_STDIN, |fd| fd.read(buf)) } + + fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> { + with_std_fd(abi::FD_STDIN, |fd| fd.read_buf(buf)) + } + + fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { + with_std_fd(abi::FD_STDIN, |fd| fd.read_vectored(bufs)) + } + + #[inline] + fn is_read_vectored(&self) -> bool { + true + } } impl Stdout { @@ -40,6 +53,15 @@ impl io::Write for Stdout { fn flush(&mut self) -> io::Result<()> { with_std_fd(abi::FD_STDOUT, |fd| fd.flush()) } + + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { + with_std_fd(abi::FD_STDOUT, |fd| fd.write_vectored(bufs)) + } + + #[inline] + fn is_write_vectored(&self) -> bool { + true + } } impl Stderr { @@ -56,6 +78,15 @@ impl io::Write for Stderr { fn flush(&mut self) -> io::Result<()> { with_std_fd(abi::FD_STDERR, |fd| fd.flush()) } + + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { + with_std_fd(abi::FD_STDERR, |fd| fd.write_vectored(bufs)) + } + + #[inline] + fn is_write_vectored(&self) -> bool { + true + } } pub const STDIN_BUF_SIZE: usize = crate::sys::io::DEFAULT_BUF_SIZE; diff --git a/library/std/src/sys/stdio/trusty.rs b/library/std/src/sys/stdio/trusty.rs new file mode 100644 index 0000000000000..d393e95394d1a --- /dev/null +++ b/library/std/src/sys/stdio/trusty.rs @@ -0,0 +1,81 @@ +use crate::io; + +pub struct Stdin; +pub struct Stdout; +pub struct Stderr; + +impl Stdin { + pub const fn new() -> Stdin { + Stdin + } +} + +impl io::Read for Stdin { + fn read(&mut self, _buf: &mut [u8]) -> io::Result { + Ok(0) + } +} + +impl Stdout { + pub const fn new() -> Stdout { + Stdout + } +} + +impl io::Write for Stdout { + fn write(&mut self, buf: &[u8]) -> io::Result { + _write(libc::STDOUT_FILENO, buf) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +impl Stderr { + pub const fn new() -> Stderr { + Stderr + } +} + +impl io::Write for Stderr { + fn write(&mut self, buf: &[u8]) -> io::Result { + _write(libc::STDERR_FILENO, buf) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +pub const STDIN_BUF_SIZE: usize = 0; + +pub fn is_ebadf(_err: &io::Error) -> bool { + true +} + +pub fn panic_output() -> Option { + Some(Stderr) +} + +fn _write(fd: i32, message: &[u8]) -> io::Result { + let mut iov = libc::iovec { iov_base: message.as_ptr() as *mut _, iov_len: message.len() }; + loop { + // SAFETY: syscall, safe arguments. + let ret = unsafe { libc::writev(fd, &iov, 1) }; + if ret < 0 { + return Err(io::Error::last_os_error()); + } + let ret = ret as usize; + if ret > iov.iov_len { + return Err(io::Error::last_os_error()); + } + if ret == iov.iov_len { + return Ok(message.len()); + } + // SAFETY: ret has been checked to be less than the length of + // the buffer + iov.iov_base = unsafe { iov.iov_base.add(ret) }; + iov.iov_len -= ret; + } +} diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs index f0a13323ec93f..1ff13154b7b3c 100644 --- a/library/std/src/sys/thread_local/mod.rs +++ b/library/std/src/sys/thread_local/mod.rs @@ -28,6 +28,7 @@ cfg_if::cfg_if! { all(target_family = "wasm", not(target_feature = "atomics")), target_os = "uefi", target_os = "zkvm", + target_os = "trusty", ))] { mod statik; pub use statik::{EagerStorage, LazyStorage, thread_local_inner}; @@ -91,6 +92,7 @@ pub(crate) mod guard { )), target_os = "uefi", target_os = "zkvm", + target_os = "trusty", ))] { pub(crate) fn enable() { // FIXME: Right now there is no concept of "thread exit" on diff --git a/library/std/tests/floats/f16.rs b/library/std/tests/floats/f16.rs index 5180f3d40f3a7..19389a9178e91 100644 --- a/library/std/tests/floats/f16.rs +++ b/library/std/tests/floats/f16.rs @@ -461,18 +461,16 @@ fn test_recip() { #[test] #[cfg(reliable_f16_math)] fn test_powi() { - // FIXME(llvm19): LLVM misoptimizes `powi.f16` - // - // let nan: f16 = f16::NAN; - // let inf: f16 = f16::INFINITY; - // let neg_inf: f16 = f16::NEG_INFINITY; - // assert_eq!(1.0f16.powi(1), 1.0); - // assert_approx_eq!((-3.1f16).powi(2), 9.61, TOL_0); - // assert_approx_eq!(5.9f16.powi(-2), 0.028727, TOL_N2); - // assert_eq!(8.3f16.powi(0), 1.0); - // assert!(nan.powi(2).is_nan()); - // assert_eq!(inf.powi(3), inf); - // assert_eq!(neg_inf.powi(2), inf); + let nan: f16 = f16::NAN; + let inf: f16 = f16::INFINITY; + let neg_inf: f16 = f16::NEG_INFINITY; + assert_eq!(1.0f16.powi(1), 1.0); + assert_approx_eq!((-3.1f16).powi(2), 9.61, TOL_0); + assert_approx_eq!(5.9f16.powi(-2), 0.028727, TOL_N2); + assert_eq!(8.3f16.powi(0), 1.0); + assert!(nan.powi(2).is_nan()); + assert_eq!(inf.powi(3), inf); + assert_eq!(neg_inf.powi(2), inf); } #[test] @@ -813,6 +811,7 @@ fn test_clamp_max_is_nan() { } #[test] +#[cfg(reliable_f16_math)] fn test_total_cmp() { use core::cmp::Ordering; @@ -820,14 +819,13 @@ fn test_total_cmp() { 1 << (f16::MANTISSA_DIGITS - 2) } - // FIXME(f16_f128): test subnormals when powf is available - // fn min_subnorm() -> f16 { - // f16::MIN_POSITIVE / f16::powf(2.0, f16::MANTISSA_DIGITS as f16 - 1.0) - // } + fn min_subnorm() -> f16 { + f16::MIN_POSITIVE / f16::powf(2.0, f16::MANTISSA_DIGITS as f16 - 1.0) + } - // fn max_subnorm() -> f16 { - // f16::MIN_POSITIVE - min_subnorm() - // } + fn max_subnorm() -> f16 { + f16::MIN_POSITIVE - min_subnorm() + } fn q_nan() -> f16 { f16::from_bits(f16::NAN.to_bits() | quiet_bit_mask()) @@ -846,12 +844,12 @@ fn test_total_cmp() { assert_eq!(Ordering::Equal, (-1.5_f16).total_cmp(&-1.5)); assert_eq!(Ordering::Equal, (-0.5_f16).total_cmp(&-0.5)); assert_eq!(Ordering::Equal, (-f16::MIN_POSITIVE).total_cmp(&-f16::MIN_POSITIVE)); - // assert_eq!(Ordering::Equal, (-max_subnorm()).total_cmp(&-max_subnorm())); - // assert_eq!(Ordering::Equal, (-min_subnorm()).total_cmp(&-min_subnorm())); + assert_eq!(Ordering::Equal, (-max_subnorm()).total_cmp(&-max_subnorm())); + assert_eq!(Ordering::Equal, (-min_subnorm()).total_cmp(&-min_subnorm())); assert_eq!(Ordering::Equal, (-0.0_f16).total_cmp(&-0.0)); assert_eq!(Ordering::Equal, 0.0_f16.total_cmp(&0.0)); - // assert_eq!(Ordering::Equal, min_subnorm().total_cmp(&min_subnorm())); - // assert_eq!(Ordering::Equal, max_subnorm().total_cmp(&max_subnorm())); + assert_eq!(Ordering::Equal, min_subnorm().total_cmp(&min_subnorm())); + assert_eq!(Ordering::Equal, max_subnorm().total_cmp(&max_subnorm())); assert_eq!(Ordering::Equal, f16::MIN_POSITIVE.total_cmp(&f16::MIN_POSITIVE)); assert_eq!(Ordering::Equal, 0.5_f16.total_cmp(&0.5)); assert_eq!(Ordering::Equal, 1.0_f16.total_cmp(&1.0)); @@ -870,13 +868,13 @@ fn test_total_cmp() { assert_eq!(Ordering::Less, (-1.5_f16).total_cmp(&-1.0)); assert_eq!(Ordering::Less, (-1.0_f16).total_cmp(&-0.5)); assert_eq!(Ordering::Less, (-0.5_f16).total_cmp(&-f16::MIN_POSITIVE)); - // assert_eq!(Ordering::Less, (-f16::MIN_POSITIVE).total_cmp(&-max_subnorm())); - // assert_eq!(Ordering::Less, (-max_subnorm()).total_cmp(&-min_subnorm())); - // assert_eq!(Ordering::Less, (-min_subnorm()).total_cmp(&-0.0)); + assert_eq!(Ordering::Less, (-f16::MIN_POSITIVE).total_cmp(&-max_subnorm())); + assert_eq!(Ordering::Less, (-max_subnorm()).total_cmp(&-min_subnorm())); + assert_eq!(Ordering::Less, (-min_subnorm()).total_cmp(&-0.0)); assert_eq!(Ordering::Less, (-0.0_f16).total_cmp(&0.0)); - // assert_eq!(Ordering::Less, 0.0_f16.total_cmp(&min_subnorm())); - // assert_eq!(Ordering::Less, min_subnorm().total_cmp(&max_subnorm())); - // assert_eq!(Ordering::Less, max_subnorm().total_cmp(&f16::MIN_POSITIVE)); + assert_eq!(Ordering::Less, 0.0_f16.total_cmp(&min_subnorm())); + assert_eq!(Ordering::Less, min_subnorm().total_cmp(&max_subnorm())); + assert_eq!(Ordering::Less, max_subnorm().total_cmp(&f16::MIN_POSITIVE)); assert_eq!(Ordering::Less, f16::MIN_POSITIVE.total_cmp(&0.5)); assert_eq!(Ordering::Less, 0.5_f16.total_cmp(&1.0)); assert_eq!(Ordering::Less, 1.0_f16.total_cmp(&1.5)); @@ -894,13 +892,13 @@ fn test_total_cmp() { assert_eq!(Ordering::Greater, (-1.0_f16).total_cmp(&-1.5)); assert_eq!(Ordering::Greater, (-0.5_f16).total_cmp(&-1.0)); assert_eq!(Ordering::Greater, (-f16::MIN_POSITIVE).total_cmp(&-0.5)); - // assert_eq!(Ordering::Greater, (-max_subnorm()).total_cmp(&-f16::MIN_POSITIVE)); - // assert_eq!(Ordering::Greater, (-min_subnorm()).total_cmp(&-max_subnorm())); - // assert_eq!(Ordering::Greater, (-0.0_f16).total_cmp(&-min_subnorm())); + assert_eq!(Ordering::Greater, (-max_subnorm()).total_cmp(&-f16::MIN_POSITIVE)); + assert_eq!(Ordering::Greater, (-min_subnorm()).total_cmp(&-max_subnorm())); + assert_eq!(Ordering::Greater, (-0.0_f16).total_cmp(&-min_subnorm())); assert_eq!(Ordering::Greater, 0.0_f16.total_cmp(&-0.0)); - // assert_eq!(Ordering::Greater, min_subnorm().total_cmp(&0.0)); - // assert_eq!(Ordering::Greater, max_subnorm().total_cmp(&min_subnorm())); - // assert_eq!(Ordering::Greater, f16::MIN_POSITIVE.total_cmp(&max_subnorm())); + assert_eq!(Ordering::Greater, min_subnorm().total_cmp(&0.0)); + assert_eq!(Ordering::Greater, max_subnorm().total_cmp(&min_subnorm())); + assert_eq!(Ordering::Greater, f16::MIN_POSITIVE.total_cmp(&max_subnorm())); assert_eq!(Ordering::Greater, 0.5_f16.total_cmp(&f16::MIN_POSITIVE)); assert_eq!(Ordering::Greater, 1.0_f16.total_cmp(&0.5)); assert_eq!(Ordering::Greater, 1.5_f16.total_cmp(&1.0)); @@ -918,12 +916,12 @@ fn test_total_cmp() { assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-1.0)); assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-0.5)); assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f16::MIN_POSITIVE)); - // assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-max_subnorm())); - // assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-min_subnorm())); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-max_subnorm())); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-min_subnorm())); assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-0.0)); assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&0.0)); - // assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&min_subnorm())); - // assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&max_subnorm())); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&min_subnorm())); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&max_subnorm())); assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f16::MIN_POSITIVE)); assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&0.5)); assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&1.0)); @@ -940,12 +938,12 @@ fn test_total_cmp() { assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-1.0)); assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-0.5)); assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f16::MIN_POSITIVE)); - // assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-max_subnorm())); - // assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-min_subnorm())); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-max_subnorm())); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-min_subnorm())); assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-0.0)); assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&0.0)); - // assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&min_subnorm())); - // assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&max_subnorm())); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&min_subnorm())); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&max_subnorm())); assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f16::MIN_POSITIVE)); assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&0.5)); assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&1.0)); 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() { diff --git a/library/sysroot/Cargo.toml b/library/sysroot/Cargo.toml index 0f6fa2d291ab3..ec6ae31507e05 100644 --- a/library/sysroot/Cargo.toml +++ b/library/sysroot/Cargo.toml @@ -3,7 +3,7 @@ cargo-features = ["public-dependency"] [package] name = "sysroot" version = "0.0.0" -edition = "2021" +edition = "2024" # this is a dummy crate to ensure that all required crates appear in the sysroot [dependencies] diff --git a/library/test/Cargo.toml b/library/test/Cargo.toml index 241ef324b0088..2a32a7dd76eed 100644 --- a/library/test/Cargo.toml +++ b/library/test/Cargo.toml @@ -3,7 +3,7 @@ cargo-features = ["public-dependency"] [package] name = "test" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] getopts = { version = "0.2.21", features = ['rustc-dep-of-std'] } diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml index 66e8d1a3ffe5f..da60924c2b419 100644 --- a/library/unwind/Cargo.toml +++ b/library/unwind/Cargo.toml @@ -3,7 +3,7 @@ name = "unwind" version = "0.0.0" license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/rust.git" -edition = "2021" +edition = "2024" include = [ '/libunwind/*', ] diff --git a/library/windows_targets/Cargo.toml b/library/windows_targets/Cargo.toml index 94d7c8210647c..705c9e0438119 100644 --- a/library/windows_targets/Cargo.toml +++ b/library/windows_targets/Cargo.toml @@ -2,7 +2,7 @@ name = "windows-targets" description = "A drop-in replacement for the real windows-targets crate for use in std only." version = "0.0.0" -edition = "2021" +edition = "2024" [features] # Enable using raw-dylib for Windows imports. diff --git a/library/windows_targets/src/lib.rs b/library/windows_targets/src/lib.rs index 939fab7d5fe62..c7d158584ebd8 100644 --- a/library/windows_targets/src/lib.rs +++ b/library/windows_targets/src/lib.rs @@ -12,7 +12,7 @@ pub macro link { ($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => ( #[cfg_attr(not(target_arch = "x86"), link(name = $library, kind = "raw-dylib", modifiers = "+verbatim"))] #[cfg_attr(target_arch = "x86", link(name = $library, kind = "raw-dylib", modifiers = "+verbatim", import_name_type = "undecorated"))] - extern $abi { + unsafe extern $abi { $(#[link_name=$link_name])? pub fn $($function)*; } @@ -26,7 +26,7 @@ pub macro link { // libraries below by using an empty extern block. This works because extern blocks are not // connected to the library given in the #[link] attribute. #[link(name = "kernel32")] - extern $abi { + unsafe extern $abi { $(#[link_name=$link_name])? pub fn $($function)*; } diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 4c1961eea0864..c4ac176617fac 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -2,5 +2,5 @@ # standard library we currently track. [toolchain] -channel = "nightly-2025-03-13" +channel = "nightly-2025-03-17" components = ["llvm-tools-preview", "rustc-dev", "rust-src", "rustfmt"] diff --git a/tool_config/kani-version.toml b/tool_config/kani-version.toml index 6256b6d478186..aee64d37da844 100644 --- a/tool_config/kani-version.toml +++ b/tool_config/kani-version.toml @@ -2,4 +2,4 @@ # incompatible with the verify-std repo. [kani] -commit = "e48888716ac16e2ce098c00355a52205c683f679" +commit = "62dd13c914191b91ffd8244f70508791e6270a52"