Skip to content

Commit

Permalink
Auto merge of #52123 - Mark-Simulacrum:rollup, r=Mark-Simulacrum
Browse files Browse the repository at this point in the history
Rollup of 9 pull requests

Successful merges:

 - #51901 (Rc: remove unused allocation and fix segfault in Weak::new())
 - #52058 (Use of unimplemented!() causing ICE with NLL)
 - #52067 (Visit the mir basic blocks in reverse-postfix order)
 - #52083 (Dont run ast borrowck on mir mode)
 - #52099 (fix typo in stable `--edition` error message)
 - #52103 (Stabilize rc_downcast)
 - #52104 (Remove unnecessary feature gate.)
 - #52117 (Dedupe filetime)
 - #52120 (ARM: expose the "mclass" target feature)

Failed merges:

r? @ghost
  • Loading branch information
bors committed Jul 7, 2018
2 parents 99b0ddb + cd7ddae commit 4f0ca92
Show file tree
Hide file tree
Showing 35 changed files with 354 additions and 175 deletions.
23 changes: 6 additions & 17 deletions src/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ dependencies = [
"build_helper 0.1.0",
"cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
"cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
Expand Down Expand Up @@ -416,7 +416,7 @@ version = "0.0.0"
dependencies = [
"diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
Expand Down Expand Up @@ -693,16 +693,6 @@ dependencies = [
name = "features"
version = "0.1.0"

[[package]]
name = "filetime"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "filetime"
version = "0.2.1"
Expand Down Expand Up @@ -1139,11 +1129,11 @@ dependencies = [

[[package]]
name = "lzma-sys"
version = "0.1.9"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
Expand Down Expand Up @@ -3075,7 +3065,7 @@ name = "xz2"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lzma-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"lzma-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
Expand Down Expand Up @@ -3134,7 +3124,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
"checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82"
"checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b"
"checksum filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "714653f3e34871534de23771ac7b26e999651a0a228f47beb324dfdf1dd4b10f"
"checksum filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da4b9849e77b13195302c174324b5ba73eec9b236b24c221a61000daefb95c5f"
"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
"checksum flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fac2277e84e5e858483756647a9d0aa8d9a2b7cba517fd84325a0aaa69a0909"
Expand Down Expand Up @@ -3179,7 +3168,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
"checksum log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "61bd98ae7f7b754bc53dca7d44b604f733c6bba044ea6f41bc8d89272d8161d2"
"checksum log_settings 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19af41f0565d7c19b2058153ad0b42d4d5ce89ec4dbf06ed6741114a8b63e7cd"
"checksum lzma-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c1b93b78f89e8737dac81837fc8f5521ac162abcba902e1a3db949d55346d1da"
"checksum lzma-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d1eaa027402541975218bb0eec67d6b0412f6233af96e0d096d31dbdfd22e614"
"checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
"checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43"
"checksum markup5ever 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfedc97d5a503e96816d10fedcd5b42f760b2e525ce2f7ec71f6a41780548475"
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ test = false
[dependencies]
build_helper = { path = "../build_helper" }
cmake = "0.1.23"
filetime = "0.1"
filetime = "0.2"
num_cpus = "1.0"
getopts = "0.2"
cc = "1.0.1"
Expand Down
67 changes: 42 additions & 25 deletions src/liballoc/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ use core::hash::{Hash, Hasher};
use core::intrinsics::abort;
use core::marker;
use core::marker::{Unsize, PhantomData};
use core::mem::{self, align_of_val, forget, size_of_val, uninitialized};
use core::mem::{self, align_of_val, forget, size_of_val};
use core::ops::Deref;
use core::ops::CoerceUnsized;
use core::ptr::{self, NonNull};
Expand Down Expand Up @@ -620,13 +620,12 @@ impl<T: Clone> Rc<T> {

impl Rc<Any> {
#[inline]
#[unstable(feature = "rc_downcast", issue = "44608")]
#[stable(feature = "rc_downcast", since = "1.29.0")]
/// Attempt to downcast the `Rc<Any>` to a concrete type.
///
/// # Examples
///
/// ```
/// #![feature(rc_downcast)]
/// use std::any::Any;
/// use std::rc::Rc;
///
Expand Down Expand Up @@ -1153,6 +1152,10 @@ impl<T> From<Vec<T>> for Rc<[T]> {
/// [`None`]: ../../std/option/enum.Option.html#variant.None
#[stable(feature = "rc_weak", since = "1.4.0")]
pub struct Weak<T: ?Sized> {
// This is a `NonNull` to allow optimizing the size of this type in enums,
// but it is not necessarily a valid pointer.
// `Weak::new` sets this to a dangling pointer so that it doesn’t need
// to allocate space on the heap.
ptr: NonNull<RcBox<T>>,
}

Expand All @@ -1165,8 +1168,8 @@ impl<T: ?Sized> !marker::Sync for Weak<T> {}
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Weak<U>> for Weak<T> {}

impl<T> Weak<T> {
/// Constructs a new `Weak<T>`, allocating memory for `T` without initializing
/// it. Calling [`upgrade`] on the return value always gives [`None`].
/// Constructs a new `Weak<T>`, without allocating any memory.
/// Calling [`upgrade`] on the return value always gives [`None`].
///
/// [`upgrade`]: struct.Weak.html#method.upgrade
/// [`None`]: ../../std/option/enum.Option.html
Expand All @@ -1181,18 +1184,18 @@ impl<T> Weak<T> {
/// ```
#[stable(feature = "downgraded_weak", since = "1.10.0")]
pub fn new() -> Weak<T> {
unsafe {
Weak {
ptr: Box::into_raw_non_null(box RcBox {
strong: Cell::new(0),
weak: Cell::new(1),
value: uninitialized(),
}),
}
Weak {
ptr: NonNull::dangling(),
}
}
}

pub(crate) fn is_dangling<T: ?Sized>(ptr: NonNull<T>) -> bool {
let address = ptr.as_ptr() as *mut () as usize;
let align = align_of_val(unsafe { ptr.as_ref() });
address == align
}

impl<T: ?Sized> Weak<T> {
/// Attempts to upgrade the `Weak` pointer to an [`Rc`], extending
/// the lifetime of the value if successful.
Expand Down Expand Up @@ -1222,13 +1225,25 @@ impl<T: ?Sized> Weak<T> {
/// ```
#[stable(feature = "rc_weak", since = "1.4.0")]
pub fn upgrade(&self) -> Option<Rc<T>> {
if self.strong() == 0 {
let inner = self.inner()?;
if inner.strong() == 0 {
None
} else {
self.inc_strong();
inner.inc_strong();
Some(Rc { ptr: self.ptr, phantom: PhantomData })
}
}

/// Return `None` when the pointer is dangling and there is no allocated `RcBox`,
/// i.e. this `Weak` was created by `Weak::new`
#[inline]
fn inner(&self) -> Option<&RcBox<T>> {
if is_dangling(self.ptr) {
None
} else {
Some(unsafe { self.ptr.as_ref() })
}
}
}

#[stable(feature = "rc_weak", since = "1.4.0")]
Expand Down Expand Up @@ -1258,12 +1273,14 @@ impl<T: ?Sized> Drop for Weak<T> {
/// assert!(other_weak_foo.upgrade().is_none());
/// ```
fn drop(&mut self) {
unsafe {
self.dec_weak();
if let Some(inner) = self.inner() {
inner.dec_weak();
// the weak count starts at 1, and will only go to zero if all
// the strong pointers have disappeared.
if self.weak() == 0 {
Global.dealloc(self.ptr.cast(), Layout::for_value(self.ptr.as_ref()));
if inner.weak() == 0 {
unsafe {
Global.dealloc(self.ptr.cast(), Layout::for_value(self.ptr.as_ref()));
}
}
}
}
Expand All @@ -1284,7 +1301,9 @@ impl<T: ?Sized> Clone for Weak<T> {
/// ```
#[inline]
fn clone(&self) -> Weak<T> {
self.inc_weak();
if let Some(inner) = self.inner() {
inner.inc_weak()
}
Weak { ptr: self.ptr }
}
}
Expand Down Expand Up @@ -1317,7 +1336,7 @@ impl<T> Default for Weak<T> {
}
}

// NOTE: We checked_add here to deal with mem::forget safety. In particular
// NOTE: We checked_add here to deal with mem::forget safely. In particular
// if you mem::forget Rcs (or Weaks), the ref-count can overflow, and then
// you can free the allocation while outstanding Rcs (or Weaks) exist.
// We abort because this is such a degenerate scenario that we don't care about
Expand Down Expand Up @@ -1370,12 +1389,10 @@ impl<T: ?Sized> RcBoxPtr<T> for Rc<T> {
}
}

impl<T: ?Sized> RcBoxPtr<T> for Weak<T> {
impl<T: ?Sized> RcBoxPtr<T> for RcBox<T> {
#[inline(always)]
fn inner(&self) -> &RcBox<T> {
unsafe {
self.ptr.as_ref()
}
self
}
}

Expand Down
48 changes: 25 additions & 23 deletions src/liballoc/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ use core::convert::From;

use alloc::{Global, Alloc, Layout, box_free, handle_alloc_error};
use boxed::Box;
use rc::is_dangling;
use string::String;
use vec::Vec;

Expand All @@ -43,9 +44,6 @@ use vec::Vec;
/// necessarily) at _exactly_ `MAX_REFCOUNT + 1` references.
const MAX_REFCOUNT: usize = (isize::MAX) as usize;

/// A sentinel value that is used for the pointer of `Weak::new()`.
const WEAK_EMPTY: usize = 1;

/// A thread-safe reference-counting pointer. 'Arc' stands for 'Atomically
/// Reference Counted'.
///
Expand Down Expand Up @@ -239,9 +237,9 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {}
#[stable(feature = "arc_weak", since = "1.4.0")]
pub struct Weak<T: ?Sized> {
// This is a `NonNull` to allow optimizing the size of this type in enums,
// but it is actually not truly "non-null". A `Weak::new()` will set this
// to a sentinel value, instead of needing to allocate some space in the
// heap.
// but it is not necessarily a valid pointer.
// `Weak::new` sets this to a dangling pointer so that it doesn’t need
// to allocate space on the heap.
ptr: NonNull<ArcInner<T>>,
}

Expand Down Expand Up @@ -982,13 +980,12 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Arc<T> {

impl Arc<Any + Send + Sync> {
#[inline]
#[unstable(feature = "rc_downcast", issue = "44608")]
#[stable(feature = "rc_downcast", since = "1.29.0")]
/// Attempt to downcast the `Arc<Any + Send + Sync>` to a concrete type.
///
/// # Examples
///
/// ```
/// #![feature(rc_downcast)]
/// use std::any::Any;
/// use std::sync::Arc;
///
Expand Down Expand Up @@ -1035,10 +1032,8 @@ impl<T> Weak<T> {
/// ```
#[stable(feature = "downgraded_weak", since = "1.10.0")]
pub fn new() -> Weak<T> {
unsafe {
Weak {
ptr: NonNull::new_unchecked(WEAK_EMPTY as *mut _),
}
Weak {
ptr: NonNull::dangling(),
}
}
}
Expand Down Expand Up @@ -1074,11 +1069,7 @@ impl<T: ?Sized> Weak<T> {
pub fn upgrade(&self) -> Option<Arc<T>> {
// We use a CAS loop to increment the strong count instead of a
// fetch_add because once the count hits 0 it must never be above 0.
let inner = if self.ptr.as_ptr() as *const u8 as usize == WEAK_EMPTY {
return None;
} else {
unsafe { self.ptr.as_ref() }
};
let inner = self.inner()?;

// Relaxed load because any write of 0 that we can observe
// leaves the field in a permanently zero state (so a
Expand Down Expand Up @@ -1109,6 +1100,17 @@ impl<T: ?Sized> Weak<T> {
}
}
}

/// Return `None` when the pointer is dangling and there is no allocated `ArcInner`,
/// i.e. this `Weak` was created by `Weak::new`
#[inline]
fn inner(&self) -> Option<&ArcInner<T>> {
if is_dangling(self.ptr) {
None
} else {
Some(unsafe { self.ptr.as_ref() })
}
}
}

#[stable(feature = "arc_weak", since = "1.4.0")]
Expand All @@ -1126,10 +1128,10 @@ impl<T: ?Sized> Clone for Weak<T> {
/// ```
#[inline]
fn clone(&self) -> Weak<T> {
let inner = if self.ptr.as_ptr() as *const u8 as usize == WEAK_EMPTY {
return Weak { ptr: self.ptr };
let inner = if let Some(inner) = self.inner() {
inner
} else {
unsafe { self.ptr.as_ref() }
return Weak { ptr: self.ptr };
};
// See comments in Arc::clone() for why this is relaxed. This can use a
// fetch_add (ignoring the lock) because the weak count is only locked
Expand Down Expand Up @@ -1204,10 +1206,10 @@ impl<T: ?Sized> Drop for Weak<T> {
// weak count can only be locked if there was precisely one weak ref,
// meaning that drop could only subsequently run ON that remaining weak
// ref, which can only happen after the lock is released.
let inner = if self.ptr.as_ptr() as *const u8 as usize == WEAK_EMPTY {
return;
let inner = if let Some(inner) = self.inner() {
inner
} else {
unsafe { self.ptr.as_ref() }
return
};

if inner.weak.fetch_sub(1, Release) == 1 {
Expand Down
Loading

0 comments on commit 4f0ca92

Please sign in to comment.