Skip to content

Commit f0d4b57

Browse files
committed
Auto merge of #67342 - Centril:rollup-fl44n41, r=Centril
Rollup of 7 pull requests Successful merges: - #65778 (Stabilize `std::{rc,sync}::Weak::{weak_count, strong_count}`) - #66570 (stabilize Result::map_or) - #66735 (Add str::strip_prefix and str::strip_suffix) - #66771 (Stabilize the `core::panic` module) - #67317 (fix type_name_of_val doc comment) - #67324 (Fix repetition in matches/mod.rs) - #67325 (cleanup with push_fake_read) Failed merges: r? @ghost
2 parents a605441 + 71a9a99 commit f0d4b57

File tree

14 files changed

+146
-114
lines changed

14 files changed

+146
-114
lines changed

src/liballoc/rc.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -1836,7 +1836,7 @@ impl<T: ?Sized> Weak<T> {
18361836
/// If `self` was created using [`Weak::new`], this will return 0.
18371837
///
18381838
/// [`Weak::new`]: #method.new
1839-
#[unstable(feature = "weak_counts", issue = "57977")]
1839+
#[stable(feature = "weak_counts", since = "1.41.0")]
18401840
pub fn strong_count(&self) -> usize {
18411841
if let Some(inner) = self.inner() {
18421842
inner.strong()
@@ -1847,20 +1847,16 @@ impl<T: ?Sized> Weak<T> {
18471847

18481848
/// Gets the number of `Weak` pointers pointing to this allocation.
18491849
///
1850-
/// If `self` was created using [`Weak::new`], this will return `None`. If
1851-
/// not, the returned value is at least 1, since `self` still points to the
1852-
/// allocation.
1853-
///
1854-
/// [`Weak::new`]: #method.new
1855-
#[unstable(feature = "weak_counts", issue = "57977")]
1856-
pub fn weak_count(&self) -> Option<usize> {
1850+
/// If no strong pointers remain, this will return zero.
1851+
#[stable(feature = "weak_counts", since = "1.41.0")]
1852+
pub fn weak_count(&self) -> usize {
18571853
self.inner().map(|inner| {
18581854
if inner.strong() > 0 {
18591855
inner.weak() - 1 // subtract the implicit weak ptr
18601856
} else {
1861-
inner.weak()
1857+
0
18621858
}
1863-
})
1859+
}).unwrap_or(0)
18641860
}
18651861

18661862
/// Returns `None` when the pointer is dangling and there is no allocated `RcBox`

src/liballoc/rc/tests.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -114,28 +114,28 @@ fn test_weak_count() {
114114

115115
#[test]
116116
fn weak_counts() {
117-
assert_eq!(Weak::weak_count(&Weak::<u64>::new()), None);
117+
assert_eq!(Weak::weak_count(&Weak::<u64>::new()), 0);
118118
assert_eq!(Weak::strong_count(&Weak::<u64>::new()), 0);
119119

120120
let a = Rc::new(0);
121121
let w = Rc::downgrade(&a);
122122
assert_eq!(Weak::strong_count(&w), 1);
123-
assert_eq!(Weak::weak_count(&w), Some(1));
123+
assert_eq!(Weak::weak_count(&w), 1);
124124
let w2 = w.clone();
125125
assert_eq!(Weak::strong_count(&w), 1);
126-
assert_eq!(Weak::weak_count(&w), Some(2));
126+
assert_eq!(Weak::weak_count(&w), 2);
127127
assert_eq!(Weak::strong_count(&w2), 1);
128-
assert_eq!(Weak::weak_count(&w2), Some(2));
128+
assert_eq!(Weak::weak_count(&w2), 2);
129129
drop(w);
130130
assert_eq!(Weak::strong_count(&w2), 1);
131-
assert_eq!(Weak::weak_count(&w2), Some(1));
131+
assert_eq!(Weak::weak_count(&w2), 1);
132132
let a2 = a.clone();
133133
assert_eq!(Weak::strong_count(&w2), 2);
134-
assert_eq!(Weak::weak_count(&w2), Some(1));
134+
assert_eq!(Weak::weak_count(&w2), 1);
135135
drop(a2);
136136
drop(a);
137137
assert_eq!(Weak::strong_count(&w2), 0);
138-
assert_eq!(Weak::weak_count(&w2), Some(1));
138+
assert_eq!(Weak::weak_count(&w2), 0);
139139
drop(w2);
140140
}
141141

src/liballoc/sync.rs

+15-25
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use core::sync::atomic;
1212
use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst};
1313
use core::borrow;
1414
use core::fmt;
15-
use core::cmp::{self, Ordering};
15+
use core::cmp::Ordering;
1616
use core::iter;
1717
use core::intrinsics::abort;
1818
use core::mem::{self, align_of, align_of_val, size_of_val};
@@ -1529,7 +1529,7 @@ impl<T: ?Sized> Weak<T> {
15291529
/// If `self` was created using [`Weak::new`], this will return 0.
15301530
///
15311531
/// [`Weak::new`]: #method.new
1532-
#[unstable(feature = "weak_counts", issue = "57977")]
1532+
#[stable(feature = "weak_counts", since = "1.41.0")]
15331533
pub fn strong_count(&self) -> usize {
15341534
if let Some(inner) = self.inner() {
15351535
inner.strong.load(SeqCst)
@@ -1541,9 +1541,8 @@ impl<T: ?Sized> Weak<T> {
15411541
/// Gets an approximation of the number of `Weak` pointers pointing to this
15421542
/// allocation.
15431543
///
1544-
/// If `self` was created using [`Weak::new`], this will return 0. If not,
1545-
/// the returned value is at least 1, since `self` still points to the
1546-
/// allocation.
1544+
/// If `self` was created using [`Weak::new`], or if there are no remaining
1545+
/// strong pointers, this will return 0.
15471546
///
15481547
/// # Accuracy
15491548
///
@@ -1552,31 +1551,22 @@ impl<T: ?Sized> Weak<T> {
15521551
/// `Weak`s pointing to the same allocation.
15531552
///
15541553
/// [`Weak::new`]: #method.new
1555-
#[unstable(feature = "weak_counts", issue = "57977")]
1556-
pub fn weak_count(&self) -> Option<usize> {
1557-
// Due to the implicit weak pointer added when any strong pointers are
1558-
// around, we cannot implement `weak_count` correctly since it
1559-
// necessarily requires accessing the strong count and weak count in an
1560-
// unsynchronized fashion. So this version is a bit racy.
1554+
#[stable(feature = "weak_counts", since = "1.41.0")]
1555+
pub fn weak_count(&self) -> usize {
15611556
self.inner().map(|inner| {
1562-
let strong = inner.strong.load(SeqCst);
15631557
let weak = inner.weak.load(SeqCst);
1558+
let strong = inner.strong.load(SeqCst);
15641559
if strong == 0 {
1565-
// If the last `Arc` has *just* been dropped, it might not yet
1566-
// have removed the implicit weak count, so the value we get
1567-
// here might be 1 too high.
1568-
weak
1560+
0
15691561
} else {
1570-
// As long as there's still at least 1 `Arc` around, subtract
1571-
// the implicit weak pointer.
1572-
// Note that the last `Arc` might get dropped between the 2
1573-
// loads we do above, removing the implicit weak pointer. This
1574-
// means that the value might be 1 too low here. In order to not
1575-
// return 0 here (which would happen if we're the only weak
1576-
// pointer), we guard against that specifically.
1577-
cmp::max(1, weak - 1)
1562+
// Since we observed that there was at least one strong pointer
1563+
// after reading the weak count, we know that the implicit weak
1564+
// reference (present whenever any strong references are alive)
1565+
// was still around when we observed the weak count, and can
1566+
// therefore safely subtract it.
1567+
weak - 1
15781568
}
1579-
})
1569+
}).unwrap_or(0)
15801570
}
15811571

15821572
/// Returns `None` when the pointer is dangling and there is no allocated `ArcInner`,

src/liballoc/sync/tests.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -62,28 +62,28 @@ fn test_arc_get_mut() {
6262

6363
#[test]
6464
fn weak_counts() {
65-
assert_eq!(Weak::weak_count(&Weak::<u64>::new()), None);
65+
assert_eq!(Weak::weak_count(&Weak::<u64>::new()), 0);
6666
assert_eq!(Weak::strong_count(&Weak::<u64>::new()), 0);
6767

6868
let a = Arc::new(0);
6969
let w = Arc::downgrade(&a);
7070
assert_eq!(Weak::strong_count(&w), 1);
71-
assert_eq!(Weak::weak_count(&w), Some(1));
71+
assert_eq!(Weak::weak_count(&w), 1);
7272
let w2 = w.clone();
7373
assert_eq!(Weak::strong_count(&w), 1);
74-
assert_eq!(Weak::weak_count(&w), Some(2));
74+
assert_eq!(Weak::weak_count(&w), 2);
7575
assert_eq!(Weak::strong_count(&w2), 1);
76-
assert_eq!(Weak::weak_count(&w2), Some(2));
76+
assert_eq!(Weak::weak_count(&w2), 2);
7777
drop(w);
7878
assert_eq!(Weak::strong_count(&w2), 1);
79-
assert_eq!(Weak::weak_count(&w2), Some(1));
79+
assert_eq!(Weak::weak_count(&w2), 1);
8080
let a2 = a.clone();
8181
assert_eq!(Weak::strong_count(&w2), 2);
82-
assert_eq!(Weak::weak_count(&w2), Some(1));
82+
assert_eq!(Weak::weak_count(&w2), 1);
8383
drop(a2);
8484
drop(a);
8585
assert_eq!(Weak::strong_count(&w2), 0);
86-
assert_eq!(Weak::weak_count(&w2), Some(1));
86+
assert_eq!(Weak::weak_count(&w2), 0);
8787
drop(w2);
8888
}
8989

src/libcore/any.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ pub const fn type_name<T: ?Sized>() -> &'static str {
476476
///
477477
/// This is intended for diagnostic use. The exact contents and format of the
478478
/// string are not specified, other than being a best-effort description of the
479-
/// type. For example, `type_name_of::<Option<String>>(None)` could return the
479+
/// type. For example, `type_name_of::<Option<String>>(None)` could return
480480
/// `"Option<String>"` or `"std::option::Option<std::string::String>"`, but not
481481
/// `"foobar"`. In addition, the output may change between versions of the
482482
/// compiler.

src/libcore/panic.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
//! Panic support in the standard library.
22
3-
#![unstable(feature = "core_panic_info",
4-
reason = "newly available in libcore",
5-
issue = "44489")]
3+
#![stable(feature = "core_panic_info", since = "1.41.0")]
64

75
use crate::any::Any;
86
use crate::fmt;
@@ -39,10 +37,10 @@ pub struct PanicInfo<'a> {
3937
}
4038

4139
impl<'a> PanicInfo<'a> {
42-
#![unstable(feature = "panic_internals",
43-
reason = "internal details of the implementation of the `panic!` \
44-
and related macros",
45-
issue = "0")]
40+
#[unstable(feature = "panic_internals",
41+
reason = "internal details of the implementation of the `panic!` \
42+
and related macros",
43+
issue = "0")]
4644
#[doc(hidden)]
4745
#[inline]
4846
pub fn internal_constructor(
@@ -57,6 +55,10 @@ impl<'a> PanicInfo<'a> {
5755
}
5856
}
5957

58+
#[unstable(feature = "panic_internals",
59+
reason = "internal details of the implementation of the `panic!` \
60+
and related macros",
61+
issue = "0")]
6062
#[doc(hidden)]
6163
#[inline]
6264
pub fn set_payload(&mut self, info: &'a (dyn Any + Send)) {
@@ -90,7 +92,7 @@ impl<'a> PanicInfo<'a> {
9092
/// returns that message ready to be used for example with [`fmt::write`]
9193
///
9294
/// [`fmt::write`]: ../fmt/fn.write.html
93-
#[unstable(feature = "panic_info_message", issue = "44489")]
95+
#[unstable(feature = "panic_info_message", issue = "66745")]
9496
pub fn message(&self) -> Option<&fmt::Arguments<'_>> {
9597
self.message
9698
}

src/libcore/result.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -520,15 +520,14 @@ impl<T, E> Result<T, E> {
520520
/// # Examples
521521
///
522522
/// ```
523-
/// #![feature(result_map_or)]
524523
/// let x: Result<_, &str> = Ok("foo");
525524
/// assert_eq!(x.map_or(42, |v| v.len()), 3);
526525
///
527526
/// let x: Result<&str, _> = Err("bar");
528527
/// assert_eq!(x.map_or(42, |v| v.len()), 42);
529528
/// ```
530529
#[inline]
531-
#[unstable(feature = "result_map_or", issue = "66293")]
530+
#[stable(feature = "result_map_or", since = "1.41.0")]
532531
pub fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U {
533532
match self {
534533
Ok(t) => f(t),

src/libcore/str/mod.rs

+72-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#![stable(feature = "rust1", since = "1.0.0")]
99

1010
use self::pattern::Pattern;
11-
use self::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
11+
use self::pattern::{Searcher, SearchStep, ReverseSearcher, DoubleEndedSearcher};
1212

1313
use crate::char;
1414
use crate::fmt::{self, Write};
@@ -3798,6 +3798,77 @@ impl str {
37983798
}
37993799
}
38003800

3801+
/// Returns a string slice with the prefix removed.
3802+
///
3803+
/// If the string starts with the pattern `prefix`, `Some` is returned with the substring where
3804+
/// the prefix is removed. Unlike `trim_start_matches`, this method removes the prefix exactly
3805+
/// once.
3806+
///
3807+
/// If the string does not start with `prefix`, `None` is returned.
3808+
///
3809+
/// # Examples
3810+
///
3811+
/// ```
3812+
/// #![feature(str_strip)]
3813+
///
3814+
/// assert_eq!("foobar".strip_prefix("foo"), Some("bar"));
3815+
/// assert_eq!("foobar".strip_prefix("bar"), None);
3816+
/// assert_eq!("foofoo".strip_prefix("foo"), Some("foo"));
3817+
/// ```
3818+
#[must_use = "this returns the remaining substring as a new slice, \
3819+
without modifying the original"]
3820+
#[unstable(feature = "str_strip", reason = "newly added", issue = "67302")]
3821+
pub fn strip_prefix<'a, P: Pattern<'a>>(&'a self, prefix: P) -> Option<&'a str> {
3822+
let mut matcher = prefix.into_searcher(self);
3823+
if let SearchStep::Match(start, len) = matcher.next() {
3824+
debug_assert_eq!(start, 0, "The first search step from Searcher \
3825+
must include the first character");
3826+
unsafe {
3827+
// Searcher is known to return valid indices.
3828+
Some(self.get_unchecked(len..))
3829+
}
3830+
} else {
3831+
None
3832+
}
3833+
}
3834+
3835+
/// Returns a string slice with the suffix removed.
3836+
///
3837+
/// If the string ends with the pattern `suffix`, `Some` is returned with the substring where
3838+
/// the suffix is removed. Unlike `trim_end_matches`, this method removes the suffix exactly
3839+
/// once.
3840+
///
3841+
/// If the string does not end with `suffix`, `None` is returned.
3842+
///
3843+
/// # Examples
3844+
///
3845+
/// ```
3846+
/// #![feature(str_strip)]
3847+
/// assert_eq!("barfoo".strip_suffix("foo"), Some("bar"));
3848+
/// assert_eq!("barfoo".strip_suffix("bar"), None);
3849+
/// assert_eq!("foofoo".strip_suffix("foo"), Some("foo"));
3850+
/// ```
3851+
#[must_use = "this returns the remaining substring as a new slice, \
3852+
without modifying the original"]
3853+
#[unstable(feature = "str_strip", reason = "newly added", issue = "67302")]
3854+
pub fn strip_suffix<'a, P>(&'a self, suffix: P) -> Option<&'a str>
3855+
where
3856+
P: Pattern<'a>,
3857+
<P as Pattern<'a>>::Searcher: ReverseSearcher<'a>,
3858+
{
3859+
let mut matcher = suffix.into_searcher(self);
3860+
if let SearchStep::Match(start, end) = matcher.next_back() {
3861+
debug_assert_eq!(end, self.len(), "The first search step from ReverseSearcher \
3862+
must include the last character");
3863+
unsafe {
3864+
// Searcher is known to return valid indices.
3865+
Some(self.get_unchecked(..start))
3866+
}
3867+
} else {
3868+
None
3869+
}
3870+
}
3871+
38013872
/// Returns a string slice with all suffixes that match a pattern
38023873
/// repeatedly removed.
38033874
///

src/librustc_mir/build/cfg.rs

+12
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,18 @@ impl<'tcx> CFG<'tcx> {
5959
));
6060
}
6161

62+
pub fn push_fake_read(
63+
&mut self,
64+
block: BasicBlock,
65+
source_info: SourceInfo,
66+
cause: FakeReadCause,
67+
place: Place<'tcx>,
68+
) {
69+
let kind = StatementKind::FakeRead(cause, box place);
70+
let stmt = Statement { source_info, kind };
71+
self.push(block, stmt);
72+
}
73+
6274
pub fn terminate(&mut self,
6375
block: BasicBlock,
6476
source_info: SourceInfo,

src/librustc_mir/build/expr/as_place.rs

+2-11
Original file line numberDiff line numberDiff line change
@@ -484,24 +484,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
484484

485485
fn read_fake_borrows(
486486
&mut self,
487-
block: BasicBlock,
487+
bb: BasicBlock,
488488
fake_borrow_temps: &mut Vec<Local>,
489489
source_info: SourceInfo,
490490
) {
491491
// All indexes have been evaluated now, read all of the
492492
// fake borrows so that they are live across those index
493493
// expressions.
494494
for temp in fake_borrow_temps {
495-
self.cfg.push(
496-
block,
497-
Statement {
498-
source_info,
499-
kind: StatementKind::FakeRead(
500-
FakeReadCause::ForIndex,
501-
Box::new(Place::from(*temp)),
502-
)
503-
}
504-
);
495+
self.cfg.push_fake_read(bb, source_info, FakeReadCause::ForIndex, Place::from(*temp));
505496
}
506497
}
507498
}

0 commit comments

Comments
 (0)