Skip to content

Update subtree/library to 2025-08-13 #460

New issue

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

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

Already on GitHub? Sign in to your account

Open
wants to merge 28 commits into
base: subtree/library
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
6ff81cb
document assumptions about `Clone` and `Eq` traits
gewitternacht Jul 22, 2025
bd578ab
remove trailing whitespace
gewitternacht Jul 22, 2025
b57d8af
add links to collections
gewitternacht Jul 22, 2025
624645d
clearer wording for `unsafe` code
gewitternacht Jul 29, 2025
2b1046a
std: sys: io: io_slice: Add UEFI types
Ayush1325 Jul 20, 2025
d451ec1
Replace unsafe function with safe alternative
ChrisDenton Aug 9, 2025
e06e0ed
Stabilize feature
Kivooeo Aug 8, 2025
29c83f4
`{BTree,Hash}Map`: add "`Entry` API" section heading
ada4a Aug 9, 2025
0cf20bd
`HashMap`: also add "Usage with custom key types" heading
ada4a Aug 9, 2025
b61bc0d
Let forward_ref_* macros accept multiple attributes, and require attr…
clarfonthey Jul 14, 2025
5235f7a
Constify remaining operators
clarfonthey Jul 15, 2025
e6bca6d
Rollup merge of #145135 - Kivooeo:stabilize-duration_constructors_lit…
Zalathar Aug 10, 2025
7029f55
Rollup merge of #145162 - ada4a:hash_and_btree_map-add-entry-section,…
Zalathar Aug 10, 2025
59ee82e
Rollup merge of #145150 - ChrisDenton:inherit, r=Mark-Simulacrum
jhpratt Aug 10, 2025
44db1e4
Remove unnecessary parentheses in `assert!`s
estebank Aug 10, 2025
d88aefd
mention `Hash` and `Ord`; refine description of `derive`
gewitternacht Aug 10, 2025
f2e76f8
Rollup merge of #143949 - clarfonthey:const-arith-ops, r=Amanieu
Zalathar Aug 11, 2025
1f8bb9f
Rollup merge of #144330 - gewitternacht:document-clone-eq, r=Amanieu
Zalathar Aug 11, 2025
893580e
Rollup merge of #144350 - Ayush1325:uefi-io, r=tgross35,nicholasbishop
Zalathar Aug 11, 2025
bfb736f
Rollup merge of #145228 - estebank:unnecessary-parens, r=joshtriplett
Zalathar Aug 11, 2025
2bf3644
std: sys: pal: uefi: Overhaul Time
Ayush1325 Apr 14, 2025
e6fd5d5
std: sys: pal: uefi: tests: Add systemtime tests
Ayush1325 May 24, 2025
ad58f8c
Make explicit guarantees about `Vec`’s allocator
SabrinaJewson Aug 11, 2025
6a1fb51
Respond to review comments
SabrinaJewson Aug 11, 2025
5b128ea
Handle the `capacity == 0` case
SabrinaJewson Aug 12, 2025
70be52f
fix typo
ada4a Aug 12, 2025
c598835
Rollup merge of #145260 - SabrinaJewson:vec-allocator-docs, r=dtolnay
Zalathar Aug 12, 2025
aad53ec
Rollup merge of #145292 - ada4a:patch-2, r=tgross35
Zalathar Aug 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions alloc/src/collections/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ pub(super) const MIN_LEN: usize = node::MIN_LEN_AFTER_SPLIT;
/// ]);
/// ```
///
/// ## `Entry` API
///
/// `BTreeMap` implements an [`Entry API`], which allows for complex
/// methods of getting, setting, updating and removing keys and their values:
///
Expand Down
72 changes: 61 additions & 11 deletions alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,27 @@
//! v[1] = v[1] + 5;
//! ```
//!
//! # Memory layout
//!
//! When the type is non-zero-sized and the capacity is nonzero, [`Vec`] uses the [`Global`]
//! allocator for its allocation. It is valid to convert both ways between such a [`Vec`] and a raw
//! pointer allocated with the [`Global`] allocator, provided that the [`Layout`] used with the
//! allocator is correct for a sequence of `capacity` elements of the type, and the first `len`
//! values pointed to by the raw pointer are valid. More precisely, a `ptr: *mut T` that has been
//! allocated with the [`Global`] allocator with [`Layout::array::<T>(capacity)`][Layout::array] may
//! be converted into a vec using
//! [`Vec::<T>::from_raw_parts(ptr, len, capacity)`](Vec::from_raw_parts). Conversely, the memory
//! backing a `value: *mut T` obtained from [`Vec::<T>::as_mut_ptr`] may be deallocated using the
//! [`Global`] allocator with the same layout.
//!
//! For zero-sized types (ZSTs), or when the capacity is zero, the `Vec` pointer must be non-null
//! and sufficiently aligned. The recommended way to build a `Vec` of ZSTs if [`vec!`] cannot be
//! used is to use [`ptr::NonNull::dangling`].
//!
//! [`push`]: Vec::push
//! [`ptr::NonNull::dangling`]: NonNull::dangling
//! [`Layout`]: crate::alloc::Layout
//! [Layout::array]: crate::alloc::Layout::array

#![stable(feature = "rust1", since = "1.0.0")]

Expand Down Expand Up @@ -523,18 +543,23 @@ impl<T> Vec<T> {
/// This is highly unsafe, due to the number of invariants that aren't
/// checked:
///
/// * `ptr` must have been allocated using the global allocator, such as via
/// the [`alloc::alloc`] function.
/// * `T` needs to have the same alignment as what `ptr` was allocated with.
/// * If `T` is not a zero-sized type and the capacity is nonzero, `ptr` must have
/// been allocated using the global allocator, such as via the [`alloc::alloc`]
/// function. If `T` is a zero-sized type or the capacity is zero, `ptr` need
/// only be non-null and aligned.
/// * `T` needs to have the same alignment as what `ptr` was allocated with,
/// if the pointer is required to be allocated.
/// (`T` having a less strict alignment is not sufficient, the alignment really
/// needs to be equal to satisfy the [`dealloc`] requirement that memory must be
/// allocated and deallocated with the same layout.)
/// * The size of `T` times the `capacity` (ie. the allocated size in bytes) needs
/// to be the same size as the pointer was allocated with. (Because similar to
/// alignment, [`dealloc`] must be called with the same layout `size`.)
/// * The size of `T` times the `capacity` (ie. the allocated size in bytes), if
/// nonzero, needs to be the same size as the pointer was allocated with.
/// (Because similar to alignment, [`dealloc`] must be called with the same
/// layout `size`.)
/// * `length` needs to be less than or equal to `capacity`.
/// * The first `length` values must be properly initialized values of type `T`.
/// * `capacity` needs to be the capacity that the pointer was allocated with.
/// * `capacity` needs to be the capacity that the pointer was allocated with,
/// if the pointer is required to be allocated.
/// * The allocated size in bytes must be no larger than `isize::MAX`.
/// See the safety documentation of [`pointer::offset`].
///
Expand Down Expand Up @@ -770,12 +795,16 @@ impl<T> Vec<T> {
/// order as the arguments to [`from_raw_parts`].
///
/// After calling this function, the caller is responsible for the
/// memory previously managed by the `Vec`. The only way to do
/// this is to convert the raw pointer, length, and capacity back
/// into a `Vec` with the [`from_raw_parts`] function, allowing
/// the destructor to perform the cleanup.
/// memory previously managed by the `Vec`. Most often, one does
/// this by converting the raw pointer, length, and capacity back
/// into a `Vec` with the [`from_raw_parts`] function; more generally,
/// if `T` is non-zero-sized and the capacity is nonzero, one may use
/// any method that calls [`dealloc`] with a layout of
/// `Layout::array::<T>(capacity)`; if `T` is zero-sized or the
/// capacity is zero, nothing needs to be done.
///
/// [`from_raw_parts`]: Vec::from_raw_parts
/// [`dealloc`]: crate::alloc::GlobalAlloc::dealloc
///
/// # Examples
///
Expand Down Expand Up @@ -1755,6 +1784,12 @@ impl<T, A: Allocator> Vec<T, A> {
/// may still invalidate this pointer.
/// See the second example below for how this guarantee can be used.
///
/// The method also guarantees that, as long as `T` is not zero-sized and the capacity is
/// nonzero, the pointer may be passed into [`dealloc`] with a layout of
/// `Layout::array::<T>(capacity)` in order to deallocate the backing memory. If this is done,
/// be careful not to run the destructor of the `Vec`, as dropping it will result in
/// double-frees. Wrapping the `Vec` in a [`ManuallyDrop`] is the typical way to achieve this.
///
/// # Examples
///
/// ```
Expand Down Expand Up @@ -1787,9 +1822,24 @@ impl<T, A: Allocator> Vec<T, A> {
/// }
/// ```
///
/// Deallocating a vector using [`Box`] (which uses [`dealloc`] internally):
///
/// ```
/// use std::mem::{ManuallyDrop, MaybeUninit};
///
/// let mut v = ManuallyDrop::new(vec![0, 1, 2]);
/// let ptr = v.as_mut_ptr();
/// let capacity = v.capacity();
/// let slice_ptr: *mut [MaybeUninit<i32>] =
/// std::ptr::slice_from_raw_parts_mut(ptr.cast(), capacity);
/// drop(unsafe { Box::from_raw(slice_ptr) });
/// ```
///
/// [`as_mut_ptr`]: Vec::as_mut_ptr
/// [`as_ptr`]: Vec::as_ptr
/// [`as_non_null`]: Vec::as_non_null
/// [`dealloc`]: crate::alloc::GlobalAlloc::dealloc
/// [`ManuallyDrop`]: core::mem::ManuallyDrop
#[stable(feature = "vec_as_ptr", since = "1.37.0")]
#[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
#[rustc_never_returns_null_ptr]
Expand Down
33 changes: 33 additions & 0 deletions core/src/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,34 @@ mod uninit;
/// // Note: With the manual implementations the above line will compile.
/// ```
///
/// ## `Clone` and `PartialEq`/`Eq`
/// `Clone` is intended for the duplication of objects. Consequently, when implementing
/// both `Clone` and [`PartialEq`], the following property is expected to hold:
/// ```text
/// x == x -> x.clone() == x
/// ```
/// In other words, if an object compares equal to itself,
/// its clone must also compare equal to the original.
///
/// For types that also implement [`Eq`] – for which `x == x` always holds –
/// this implies that `x.clone() == x` must always be true.
/// Standard library collections such as
/// [`HashMap`], [`HashSet`], [`BTreeMap`], [`BTreeSet`] and [`BinaryHeap`]
/// rely on their keys respecting this property for correct behavior.
/// Furthermore, these collections require that cloning a key preserves the outcome of the
/// [`Hash`] and [`Ord`] methods. Thankfully, this follows automatically from `x.clone() == x`
/// if `Hash` and `Ord` are correctly implemented according to their own requirements.
///
/// When deriving both `Clone` and [`PartialEq`] using `#[derive(Clone, PartialEq)]`
/// or when additionally deriving [`Eq`] using `#[derive(Clone, PartialEq, Eq)]`,
/// then this property is automatically upheld – provided that it is satisfied by
/// the underlying types.
///
/// Violating this property is a logic error. The behavior resulting from a logic error is not
/// specified, but users of the trait must ensure that such logic errors do *not* result in
/// undefined behavior. This means that `unsafe` code **must not** rely on this property
/// being satisfied.
///
/// ## Additional implementors
///
/// In addition to the [implementors listed below][impls],
Expand All @@ -152,6 +180,11 @@ mod uninit;
/// (even if the referent doesn't),
/// while variables captured by mutable reference never implement `Clone`.
///
/// [`HashMap`]: ../../std/collections/struct.HashMap.html
/// [`HashSet`]: ../../std/collections/struct.HashSet.html
/// [`BTreeMap`]: ../../std/collections/struct.BTreeMap.html
/// [`BTreeSet`]: ../../std/collections/struct.BTreeSet.html
/// [`BinaryHeap`]: ../../std/collections/struct.BinaryHeap.html
/// [impls]: #implementors
#[stable(feature = "rust1", since = "1.0.0")]
#[lang = "clone"]
Expand Down
38 changes: 13 additions & 25 deletions core/src/internal_macros.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
// implements the unary operator "op &T"
// based on "op T" where T is expected to be `Copy`able
macro_rules! forward_ref_unop {
(impl $imp:ident, $method:ident for $t:ty) => {
forward_ref_unop!(impl $imp, $method for $t,
#[stable(feature = "rust1", since = "1.0.0")]);
};
(impl $imp:ident, $method:ident for $t:ty, #[$attr:meta]) => {
#[$attr]
impl $imp for &$t {
(impl $imp:ident, $method:ident for $t:ty, $(#[$attr:meta])+) => {
$(#[$attr])+
impl const $imp for &$t {
type Output = <$t as $imp>::Output;

#[inline]
Expand All @@ -21,13 +17,9 @@ macro_rules! forward_ref_unop {
// implements binary operators "&T op U", "T op &U", "&T op &U"
// based on "T op U" where T and U are expected to be `Copy`able
macro_rules! forward_ref_binop {
(impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
forward_ref_binop!(impl $imp, $method for $t, $u,
#[stable(feature = "rust1", since = "1.0.0")]);
};
(impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => {
#[$attr]
impl<'a> $imp<$u> for &'a $t {
(impl $imp:ident, $method:ident for $t:ty, $u:ty, $(#[$attr:meta])+) => {
$(#[$attr])+
impl const $imp<$u> for &$t {
type Output = <$t as $imp<$u>>::Output;

#[inline]
Expand All @@ -37,8 +29,8 @@ macro_rules! forward_ref_binop {
}
}

#[$attr]
impl $imp<&$u> for $t {
$(#[$attr])+
impl const $imp<&$u> for $t {
type Output = <$t as $imp<$u>>::Output;

#[inline]
Expand All @@ -48,8 +40,8 @@ macro_rules! forward_ref_binop {
}
}

#[$attr]
impl $imp<&$u> for &$t {
$(#[$attr])+
impl const $imp<&$u> for &$t {
type Output = <$t as $imp<$u>>::Output;

#[inline]
Expand All @@ -64,13 +56,9 @@ macro_rules! forward_ref_binop {
// implements "T op= &U", based on "T op= U"
// where U is expected to be `Copy`able
macro_rules! forward_ref_op_assign {
(impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
forward_ref_op_assign!(impl $imp, $method for $t, $u,
#[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]);
};
(impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => {
#[$attr]
impl $imp<&$u> for $t {
(impl $imp:ident, $method:ident for $t:ty, $u:ty, $(#[$attr:meta])+) => {
$(#[$attr])+
impl const $imp<&$u> for $t {
#[inline]
#[track_caller]
fn $method(&mut self, other: &$u) {
Expand Down
47 changes: 30 additions & 17 deletions core/src/net/ip_addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use super::display_buffer::DisplayBuffer;
use crate::cmp::Ordering;
use crate::fmt::{self, Write};
use crate::hash::{Hash, Hasher};
use crate::iter;
use crate::mem::transmute;
use crate::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Not};

Expand Down Expand Up @@ -2348,20 +2347,24 @@ impl const From<[u16; 8]> for IpAddr {
}

#[stable(feature = "ip_bitops", since = "1.75.0")]
impl Not for Ipv4Addr {
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
impl const Not for Ipv4Addr {
type Output = Ipv4Addr;

#[inline]
fn not(mut self) -> Ipv4Addr {
for octet in &mut self.octets {
*octet = !*octet;
let mut idx = 0;
while idx < 4 {
self.octets[idx] = !self.octets[idx];
idx += 1;
}
self
}
}

#[stable(feature = "ip_bitops", since = "1.75.0")]
impl Not for &'_ Ipv4Addr {
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
impl const Not for &'_ Ipv4Addr {
type Output = Ipv4Addr;

#[inline]
Expand All @@ -2371,20 +2374,24 @@ impl Not for &'_ Ipv4Addr {
}

#[stable(feature = "ip_bitops", since = "1.75.0")]
impl Not for Ipv6Addr {
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
impl const Not for Ipv6Addr {
type Output = Ipv6Addr;

#[inline]
fn not(mut self) -> Ipv6Addr {
for octet in &mut self.octets {
*octet = !*octet;
let mut idx = 0;
while idx < 16 {
self.octets[idx] = !self.octets[idx];
idx += 1;
}
self
}
}

#[stable(feature = "ip_bitops", since = "1.75.0")]
impl Not for &'_ Ipv6Addr {
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
impl const Not for &'_ Ipv6Addr {
type Output = Ipv6Addr;

#[inline]
Expand All @@ -2400,23 +2407,25 @@ macro_rules! bitop_impls {
)*) => {
$(
$(#[$attr])*
impl $BitOpAssign for $ty {
impl const $BitOpAssign for $ty {
fn $bitop_assign(&mut self, rhs: $ty) {
for (lhs, rhs) in iter::zip(&mut self.octets, rhs.octets) {
lhs.$bitop_assign(rhs);
let mut idx = 0;
while idx < self.octets.len() {
self.octets[idx].$bitop_assign(rhs.octets[idx]);
idx += 1;
}
}
}

$(#[$attr])*
impl $BitOpAssign<&'_ $ty> for $ty {
impl const $BitOpAssign<&'_ $ty> for $ty {
fn $bitop_assign(&mut self, rhs: &'_ $ty) {
self.$bitop_assign(*rhs);
}
}

$(#[$attr])*
impl $BitOp for $ty {
impl const $BitOp for $ty {
type Output = $ty;

#[inline]
Expand All @@ -2427,7 +2436,7 @@ macro_rules! bitop_impls {
}

$(#[$attr])*
impl $BitOp<&'_ $ty> for $ty {
impl const $BitOp<&'_ $ty> for $ty {
type Output = $ty;

#[inline]
Expand All @@ -2438,7 +2447,7 @@ macro_rules! bitop_impls {
}

$(#[$attr])*
impl $BitOp<$ty> for &'_ $ty {
impl const $BitOp<$ty> for &'_ $ty {
type Output = $ty;

#[inline]
Expand All @@ -2450,7 +2459,7 @@ macro_rules! bitop_impls {
}

$(#[$attr])*
impl $BitOp<&'_ $ty> for &'_ $ty {
impl const $BitOp<&'_ $ty> for &'_ $ty {
type Output = $ty;

#[inline]
Expand All @@ -2466,12 +2475,16 @@ macro_rules! bitop_impls {

bitop_impls! {
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
impl (BitAnd, BitAndAssign) for Ipv4Addr = (bitand, bitand_assign);
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
impl (BitOr, BitOrAssign) for Ipv4Addr = (bitor, bitor_assign);

#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
impl (BitAnd, BitAndAssign) for Ipv6Addr = (bitand, bitand_assign);
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
impl (BitOr, BitOrAssign) for Ipv6Addr = (bitor, bitor_assign);
}
Loading