Skip to content

Commit

Permalink
Auto merge of #67342 - Centril:rollup-fl44n41, r=Centril
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Dec 16, 2019
2 parents a605441 + 71a9a99 commit f0d4b57
Show file tree
Hide file tree
Showing 14 changed files with 146 additions and 114 deletions.
16 changes: 6 additions & 10 deletions src/liballoc/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1836,7 +1836,7 @@ impl<T: ?Sized> Weak<T> {
/// If `self` was created using [`Weak::new`], this will return 0.
///
/// [`Weak::new`]: #method.new
#[unstable(feature = "weak_counts", issue = "57977")]
#[stable(feature = "weak_counts", since = "1.41.0")]
pub fn strong_count(&self) -> usize {
if let Some(inner) = self.inner() {
inner.strong()
Expand All @@ -1847,20 +1847,16 @@ impl<T: ?Sized> Weak<T> {

/// Gets the number of `Weak` pointers pointing to this allocation.
///
/// If `self` was created using [`Weak::new`], this will return `None`. If
/// not, the returned value is at least 1, since `self` still points to the
/// allocation.
///
/// [`Weak::new`]: #method.new
#[unstable(feature = "weak_counts", issue = "57977")]
pub fn weak_count(&self) -> Option<usize> {
/// If no strong pointers remain, this will return zero.
#[stable(feature = "weak_counts", since = "1.41.0")]
pub fn weak_count(&self) -> usize {
self.inner().map(|inner| {
if inner.strong() > 0 {
inner.weak() - 1 // subtract the implicit weak ptr
} else {
inner.weak()
0
}
})
}).unwrap_or(0)
}

/// Returns `None` when the pointer is dangling and there is no allocated `RcBox`
Expand Down
14 changes: 7 additions & 7 deletions src/liballoc/rc/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,28 +114,28 @@ fn test_weak_count() {

#[test]
fn weak_counts() {
assert_eq!(Weak::weak_count(&Weak::<u64>::new()), None);
assert_eq!(Weak::weak_count(&Weak::<u64>::new()), 0);
assert_eq!(Weak::strong_count(&Weak::<u64>::new()), 0);

let a = Rc::new(0);
let w = Rc::downgrade(&a);
assert_eq!(Weak::strong_count(&w), 1);
assert_eq!(Weak::weak_count(&w), Some(1));
assert_eq!(Weak::weak_count(&w), 1);
let w2 = w.clone();
assert_eq!(Weak::strong_count(&w), 1);
assert_eq!(Weak::weak_count(&w), Some(2));
assert_eq!(Weak::weak_count(&w), 2);
assert_eq!(Weak::strong_count(&w2), 1);
assert_eq!(Weak::weak_count(&w2), Some(2));
assert_eq!(Weak::weak_count(&w2), 2);
drop(w);
assert_eq!(Weak::strong_count(&w2), 1);
assert_eq!(Weak::weak_count(&w2), Some(1));
assert_eq!(Weak::weak_count(&w2), 1);
let a2 = a.clone();
assert_eq!(Weak::strong_count(&w2), 2);
assert_eq!(Weak::weak_count(&w2), Some(1));
assert_eq!(Weak::weak_count(&w2), 1);
drop(a2);
drop(a);
assert_eq!(Weak::strong_count(&w2), 0);
assert_eq!(Weak::weak_count(&w2), Some(1));
assert_eq!(Weak::weak_count(&w2), 0);
drop(w2);
}

Expand Down
40 changes: 15 additions & 25 deletions src/liballoc/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use core::sync::atomic;
use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst};
use core::borrow;
use core::fmt;
use core::cmp::{self, Ordering};
use core::cmp::Ordering;
use core::iter;
use core::intrinsics::abort;
use core::mem::{self, align_of, align_of_val, size_of_val};
Expand Down Expand Up @@ -1529,7 +1529,7 @@ impl<T: ?Sized> Weak<T> {
/// If `self` was created using [`Weak::new`], this will return 0.
///
/// [`Weak::new`]: #method.new
#[unstable(feature = "weak_counts", issue = "57977")]
#[stable(feature = "weak_counts", since = "1.41.0")]
pub fn strong_count(&self) -> usize {
if let Some(inner) = self.inner() {
inner.strong.load(SeqCst)
Expand All @@ -1541,9 +1541,8 @@ impl<T: ?Sized> Weak<T> {
/// Gets an approximation of the number of `Weak` pointers pointing to this
/// allocation.
///
/// If `self` was created using [`Weak::new`], this will return 0. If not,
/// the returned value is at least 1, since `self` still points to the
/// allocation.
/// If `self` was created using [`Weak::new`], or if there are no remaining
/// strong pointers, this will return 0.
///
/// # Accuracy
///
Expand All @@ -1552,31 +1551,22 @@ impl<T: ?Sized> Weak<T> {
/// `Weak`s pointing to the same allocation.
///
/// [`Weak::new`]: #method.new
#[unstable(feature = "weak_counts", issue = "57977")]
pub fn weak_count(&self) -> Option<usize> {
// Due to the implicit weak pointer added when any strong pointers are
// around, we cannot implement `weak_count` correctly since it
// necessarily requires accessing the strong count and weak count in an
// unsynchronized fashion. So this version is a bit racy.
#[stable(feature = "weak_counts", since = "1.41.0")]
pub fn weak_count(&self) -> usize {
self.inner().map(|inner| {
let strong = inner.strong.load(SeqCst);
let weak = inner.weak.load(SeqCst);
let strong = inner.strong.load(SeqCst);
if strong == 0 {
// If the last `Arc` has *just* been dropped, it might not yet
// have removed the implicit weak count, so the value we get
// here might be 1 too high.
weak
0
} else {
// As long as there's still at least 1 `Arc` around, subtract
// the implicit weak pointer.
// Note that the last `Arc` might get dropped between the 2
// loads we do above, removing the implicit weak pointer. This
// means that the value might be 1 too low here. In order to not
// return 0 here (which would happen if we're the only weak
// pointer), we guard against that specifically.
cmp::max(1, weak - 1)
// Since we observed that there was at least one strong pointer
// after reading the weak count, we know that the implicit weak
// reference (present whenever any strong references are alive)
// was still around when we observed the weak count, and can
// therefore safely subtract it.
weak - 1
}
})
}).unwrap_or(0)
}

/// Returns `None` when the pointer is dangling and there is no allocated `ArcInner`,
Expand Down
14 changes: 7 additions & 7 deletions src/liballoc/sync/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,28 +62,28 @@ fn test_arc_get_mut() {

#[test]
fn weak_counts() {
assert_eq!(Weak::weak_count(&Weak::<u64>::new()), None);
assert_eq!(Weak::weak_count(&Weak::<u64>::new()), 0);
assert_eq!(Weak::strong_count(&Weak::<u64>::new()), 0);

let a = Arc::new(0);
let w = Arc::downgrade(&a);
assert_eq!(Weak::strong_count(&w), 1);
assert_eq!(Weak::weak_count(&w), Some(1));
assert_eq!(Weak::weak_count(&w), 1);
let w2 = w.clone();
assert_eq!(Weak::strong_count(&w), 1);
assert_eq!(Weak::weak_count(&w), Some(2));
assert_eq!(Weak::weak_count(&w), 2);
assert_eq!(Weak::strong_count(&w2), 1);
assert_eq!(Weak::weak_count(&w2), Some(2));
assert_eq!(Weak::weak_count(&w2), 2);
drop(w);
assert_eq!(Weak::strong_count(&w2), 1);
assert_eq!(Weak::weak_count(&w2), Some(1));
assert_eq!(Weak::weak_count(&w2), 1);
let a2 = a.clone();
assert_eq!(Weak::strong_count(&w2), 2);
assert_eq!(Weak::weak_count(&w2), Some(1));
assert_eq!(Weak::weak_count(&w2), 1);
drop(a2);
drop(a);
assert_eq!(Weak::strong_count(&w2), 0);
assert_eq!(Weak::weak_count(&w2), Some(1));
assert_eq!(Weak::weak_count(&w2), 0);
drop(w2);
}

Expand Down
2 changes: 1 addition & 1 deletion src/libcore/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ pub const fn type_name<T: ?Sized>() -> &'static str {
///
/// This is intended for diagnostic use. The exact contents and format of the
/// string are not specified, other than being a best-effort description of the
/// type. For example, `type_name_of::<Option<String>>(None)` could return the
/// type. For example, `type_name_of::<Option<String>>(None)` could return
/// `"Option<String>"` or `"std::option::Option<std::string::String>"`, but not
/// `"foobar"`. In addition, the output may change between versions of the
/// compiler.
Expand Down
18 changes: 10 additions & 8 deletions src/libcore/panic.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
//! Panic support in the standard library.

#![unstable(feature = "core_panic_info",
reason = "newly available in libcore",
issue = "44489")]
#![stable(feature = "core_panic_info", since = "1.41.0")]

use crate::any::Any;
use crate::fmt;
Expand Down Expand Up @@ -39,10 +37,10 @@ pub struct PanicInfo<'a> {
}

impl<'a> PanicInfo<'a> {
#![unstable(feature = "panic_internals",
reason = "internal details of the implementation of the `panic!` \
and related macros",
issue = "0")]
#[unstable(feature = "panic_internals",
reason = "internal details of the implementation of the `panic!` \
and related macros",
issue = "0")]
#[doc(hidden)]
#[inline]
pub fn internal_constructor(
Expand All @@ -57,6 +55,10 @@ impl<'a> PanicInfo<'a> {
}
}

#[unstable(feature = "panic_internals",
reason = "internal details of the implementation of the `panic!` \
and related macros",
issue = "0")]
#[doc(hidden)]
#[inline]
pub fn set_payload(&mut self, info: &'a (dyn Any + Send)) {
Expand Down Expand Up @@ -90,7 +92,7 @@ impl<'a> PanicInfo<'a> {
/// returns that message ready to be used for example with [`fmt::write`]
///
/// [`fmt::write`]: ../fmt/fn.write.html
#[unstable(feature = "panic_info_message", issue = "44489")]
#[unstable(feature = "panic_info_message", issue = "66745")]
pub fn message(&self) -> Option<&fmt::Arguments<'_>> {
self.message
}
Expand Down
3 changes: 1 addition & 2 deletions src/libcore/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -520,15 +520,14 @@ impl<T, E> Result<T, E> {
/// # Examples
///
/// ```
/// #![feature(result_map_or)]
/// let x: Result<_, &str> = Ok("foo");
/// assert_eq!(x.map_or(42, |v| v.len()), 3);
///
/// let x: Result<&str, _> = Err("bar");
/// assert_eq!(x.map_or(42, |v| v.len()), 42);
/// ```
#[inline]
#[unstable(feature = "result_map_or", issue = "66293")]
#[stable(feature = "result_map_or", since = "1.41.0")]
pub fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U {
match self {
Ok(t) => f(t),
Expand Down
73 changes: 72 additions & 1 deletion src/libcore/str/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#![stable(feature = "rust1", since = "1.0.0")]

use self::pattern::Pattern;
use self::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
use self::pattern::{Searcher, SearchStep, ReverseSearcher, DoubleEndedSearcher};

use crate::char;
use crate::fmt::{self, Write};
Expand Down Expand Up @@ -3798,6 +3798,77 @@ impl str {
}
}

/// Returns a string slice with the prefix removed.
///
/// If the string starts with the pattern `prefix`, `Some` is returned with the substring where
/// the prefix is removed. Unlike `trim_start_matches`, this method removes the prefix exactly
/// once.
///
/// If the string does not start with `prefix`, `None` is returned.
///
/// # Examples
///
/// ```
/// #![feature(str_strip)]
///
/// assert_eq!("foobar".strip_prefix("foo"), Some("bar"));
/// assert_eq!("foobar".strip_prefix("bar"), None);
/// assert_eq!("foofoo".strip_prefix("foo"), Some("foo"));
/// ```
#[must_use = "this returns the remaining substring as a new slice, \
without modifying the original"]
#[unstable(feature = "str_strip", reason = "newly added", issue = "67302")]
pub fn strip_prefix<'a, P: Pattern<'a>>(&'a self, prefix: P) -> Option<&'a str> {
let mut matcher = prefix.into_searcher(self);
if let SearchStep::Match(start, len) = matcher.next() {
debug_assert_eq!(start, 0, "The first search step from Searcher \
must include the first character");
unsafe {
// Searcher is known to return valid indices.
Some(self.get_unchecked(len..))
}
} else {
None
}
}

/// Returns a string slice with the suffix removed.
///
/// If the string ends with the pattern `suffix`, `Some` is returned with the substring where
/// the suffix is removed. Unlike `trim_end_matches`, this method removes the suffix exactly
/// once.
///
/// If the string does not end with `suffix`, `None` is returned.
///
/// # Examples
///
/// ```
/// #![feature(str_strip)]
/// assert_eq!("barfoo".strip_suffix("foo"), Some("bar"));
/// assert_eq!("barfoo".strip_suffix("bar"), None);
/// assert_eq!("foofoo".strip_suffix("foo"), Some("foo"));
/// ```
#[must_use = "this returns the remaining substring as a new slice, \
without modifying the original"]
#[unstable(feature = "str_strip", reason = "newly added", issue = "67302")]
pub fn strip_suffix<'a, P>(&'a self, suffix: P) -> Option<&'a str>
where
P: Pattern<'a>,
<P as Pattern<'a>>::Searcher: ReverseSearcher<'a>,
{
let mut matcher = suffix.into_searcher(self);
if let SearchStep::Match(start, end) = matcher.next_back() {
debug_assert_eq!(end, self.len(), "The first search step from ReverseSearcher \
must include the last character");
unsafe {
// Searcher is known to return valid indices.
Some(self.get_unchecked(..start))
}
} else {
None
}
}

/// Returns a string slice with all suffixes that match a pattern
/// repeatedly removed.
///
Expand Down
12 changes: 12 additions & 0 deletions src/librustc_mir/build/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ impl<'tcx> CFG<'tcx> {
));
}

pub fn push_fake_read(
&mut self,
block: BasicBlock,
source_info: SourceInfo,
cause: FakeReadCause,
place: Place<'tcx>,
) {
let kind = StatementKind::FakeRead(cause, box place);
let stmt = Statement { source_info, kind };
self.push(block, stmt);
}

pub fn terminate(&mut self,
block: BasicBlock,
source_info: SourceInfo,
Expand Down
13 changes: 2 additions & 11 deletions src/librustc_mir/build/expr/as_place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,24 +484,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {

fn read_fake_borrows(
&mut self,
block: BasicBlock,
bb: BasicBlock,
fake_borrow_temps: &mut Vec<Local>,
source_info: SourceInfo,
) {
// All indexes have been evaluated now, read all of the
// fake borrows so that they are live across those index
// expressions.
for temp in fake_borrow_temps {
self.cfg.push(
block,
Statement {
source_info,
kind: StatementKind::FakeRead(
FakeReadCause::ForIndex,
Box::new(Place::from(*temp)),
)
}
);
self.cfg.push_fake_read(bb, source_info, FakeReadCause::ForIndex, Place::from(*temp));
}
}
}
Loading

0 comments on commit f0d4b57

Please sign in to comment.