Skip to content

Commit a46ec5c

Browse files
committed
Auto merge of rust-lang#142613 - workingjubilee:rollup-yuod2hg, r=workingjubilee
Rollup of 13 pull requests Successful merges: - rust-lang#138538 (Make performance description of String::{insert,insert_str,remove} more precise) - rust-lang#141946 (std: refactor explanation of `NonNull`) - rust-lang#142216 (Miscellaneous RefCell cleanups) - rust-lang#142542 (Manually invalidate caches in SimplifyCfg.) - rust-lang#142563 (Refine run-make test ignores due to unpredictable `i686-pc-windows-gnu` unwind mechanism) - rust-lang#142570 (Reject union default field values) - rust-lang#142584 (Handle same-crate macro for borrowck semicolon suggestion) - rust-lang#142585 (Update books) - rust-lang#142586 (Fold unnecessary `visit_struct_field_def` in AstValidator) - rust-lang#142587 (Make sure to propagate result from `visit_expr_fields`) - rust-lang#142595 (Revert overeager warning for misuse of `--print native-static-libs`) - rust-lang#142598 (Set elf e_flags on ppc64 targets according to abi) - rust-lang#142601 (Add a comment to `FORMAT_VERSION`.) r? `@ghost` `@rustbot` modify labels: rollup
2 parents c0dc1e7 + 7e2f21a commit a46ec5c

File tree

3 files changed

+62
-56
lines changed

3 files changed

+62
-56
lines changed

alloc/src/string.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1489,10 +1489,11 @@ impl String {
14891489
Some(ch)
14901490
}
14911491

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

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

1736-
/// Inserts a string slice into this `String` at a byte position.
1740+
/// Inserts a string slice into this `String` at byte position `idx`.
1741+
///
1742+
/// Reallocates if `self.capacity()` is insufficient, which may involve copying all
1743+
/// `self.capacity()` bytes. Makes space for the insertion by copying all bytes of
1744+
/// `&self[idx..]` to new positions.
17371745
///
1738-
/// This is an *O*(*n*) operation as it requires copying every element in the
1739-
/// buffer.
1746+
/// Note that calling this in a loop can result in quadratic behavior.
17401747
///
17411748
/// # Panics
17421749
///

core/src/cell.rs

Lines changed: 30 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -719,7 +719,7 @@ impl<T, const N: usize> Cell<[T; N]> {
719719
#[rustc_diagnostic_item = "RefCell"]
720720
#[stable(feature = "rust1", since = "1.0.0")]
721721
pub struct RefCell<T: ?Sized> {
722-
borrow: Cell<BorrowFlag>,
722+
borrow: Cell<BorrowCounter>,
723723
// Stores the location of the earliest currently active borrow.
724724
// This gets updated whenever we go from having zero borrows
725725
// to having a single borrow. When a borrow occurs, this gets included
@@ -732,54 +732,48 @@ pub struct RefCell<T: ?Sized> {
732732
/// An error returned by [`RefCell::try_borrow`].
733733
#[stable(feature = "try_borrow", since = "1.13.0")]
734734
#[non_exhaustive]
735+
#[derive(Debug)]
735736
pub struct BorrowError {
736737
#[cfg(feature = "debug_refcell")]
737738
location: &'static crate::panic::Location<'static>,
738739
}
739740

740741
#[stable(feature = "try_borrow", since = "1.13.0")]
741-
impl Debug for BorrowError {
742+
impl Display for BorrowError {
742743
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
743-
let mut builder = f.debug_struct("BorrowError");
744-
745744
#[cfg(feature = "debug_refcell")]
746-
builder.field("location", self.location);
745+
let res = write!(
746+
f,
747+
"RefCell already mutably borrowed; a previous borrow was at {}",
748+
self.location
749+
);
747750

748-
builder.finish()
749-
}
750-
}
751+
#[cfg(not(feature = "debug_refcell"))]
752+
let res = Display::fmt("RefCell already mutably borrowed", f);
751753

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

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

767767
#[stable(feature = "try_borrow", since = "1.13.0")]
768-
impl Debug for BorrowMutError {
768+
impl Display for BorrowMutError {
769769
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
770-
let mut builder = f.debug_struct("BorrowMutError");
771-
772770
#[cfg(feature = "debug_refcell")]
773-
builder.field("location", self.location);
771+
let res = write!(f, "RefCell already borrowed; a previous borrow was at {}", self.location);
774772

775-
builder.finish()
776-
}
777-
}
773+
#[cfg(not(feature = "debug_refcell"))]
774+
let res = Display::fmt("RefCell already borrowed", f);
778775

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

@@ -788,15 +782,15 @@ impl Display for BorrowMutError {
788782
#[track_caller]
789783
#[cold]
790784
fn panic_already_borrowed(err: BorrowMutError) -> ! {
791-
panic!("already borrowed: {:?}", err)
785+
panic!("{err}")
792786
}
793787

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

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

818812
#[inline(always)]
819-
fn is_writing(x: BorrowFlag) -> bool {
813+
fn is_writing(x: BorrowCounter) -> bool {
820814
x < UNUSED
821815
}
822816

823817
#[inline(always)]
824-
fn is_reading(x: BorrowFlag) -> bool {
818+
fn is_reading(x: BorrowCounter) -> bool {
825819
x > UNUSED
826820
}
827821

@@ -1401,12 +1395,12 @@ impl<T> From<T> for RefCell<T> {
14011395
impl<T: CoerceUnsized<U>, U> CoerceUnsized<RefCell<U>> for RefCell<T> {}
14021396

14031397
struct BorrowRef<'b> {
1404-
borrow: &'b Cell<BorrowFlag>,
1398+
borrow: &'b Cell<BorrowCounter>,
14051399
}
14061400

14071401
impl<'b> BorrowRef<'b> {
14081402
#[inline]
1409-
fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRef<'b>> {
1403+
fn new(borrow: &'b Cell<BorrowCounter>) -> Option<BorrowRef<'b>> {
14101404
let b = borrow.get().wrapping_add(1);
14111405
if !is_reading(b) {
14121406
// Incrementing borrow can result in a non-reading value (<= 0) in these cases:
@@ -1447,7 +1441,7 @@ impl Clone for BorrowRef<'_> {
14471441
debug_assert!(is_reading(borrow));
14481442
// Prevent the borrow counter from overflowing into
14491443
// a writing borrow.
1450-
assert!(borrow != BorrowFlag::MAX);
1444+
assert!(borrow != BorrowCounter::MAX);
14511445
self.borrow.set(borrow + 1);
14521446
BorrowRef { borrow: self.borrow }
14531447
}
@@ -1795,7 +1789,7 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
17951789
}
17961790

17971791
struct BorrowRefMut<'b> {
1798-
borrow: &'b Cell<BorrowFlag>,
1792+
borrow: &'b Cell<BorrowCounter>,
17991793
}
18001794

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

18101804
impl<'b> BorrowRefMut<'b> {
18111805
#[inline]
1812-
fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRefMut<'b>> {
1806+
fn new(borrow: &'b Cell<BorrowCounter>) -> Option<BorrowRefMut<'b>> {
18131807
// NOTE: Unlike BorrowRefMut::clone, new is called to create the initial
18141808
// mutable reference, and so there must currently be no existing
18151809
// references. Thus, while clone increments the mutable refcount, here
@@ -1833,7 +1827,7 @@ impl<'b> BorrowRefMut<'b> {
18331827
let borrow = self.borrow.get();
18341828
debug_assert!(is_writing(borrow));
18351829
// Prevent the borrow counter from underflowing.
1836-
assert!(borrow != BorrowFlag::MIN);
1830+
assert!(borrow != BorrowCounter::MIN);
18371831
self.borrow.set(borrow - 1);
18381832
BorrowRefMut { borrow: self.borrow }
18391833
}

core/src/ptr/non_null.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,24 @@ use crate::{fmt, hash, intrinsics, mem, ptr};
2020
/// as a discriminant -- `Option<NonNull<T>>` has the same size as `*mut T`.
2121
/// However the pointer may still dangle if it isn't dereferenced.
2222
///
23-
/// Unlike `*mut T`, `NonNull<T>` was chosen to be covariant over `T`. This makes it
24-
/// possible to use `NonNull<T>` when building covariant types, but introduces the
25-
/// risk of unsoundness if used in a type that shouldn't actually be covariant.
26-
/// (The opposite choice was made for `*mut T` even though technically the unsoundness
27-
/// could only be caused by calling unsafe functions.)
23+
/// Unlike `*mut T`, `NonNull<T>` is covariant over `T`. This is usually the correct
24+
/// choice for most data structures and safe abstractions, such as `Box`, `Rc`, `Arc`, `Vec`,
25+
/// and `LinkedList`.
2826
///
29-
/// Covariance is correct for most safe abstractions, such as `Box`, `Rc`, `Arc`, `Vec`,
30-
/// and `LinkedList`. This is the case because they provide a public API that follows the
31-
/// normal shared XOR mutable rules of Rust.
27+
/// In rare cases, if your type exposes a way to mutate the value of `T` through a `NonNull<T>`,
28+
/// and you need to prevent unsoundness from variance (for example, if `T` could be a reference
29+
/// with a shorter lifetime), you should add a field to make your type invariant, such as
30+
/// `PhantomData<Cell<T>>` or `PhantomData<&'a mut T>`.
3231
///
33-
/// If your type cannot safely be covariant, you must ensure it contains some
34-
/// additional field to provide invariance. Often this field will be a [`PhantomData`]
35-
/// type like `PhantomData<Cell<T>>` or `PhantomData<&'a mut T>`.
32+
/// Example of a type that must be invariant:
33+
/// ```rust
34+
/// use std::cell::Cell;
35+
/// use std::marker::PhantomData;
36+
/// struct Invariant<T> {
37+
/// ptr: std::ptr::NonNull<T>,
38+
/// _invariant: PhantomData<Cell<T>>,
39+
/// }
40+
/// ```
3641
///
3742
/// Notice that `NonNull<T>` has a `From` instance for `&T`. However, this does
3843
/// not change the fact that mutating through a (pointer derived from a) shared

0 commit comments

Comments
 (0)