Skip to content

Update subtree/library to 2025-06-18 #26

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 12 commits into
base: subtree/library
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
25 changes: 16 additions & 9 deletions alloc/src/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1489,10 +1489,11 @@ impl String {
Some(ch)
}

/// Removes a [`char`] from this `String` at a byte position and returns it.
/// Removes a [`char`] from this `String` at byte position `idx` and returns it.
///
/// This is an *O*(*n*) operation, as it requires copying every element in the
/// buffer.
/// Copies all bytes after the removed char to new positions.
///
/// Note that calling this in a loop can result in quadratic behavior.
///
/// # Panics
///
Expand Down Expand Up @@ -1678,10 +1679,13 @@ impl String {
drop(guard);
}

/// Inserts a character into this `String` at a byte position.
/// Inserts a character into this `String` at byte position `idx`.
///
/// Reallocates if `self.capacity()` is insufficient, which may involve copying all
/// `self.capacity()` bytes. Makes space for the insertion by copying all bytes of
/// `&self[idx..]` to new positions.
///
/// This is an *O*(*n*) operation as it requires copying every element in the
/// buffer.
/// Note that calling this in a loop can result in quadratic behavior.
///
/// # Panics
///
Expand Down Expand Up @@ -1733,10 +1737,13 @@ impl String {
}
}

/// Inserts a string slice into this `String` at a byte position.
/// Inserts a string slice into this `String` at byte position `idx`.
///
/// Reallocates if `self.capacity()` is insufficient, which may involve copying all
/// `self.capacity()` bytes. Makes space for the insertion by copying all bytes of
/// `&self[idx..]` to new positions.
///
/// This is an *O*(*n*) operation as it requires copying every element in the
/// buffer.
/// Note that calling this in a loop can result in quadratic behavior.
///
/// # Panics
///
Expand Down
66 changes: 30 additions & 36 deletions core/src/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,7 @@ impl<T, const N: usize> Cell<[T; N]> {
#[rustc_diagnostic_item = "RefCell"]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct RefCell<T: ?Sized> {
borrow: Cell<BorrowFlag>,
borrow: Cell<BorrowCounter>,
// Stores the location of the earliest currently active borrow.
// This gets updated whenever we go from having zero borrows
// to having a single borrow. When a borrow occurs, this gets included
Expand All @@ -732,54 +732,48 @@ pub struct RefCell<T: ?Sized> {
/// An error returned by [`RefCell::try_borrow`].
#[stable(feature = "try_borrow", since = "1.13.0")]
#[non_exhaustive]
#[derive(Debug)]
pub struct BorrowError {
#[cfg(feature = "debug_refcell")]
location: &'static crate::panic::Location<'static>,
}

#[stable(feature = "try_borrow", since = "1.13.0")]
impl Debug for BorrowError {
impl Display for BorrowError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut builder = f.debug_struct("BorrowError");

#[cfg(feature = "debug_refcell")]
builder.field("location", self.location);
let res = write!(
f,
"RefCell already mutably borrowed; a previous borrow was at {}",
self.location
);

builder.finish()
}
}
#[cfg(not(feature = "debug_refcell"))]
let res = Display::fmt("RefCell already mutably borrowed", f);

#[stable(feature = "try_borrow", since = "1.13.0")]
impl Display for BorrowError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt("already mutably borrowed", f)
res
}
}

/// An error returned by [`RefCell::try_borrow_mut`].
#[stable(feature = "try_borrow", since = "1.13.0")]
#[non_exhaustive]
#[derive(Debug)]
pub struct BorrowMutError {
#[cfg(feature = "debug_refcell")]
location: &'static crate::panic::Location<'static>,
}

#[stable(feature = "try_borrow", since = "1.13.0")]
impl Debug for BorrowMutError {
impl Display for BorrowMutError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut builder = f.debug_struct("BorrowMutError");

#[cfg(feature = "debug_refcell")]
builder.field("location", self.location);
let res = write!(f, "RefCell already borrowed; a previous borrow was at {}", self.location);

builder.finish()
}
}
#[cfg(not(feature = "debug_refcell"))]
let res = Display::fmt("RefCell already borrowed", f);

#[stable(feature = "try_borrow", since = "1.13.0")]
impl Display for BorrowMutError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt("already borrowed", f)
res
}
}

Expand All @@ -788,15 +782,15 @@ impl Display for BorrowMutError {
#[track_caller]
#[cold]
fn panic_already_borrowed(err: BorrowMutError) -> ! {
panic!("already borrowed: {:?}", err)
panic!("{err}")
}

// This ensures the panicking code is outlined from `borrow` for `RefCell`.
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
#[track_caller]
#[cold]
fn panic_already_mutably_borrowed(err: BorrowError) -> ! {
panic!("already mutably borrowed: {:?}", err)
panic!("{err}")
}

// Positive values represent the number of `Ref` active. Negative values
Expand All @@ -806,22 +800,22 @@ fn panic_already_mutably_borrowed(err: BorrowError) -> ! {
//
// `Ref` and `RefMut` are both two words in size, and so there will likely never
// be enough `Ref`s or `RefMut`s in existence to overflow half of the `usize`
// range. Thus, a `BorrowFlag` will probably never overflow or underflow.
// range. Thus, a `BorrowCounter` will probably never overflow or underflow.
// However, this is not a guarantee, as a pathological program could repeatedly
// create and then mem::forget `Ref`s or `RefMut`s. Thus, all code must
// explicitly check for overflow and underflow in order to avoid unsafety, or at
// least behave correctly in the event that overflow or underflow happens (e.g.,
// see BorrowRef::new).
type BorrowFlag = isize;
const UNUSED: BorrowFlag = 0;
type BorrowCounter = isize;
const UNUSED: BorrowCounter = 0;

#[inline(always)]
fn is_writing(x: BorrowFlag) -> bool {
fn is_writing(x: BorrowCounter) -> bool {
x < UNUSED
}

#[inline(always)]
fn is_reading(x: BorrowFlag) -> bool {
fn is_reading(x: BorrowCounter) -> bool {
x > UNUSED
}

Expand Down Expand Up @@ -1401,12 +1395,12 @@ impl<T> From<T> for RefCell<T> {
impl<T: CoerceUnsized<U>, U> CoerceUnsized<RefCell<U>> for RefCell<T> {}

struct BorrowRef<'b> {
borrow: &'b Cell<BorrowFlag>,
borrow: &'b Cell<BorrowCounter>,
}

impl<'b> BorrowRef<'b> {
#[inline]
fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRef<'b>> {
fn new(borrow: &'b Cell<BorrowCounter>) -> Option<BorrowRef<'b>> {
let b = borrow.get().wrapping_add(1);
if !is_reading(b) {
// Incrementing borrow can result in a non-reading value (<= 0) in these cases:
Expand Down Expand Up @@ -1447,7 +1441,7 @@ impl Clone for BorrowRef<'_> {
debug_assert!(is_reading(borrow));
// Prevent the borrow counter from overflowing into
// a writing borrow.
assert!(borrow != BorrowFlag::MAX);
assert!(borrow != BorrowCounter::MAX);
self.borrow.set(borrow + 1);
BorrowRef { borrow: self.borrow }
}
Expand Down Expand Up @@ -1795,7 +1789,7 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
}

struct BorrowRefMut<'b> {
borrow: &'b Cell<BorrowFlag>,
borrow: &'b Cell<BorrowCounter>,
}

impl Drop for BorrowRefMut<'_> {
Expand All @@ -1809,7 +1803,7 @@ impl Drop for BorrowRefMut<'_> {

impl<'b> BorrowRefMut<'b> {
#[inline]
fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRefMut<'b>> {
fn new(borrow: &'b Cell<BorrowCounter>) -> Option<BorrowRefMut<'b>> {
// NOTE: Unlike BorrowRefMut::clone, new is called to create the initial
// mutable reference, and so there must currently be no existing
// references. Thus, while clone increments the mutable refcount, here
Expand All @@ -1833,7 +1827,7 @@ impl<'b> BorrowRefMut<'b> {
let borrow = self.borrow.get();
debug_assert!(is_writing(borrow));
// Prevent the borrow counter from underflowing.
assert!(borrow != BorrowFlag::MIN);
assert!(borrow != BorrowCounter::MIN);
self.borrow.set(borrow - 1);
BorrowRefMut { borrow: self.borrow }
}
Expand Down
16 changes: 10 additions & 6 deletions core/src/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@

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

use crate::marker::PointeeSized;

mod uninit;

/// A common trait that allows explicit creation of a duplicate value.
Expand Down Expand Up @@ -283,7 +285,7 @@ impl_use_cloned! {
reason = "deriving hack, should not be public",
issue = "none"
)]
pub struct AssertParamIsClone<T: Clone + ?Sized> {
pub struct AssertParamIsClone<T: Clone + PointeeSized> {
_field: crate::marker::PhantomData<T>,
}
#[doc(hidden)]
Expand All @@ -293,7 +295,7 @@ pub struct AssertParamIsClone<T: Clone + ?Sized> {
reason = "deriving hack, should not be public",
issue = "none"
)]
pub struct AssertParamIsCopy<T: Copy + ?Sized> {
pub struct AssertParamIsCopy<T: Copy + PointeeSized> {
_field: crate::marker::PhantomData<T>,
}

Expand Down Expand Up @@ -530,6 +532,8 @@ unsafe impl CloneToUninit for crate::bstr::ByteStr {
/// are implemented in `traits::SelectionContext::copy_clone_conditions()`
/// in `rustc_trait_selection`.
mod impls {
use crate::marker::PointeeSized;

macro_rules! impl_clone {
($($t:ty)*) => {
$(
Expand Down Expand Up @@ -560,15 +564,15 @@ mod impls {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Clone for *const T {
impl<T: PointeeSized> Clone for *const T {
#[inline(always)]
fn clone(&self) -> Self {
*self
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Clone for *mut T {
impl<T: PointeeSized> Clone for *mut T {
#[inline(always)]
fn clone(&self) -> Self {
*self
Expand All @@ -577,7 +581,7 @@ mod impls {

/// Shared references can be cloned, but mutable references *cannot*!
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Clone for &T {
impl<T: PointeeSized> Clone for &T {
#[inline(always)]
#[rustc_diagnostic_item = "noop_method_clone"]
fn clone(&self) -> Self {
Expand All @@ -587,5 +591,5 @@ mod impls {

/// Shared references can be cloned, but mutable references *cannot*!
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> !Clone for &mut T {}
impl<T: PointeeSized> !Clone for &mut T {}
}
Loading