Skip to content
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

Rollup of 7 pull requests #67342

Merged
merged 22 commits into from
Dec 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
91ee3d1
Stabilize `std::{rc,sync}::Weak::{weak_count, strong_count}`
Oct 24, 2019
0d0b283
Make Weak::weak_count() return zero when no strong refs remain
Nov 21, 2019
9badc33
Add str::strip_prefix and str::strip_suffix
SOF3 Nov 25, 2019
6ddcf50
Fix unstable attribute accidentally applying to the entire impl
SimonSapin Nov 26, 2019
2e2e0df
Improved comments to clarify sasumptions in str::strip_prefix
SOF3 Nov 26, 2019
392e5a7
Fix the tracking issue number for `PanicInfo::message`
SimonSapin Nov 26, 2019
eab1dc9
Stabilize the `core::panic` module
SimonSapin Nov 26, 2019
4718e20
Fixed formatting issues
SOF3 Nov 26, 2019
8cae411
stabilize Result::map_or
tesuji Nov 20, 2019
93438fd
make use of Result::map_or
tesuji Nov 25, 2019
9778e03
Bump Weak::strong_count/weak_count stabilizations from 1.40 to 1.41
dtolnay Dec 15, 2019
6176051
Set tracking issue for str_strip
SOF3 Dec 15, 2019
e28153e
fix doc comment
lcnr Dec 15, 2019
8a5969d
Fix repetition in matches/mod.rs
Centril Dec 15, 2019
2d96f20
cleanup with push_fake_read
Centril Dec 15, 2019
c34ea91
Rollup merge of #65778 - bdonlan:stable_weak_count, r=dtolnay
Centril Dec 16, 2019
84ef889
Rollup merge of #66570 - lzutao:stabilize-result-map_or, r=Dylan-DPC
Centril Dec 16, 2019
1c12dc8
Rollup merge of #66735 - SOF3:feature/str_strip, r=KodrAus
Centril Dec 16, 2019
6b9bb74
Rollup merge of #66771 - SimonSapin:panic-stability, r=KodrAus
Centril Dec 16, 2019
d182397
Rollup merge of #67317 - lcnr:type_name_docs, r=jonas-schievink
Centril Dec 16, 2019
9f0cb17
Rollup merge of #67324 - Centril:mir-build-match-doc-fix, r=matthewja…
Centril Dec 16, 2019
71a9a99
Rollup merge of #67325 - Centril:push-fake-read, r=matthewjasper
Centril Dec 16, 2019
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
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