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 9 pull requests #52123

Merged
merged 26 commits into from
Jul 7, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
7eba13f
Correctly handle an activation from dead code.
davidtwco Jul 4, 2018
aeb1682
Ensure that borrows wind up unactivated.
davidtwco Jul 4, 2018
f90eada
Improve comments.
davidtwco Jul 4, 2018
37228fe
reverse_postorder
csmoe Jul 5, 2018
0e31e2f
Remove rustc_mir_borrowck attribute and use rustc_mir instead
spastorino Jul 4, 2018
e7e8c72
update test
csmoe Jul 5, 2018
25266c1
Do not run AST borrowck when -Zborrowck=mir
spastorino Jul 5, 2018
bbfdea2
typo-fix stable ed'n error: "an onlyavailable" → "and only available"
zackmdavis Jul 6, 2018
7fbc389
Stabilize rc_downcast
tmccombs Jul 6, 2018
15a196e
Remove unnecessary feature gate.
tmccombs Jul 6, 2018
933c299
Dedupe filetime
Eijebong Jul 6, 2018
b7047bb
ARM: expose the "mclass" target feature
japaric Jul 6, 2018
6e2c49f
Use an aligned dangling pointer in Weak::new, rather than address 1
SimonSapin Jun 29, 2018
41730b7
Rc: remove unused allocation from Weak::new()
SimonSapin Jun 27, 2018
21526c5
Add a test for Weak::new() not crashing for uninhabited types
SimonSapin Jun 27, 2018
5717d99
Add some unit tests for dangling Weak references
SimonSapin Jul 6, 2018
67202b8
Fix is_dangling import when Arc is #[cfg]’ed out
SimonSapin Jul 6, 2018
9b3ec57
Rollup merge of #51901 - rust-lang:weak-unboxing, r=alexcrichton
Mark-Simulacrum Jul 7, 2018
b71b921
Rollup merge of #52058 - davidtwco:issue-51345, r=nikomatsakis
Mark-Simulacrum Jul 7, 2018
ec6bba3
Rollup merge of #52067 - csmoe:issue-51167, r=nikomatsakis
Mark-Simulacrum Jul 7, 2018
54a440b
Rollup merge of #52083 - spastorino:dont-run-ast-borrowck-on-mir-mode…
Mark-Simulacrum Jul 7, 2018
9672933
Rollup merge of #52099 - zackmdavis:and_the_case_of_the_typ, r=oli-obk
Mark-Simulacrum Jul 7, 2018
e382338
Rollup merge of #52103 - tmccombs:rc_downcast, r=Mark-Simulacrum
Mark-Simulacrum Jul 7, 2018
f69baa9
Rollup merge of #52104 - tmccombs:repr_trans_stable, r=Mark-Simulacrum
Mark-Simulacrum Jul 7, 2018
4784883
Rollup merge of #52117 - Eijebong:filetime, r=alexcrichton
Mark-Simulacrum Jul 7, 2018
cd7ddae
Rollup merge of #52120 - japaric:mclass, r=alexcrichton
Mark-Simulacrum Jul 7, 2018
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
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