Auto merge of #52123 - Mark-Simulacrum:rollup, r=Mark-Simulacrum
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
This commit is contained in:
commit
4f0ca9248f
@ -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)",
|
||||
@ -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)",
|
||||
@ -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"
|
||||
@ -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)",
|
||||
]
|
||||
@ -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]]
|
||||
@ -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"
|
||||
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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};
|
||||
@ -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;
|
||||
///
|
||||
@ -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>>,
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -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.
|
||||
@ -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")]
|
||||
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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 }
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
@ -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'.
|
||||
///
|
||||
@ -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>>,
|
||||
}
|
||||
|
||||
@ -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;
|
||||
///
|
||||
@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
@ -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")]
|
||||
@ -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
|
||||
@ -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 {
|
||||
|
55
src/liballoc/tests/arc.rs
Normal file
55
src/liballoc/tests/arc.rs
Normal file
@ -0,0 +1,55 @@
|
||||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::any::Any;
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
#[test]
|
||||
fn uninhabited() {
|
||||
enum Void {}
|
||||
let mut a = Weak::<Void>::new();
|
||||
a = a.clone();
|
||||
assert!(a.upgrade().is_none());
|
||||
|
||||
let mut a: Weak<Any> = a; // Unsizing
|
||||
a = a.clone();
|
||||
assert!(a.upgrade().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slice() {
|
||||
let a: Arc<[u32; 3]> = Arc::new([3, 2, 1]);
|
||||
let a: Arc<[u32]> = a; // Unsizing
|
||||
let b: Arc<[u32]> = Arc::from(&[3, 2, 1][..]); // Conversion
|
||||
assert_eq!(a, b);
|
||||
|
||||
// Exercise is_dangling() with a DST
|
||||
let mut a = Arc::downgrade(&a);
|
||||
a = a.clone();
|
||||
assert!(a.upgrade().is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trait_object() {
|
||||
let a: Arc<u32> = Arc::new(4);
|
||||
let a: Arc<Any> = a; // Unsizing
|
||||
|
||||
// Exercise is_dangling() with a DST
|
||||
let mut a = Arc::downgrade(&a);
|
||||
a = a.clone();
|
||||
assert!(a.upgrade().is_some());
|
||||
|
||||
let mut b = Weak::<u32>::new();
|
||||
b = b.clone();
|
||||
assert!(b.upgrade().is_none());
|
||||
let mut b: Weak<Any> = b; // Unsizing
|
||||
b = b.clone();
|
||||
assert!(b.upgrade().is_none());
|
||||
}
|
@ -32,12 +32,14 @@ extern crate rand;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
|
||||
mod arc;
|
||||
mod binary_heap;
|
||||
mod btree;
|
||||
mod cow_str;
|
||||
mod fmt;
|
||||
mod heap;
|
||||
mod linked_list;
|
||||
mod rc;
|
||||
mod slice;
|
||||
mod str;
|
||||
mod string;
|
||||
|
55
src/liballoc/tests/rc.rs
Normal file
55
src/liballoc/tests/rc.rs
Normal file
@ -0,0 +1,55 @@
|
||||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::any::Any;
|
||||
use std::rc::{Rc, Weak};
|
||||
|
||||
#[test]
|
||||
fn uninhabited() {
|
||||
enum Void {}
|
||||
let mut a = Weak::<Void>::new();
|
||||
a = a.clone();
|
||||
assert!(a.upgrade().is_none());
|
||||
|
||||
let mut a: Weak<Any> = a; // Unsizing
|
||||
a = a.clone();
|
||||
assert!(a.upgrade().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slice() {
|
||||
let a: Rc<[u32; 3]> = Rc::new([3, 2, 1]);
|
||||
let a: Rc<[u32]> = a; // Unsizing
|
||||
let b: Rc<[u32]> = Rc::from(&[3, 2, 1][..]); // Conversion
|
||||
assert_eq!(a, b);
|
||||
|
||||
// Exercise is_dangling() with a DST
|
||||
let mut a = Rc::downgrade(&a);
|
||||
a = a.clone();
|
||||
assert!(a.upgrade().is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trait_object() {
|
||||
let a: Rc<u32> = Rc::new(4);
|
||||
let a: Rc<Any> = a; // Unsizing
|
||||
|
||||
// Exercise is_dangling() with a DST
|
||||
let mut a = Rc::downgrade(&a);
|
||||
a = a.clone();
|
||||
assert!(a.upgrade().is_some());
|
||||
|
||||
let mut b = Weak::<u32>::new();
|
||||
b = b.clone();
|
||||
assert!(b.upgrade().is_none());
|
||||
let mut b: Weak<Any> = b; // Unsizing
|
||||
b = b.clone();
|
||||
assert!(b.upgrade().is_none());
|
||||
}
|
@ -122,7 +122,6 @@
|
||||
#![feature(const_slice_len)]
|
||||
#![feature(const_str_as_bytes)]
|
||||
#![feature(const_str_len)]
|
||||
#![cfg_attr(stage0, feature(repr_transparent))]
|
||||
|
||||
#[prelude_import]
|
||||
#[allow(unused)]
|
||||
|
@ -1816,7 +1816,7 @@ pub fn build_session_options_and_crate_config(
|
||||
early_error(
|
||||
ErrorOutputType::default(),
|
||||
&format!(
|
||||
"Edition {} is unstable an only\
|
||||
"Edition {} is unstable and only \
|
||||
available for nightly builds of rustc.",
|
||||
edition,
|
||||
)
|
||||
|
@ -1354,6 +1354,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
!self.sess.opts.debugging_opts.disable_ast_check_for_mutation_in_guard
|
||||
}
|
||||
|
||||
/// If true, we should use the AST-based borrowck (we may *also* use
|
||||
/// the MIR-based borrowck).
|
||||
pub fn use_ast_borrowck(self) -> bool {
|
||||
self.borrowck_mode().use_ast()
|
||||
}
|
||||
|
||||
/// If true, we should use the MIR-based borrowck (we may *also* use
|
||||
/// the AST-based borrowck).
|
||||
pub fn use_mir_borrowck(self) -> bool {
|
||||
|
@ -89,6 +89,8 @@ pub struct AnalysisData<'a, 'tcx: 'a> {
|
||||
fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId)
|
||||
-> Lrc<BorrowCheckResult>
|
||||
{
|
||||
assert!(tcx.use_ast_borrowck());
|
||||
|
||||
debug!("borrowck(body_owner_def_id={:?})", owner_def_id);
|
||||
|
||||
let owner_id = tcx.hir.as_local_node_id(owner_def_id).unwrap();
|
||||
|
@ -84,6 +84,7 @@ unsafe fn configure_llvm(sess: &Session) {
|
||||
// array, leading to crashes.
|
||||
|
||||
const ARM_WHITELIST: &[(&str, Option<&str>)] = &[
|
||||
("mclass", Some("arm_target_feature")),
|
||||
("neon", Some("arm_target_feature")),
|
||||
("v7", Some("arm_target_feature")),
|
||||
("vfp2", Some("arm_target_feature")),
|
||||
|
@ -1279,7 +1279,11 @@ where
|
||||
middle::liveness::check_crate(tcx)
|
||||
});
|
||||
|
||||
time(sess, "borrow checking", || borrowck::check_crate(tcx));
|
||||
time(sess, "borrow checking", || {
|
||||
if tcx.use_ast_borrowck() {
|
||||
borrowck::check_crate(tcx);
|
||||
}
|
||||
});
|
||||
|
||||
time(sess,
|
||||
"MIR borrow checking",
|
||||
|
@ -53,15 +53,13 @@ impl<'tcx> Index<BorrowIndex> for BorrowSet<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Every two-phase borrow has *exactly one* use (or else it is not a
|
||||
/// proper two-phase borrow under our current definition). However, not
|
||||
/// all uses are actually ones that activate the reservation.. In
|
||||
/// particular, a shared borrow of a `&mut` does not activate the
|
||||
/// reservation.
|
||||
/// Location where a two phase borrow is activated, if a borrow
|
||||
/// is in fact a two phase borrow.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
crate enum TwoPhaseUse {
|
||||
MutActivate,
|
||||
SharedUse,
|
||||
crate enum TwoPhaseActivation {
|
||||
NotTwoPhase,
|
||||
NotActivated,
|
||||
ActivatedAt(Location),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -69,9 +67,8 @@ crate struct BorrowData<'tcx> {
|
||||
/// Location where the borrow reservation starts.
|
||||
/// In many cases, this will be equal to the activation location but not always.
|
||||
crate reserve_location: Location,
|
||||
/// Location where the borrow is activated. None if this is not a
|
||||
/// 2-phase borrow.
|
||||
crate activation_location: Option<(TwoPhaseUse, Location)>,
|
||||
/// Location where the borrow is activated.
|
||||
crate activation_location: TwoPhaseActivation,
|
||||
/// What kind of borrow this is
|
||||
crate kind: mir::BorrowKind,
|
||||
/// The region for which this borrow is live
|
||||
@ -116,19 +113,6 @@ impl<'tcx> BorrowSet<'tcx> {
|
||||
visitor.visit_basic_block_data(block, block_data);
|
||||
}
|
||||
|
||||
// Double check: We should have found an activation for every pending
|
||||
// activation.
|
||||
assert_eq!(
|
||||
visitor
|
||||
.pending_activations
|
||||
.iter()
|
||||
.find(|&(_local, &borrow_index)| visitor.idx_vec[borrow_index]
|
||||
.activation_location
|
||||
.is_none()),
|
||||
None,
|
||||
"never found an activation for this borrow!",
|
||||
);
|
||||
|
||||
BorrowSet {
|
||||
borrows: visitor.idx_vec,
|
||||
location_map: visitor.location_map,
|
||||
@ -183,7 +167,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> {
|
||||
kind,
|
||||
region,
|
||||
reserve_location: location,
|
||||
activation_location: None,
|
||||
activation_location: TwoPhaseActivation::NotTwoPhase,
|
||||
borrowed_place: borrowed_place.clone(),
|
||||
assigned_place: assigned_place.clone(),
|
||||
};
|
||||
@ -232,38 +216,43 @@ impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(other_activation) = borrow_data.activation_location {
|
||||
if let TwoPhaseActivation::ActivatedAt(other_location) =
|
||||
borrow_data.activation_location {
|
||||
span_bug!(
|
||||
self.mir.source_info(location).span,
|
||||
"found two uses for 2-phase borrow temporary {:?}: \
|
||||
{:?} and {:?}",
|
||||
temp,
|
||||
location,
|
||||
other_activation,
|
||||
other_location,
|
||||
);
|
||||
}
|
||||
|
||||
// Otherwise, this is the unique later use
|
||||
// that we expect.
|
||||
|
||||
let two_phase_use;
|
||||
|
||||
match context {
|
||||
borrow_data.activation_location = match context {
|
||||
// The use of TMP in a shared borrow does not
|
||||
// count as an actual activation.
|
||||
PlaceContext::Borrow { kind: mir::BorrowKind::Shared, .. } => {
|
||||
two_phase_use = TwoPhaseUse::SharedUse;
|
||||
TwoPhaseActivation::NotActivated
|
||||
}
|
||||
_ => {
|
||||
two_phase_use = TwoPhaseUse::MutActivate;
|
||||
// Double check: This borrow is indeed a two-phase borrow (that is,
|
||||
// we are 'transitioning' from `NotActivated` to `ActivatedAt`) and
|
||||
// we've not found any other activations (checked above).
|
||||
assert_eq!(
|
||||
borrow_data.activation_location,
|
||||
TwoPhaseActivation::NotActivated,
|
||||
"never found an activation for this borrow!",
|
||||
);
|
||||
|
||||
self.activation_map
|
||||
.entry(location)
|
||||
.or_insert(Vec::new())
|
||||
.push(borrow_index);
|
||||
TwoPhaseActivation::ActivatedAt(location)
|
||||
}
|
||||
}
|
||||
|
||||
borrow_data.activation_location = Some((two_phase_use, location));
|
||||
};
|
||||
}
|
||||
|
||||
None => {}
|
||||
@ -342,6 +331,11 @@ impl<'a, 'gcx, 'tcx> GatherBorrows<'a, 'gcx, 'tcx> {
|
||||
);
|
||||
};
|
||||
|
||||
// Consider the borrow not activated to start. When we find an activation, we'll update
|
||||
// this field.
|
||||
let borrow_data = &mut self.idx_vec[borrow_index];
|
||||
borrow_data.activation_location = TwoPhaseActivation::NotActivated;
|
||||
|
||||
// Insert `temp` into the list of pending activations. From
|
||||
// now on, we'll be on the lookout for a use of it. Note that
|
||||
// we are guaranteed that this use will come after the
|
||||
|
@ -80,7 +80,7 @@ fn mir_borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> BorrowC
|
||||
let mut return_early;
|
||||
|
||||
// Return early if we are not supposed to use MIR borrow checker for this function.
|
||||
return_early = !tcx.has_attr(def_id, "rustc_mir_borrowck") && !tcx.use_mir_borrowck();
|
||||
return_early = !tcx.has_attr(def_id, "rustc_mir") && !tcx.use_mir_borrowck();
|
||||
|
||||
if tcx.is_struct_constructor(def_id) {
|
||||
// We are not borrow checking the automatically generated struct constructors
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use borrow_check::borrow_set::{BorrowSet, BorrowData, TwoPhaseUse};
|
||||
use borrow_check::borrow_set::{BorrowSet, BorrowData, TwoPhaseActivation};
|
||||
use borrow_check::places_conflict;
|
||||
use borrow_check::Context;
|
||||
use borrow_check::ShallowOrDeep;
|
||||
@ -83,11 +83,11 @@ pub(super) fn is_active<'tcx>(
|
||||
|
||||
let activation_location = match borrow_data.activation_location {
|
||||
// If this is not a 2-phase borrow, it is always active.
|
||||
None => return true,
|
||||
TwoPhaseActivation::NotTwoPhase => return true,
|
||||
// And if the unique 2-phase use is not an activation, then it is *never* active.
|
||||
Some((TwoPhaseUse::SharedUse, _)) => return false,
|
||||
// Otherwise, we derive info from the activation point `v`:
|
||||
Some((TwoPhaseUse::MutActivate, v)) => v,
|
||||
TwoPhaseActivation::NotActivated => return false,
|
||||
// Otherwise, we derive info from the activation point `loc`:
|
||||
TwoPhaseActivation::ActivatedAt(loc) => loc,
|
||||
};
|
||||
|
||||
// Otherwise, it is active for every location *except* in between
|
||||
|
@ -17,6 +17,7 @@ use rustc_data_structures::work_queue::WorkQueue;
|
||||
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
use rustc::mir::{self, Mir, BasicBlock, BasicBlockData, Location, Statement, Terminator};
|
||||
use rustc::mir::traversal;
|
||||
use rustc::session::Session;
|
||||
|
||||
use std::borrow::Borrow;
|
||||
@ -332,7 +333,7 @@ pub(crate) trait DataflowResultsConsumer<'a, 'tcx: 'a> {
|
||||
|
||||
fn analyze_results(&mut self, flow_uninit: &mut Self::FlowState) {
|
||||
let flow = flow_uninit;
|
||||
for bb in self.mir().basic_blocks().indices() {
|
||||
for (bb, _) in traversal::reverse_postorder(self.mir()) {
|
||||
flow.reset_to_entry_of(bb);
|
||||
self.process_basic_block(bb, flow);
|
||||
}
|
||||
|
@ -225,7 +225,10 @@ fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
|
||||
// (Mir-)Borrowck uses `mir_validated`, so we have to force it to
|
||||
// execute before we can steal.
|
||||
let _ = tcx.mir_borrowck(def_id);
|
||||
let _ = tcx.borrowck(def_id);
|
||||
|
||||
if tcx.use_ast_borrowck() {
|
||||
let _ = tcx.borrowck(def_id);
|
||||
}
|
||||
|
||||
let mut mir = tcx.mir_validated(def_id).steal();
|
||||
run_passes![tcx, mir, def_id, 2;
|
||||
|
@ -36,7 +36,7 @@ impl MirPass for SanityCheck {
|
||||
src: MirSource, mir: &mut Mir<'tcx>) {
|
||||
let def_id = src.def_id;
|
||||
let id = tcx.hir.as_local_node_id(def_id).unwrap();
|
||||
if !tcx.has_attr(def_id, "rustc_mir_borrowck") {
|
||||
if !tcx.has_attr(def_id, "rustc_mir") {
|
||||
debug!("skipping rustc_peek::SanityCheck on {}", tcx.item_path_str(def_id));
|
||||
return;
|
||||
} else {
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
// General test of maybe_uninits state computed by MIR dataflow.
|
||||
|
||||
#![feature(nll)]
|
||||
#![feature(core_intrinsics, rustc_attrs)]
|
||||
|
||||
use std::intrinsics::rustc_peek;
|
||||
@ -17,7 +18,6 @@ use std::mem::{drop, replace};
|
||||
|
||||
struct S(i32);
|
||||
|
||||
#[rustc_mir_borrowck]
|
||||
#[rustc_mir(rustc_peek_definite_init,stop_after_dataflow)]
|
||||
fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S {
|
||||
let ret;
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
// General test of maybe_inits state computed by MIR dataflow.
|
||||
|
||||
#![feature(nll)]
|
||||
#![feature(core_intrinsics, rustc_attrs)]
|
||||
|
||||
use std::intrinsics::rustc_peek;
|
||||
@ -17,7 +18,6 @@ use std::mem::{drop, replace};
|
||||
|
||||
struct S(i32);
|
||||
|
||||
#[rustc_mir_borrowck]
|
||||
#[rustc_mir(rustc_peek_maybe_init,stop_after_dataflow)]
|
||||
fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S {
|
||||
let ret;
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
// General test of maybe_uninits state computed by MIR dataflow.
|
||||
|
||||
#![feature(nll)]
|
||||
#![feature(core_intrinsics, rustc_attrs)]
|
||||
|
||||
use std::intrinsics::rustc_peek;
|
||||
@ -17,7 +18,6 @@ use std::mem::{drop, replace};
|
||||
|
||||
struct S(i32);
|
||||
|
||||
#[rustc_mir_borrowck]
|
||||
#[rustc_mir(rustc_peek_maybe_uninit,stop_after_dataflow)]
|
||||
fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S {
|
||||
let ret;
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
// General test of maybe_uninits state computed by MIR dataflow.
|
||||
|
||||
#![feature(nll)]
|
||||
#![feature(core_intrinsics, rustc_attrs)]
|
||||
|
||||
use std::intrinsics::rustc_peek;
|
||||
@ -17,7 +18,6 @@ use std::mem::{drop, replace};
|
||||
|
||||
struct S(i32);
|
||||
|
||||
#[rustc_mir_borrowck]
|
||||
#[rustc_mir(rustc_peek_maybe_uninit,stop_after_dataflow)]
|
||||
fn foo(x: &mut S) {
|
||||
// `x` is initialized here, so maybe-uninit bit is 0.
|
||||
|
18
src/test/run-fail/issue-51345.rs
Normal file
18
src/test/run-fail/issue-51345.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: thread 'main' panicked at 'explicit panic'
|
||||
|
||||
#![feature(nll)]
|
||||
|
||||
fn main() {
|
||||
let mut vec = vec![];
|
||||
vec.push((vec.len(), panic!()));
|
||||
}
|
17
src/test/run-pass/issue-51345.rs
Normal file
17
src/test/run-pass/issue-51345.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(nll)]
|
||||
|
||||
fn main() {
|
||||
let mut v = Vec::new();
|
||||
|
||||
loop { v.push(break) }
|
||||
}
|
15
src/test/run-pass/weak-new-uninhabited-issue-48493.rs
Normal file
15
src/test/run-pass/weak-new-uninhabited-issue-48493.rs
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
fn main() {
|
||||
enum Void {}
|
||||
std::rc::Weak::<Void>::new();
|
||||
std::sync::Weak::<Void>::new();
|
||||
}
|
@ -10,18 +10,18 @@ error[E0017]: references in statics may only refer to immutable values
|
||||
LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
|
||||
| ^^^^^^ statics require immutable values
|
||||
|
||||
error[E0017]: references in statics may only refer to immutable values
|
||||
--> $DIR/E0017.rs:17:38
|
||||
|
|
||||
LL | static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
|
||||
| ^^^^^^ statics require immutable values
|
||||
|
||||
error[E0596]: cannot borrow immutable item `X` as mutable
|
||||
--> $DIR/E0017.rs:15:39
|
||||
|
|
||||
LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
|
||||
| ^^^^^^ cannot borrow as mutable
|
||||
|
||||
error[E0017]: references in statics may only refer to immutable values
|
||||
--> $DIR/E0017.rs:17:38
|
||||
|
|
||||
LL | static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
|
||||
| ^^^^^^ statics require immutable values
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors occurred: E0017, E0596.
|
||||
|
@ -10,18 +10,18 @@ error[E0017]: references in statics may only refer to immutable values
|
||||
LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
|
||||
| ^^^^^^ statics require immutable values
|
||||
|
||||
error[E0017]: references in statics may only refer to immutable values
|
||||
--> $DIR/E0388.rs:17:38
|
||||
|
|
||||
LL | static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
|
||||
| ^^^^^^ statics require immutable values
|
||||
|
||||
error[E0596]: cannot borrow immutable item `X` as mutable
|
||||
--> $DIR/E0388.rs:15:39
|
||||
|
|
||||
LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
|
||||
| ^^^^^^ cannot borrow as mutable
|
||||
|
||||
error[E0017]: references in statics may only refer to immutable values
|
||||
--> $DIR/E0388.rs:17:38
|
||||
|
|
||||
LL | static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
|
||||
| ^^^^^^ statics require immutable values
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors occurred: E0017, E0596.
|
||||
|
@ -2,10 +2,9 @@ error[E0597]: borrowed value does not live long enough
|
||||
--> $DIR/issue-47184.rs:14:44
|
||||
|
|
||||
LL | let _vec: Vec<&'static String> = vec![&String::new()];
|
||||
| ^^^^^^^^^^^^^ temporary value does not live long enough
|
||||
LL | //~^ ERROR borrowed value does not live long enough [E0597]
|
||||
LL | }
|
||||
| - temporary value only lives until here
|
||||
| ^^^^^^^^^^^^^ - temporary value only lives until here
|
||||
| |
|
||||
| temporary value does not live long enough
|
||||
|
|
||||
= note: borrowed value must be valid for the static lifetime...
|
||||
|
||||
|
@ -55,6 +55,18 @@ LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Mir)
|
||||
--> $DIR/get_default.rs:45:17
|
||||
|
|
||||
LL | match map.get() {
|
||||
| --- immutable borrow occurs here
|
||||
LL | Some(v) => {
|
||||
LL | map.set(String::new()); // Both AST and MIR error here
|
||||
| ^^^ mutable borrow occurs here
|
||||
...
|
||||
LL | return v;
|
||||
| - borrow later used here
|
||||
|
||||
error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Mir)
|
||||
--> $DIR/get_default.rs:51:17
|
||||
|
|
||||
@ -76,18 +88,6 @@ LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Mir)
|
||||
--> $DIR/get_default.rs:45:17
|
||||
|
|
||||
LL | match map.get() {
|
||||
| --- immutable borrow occurs here
|
||||
LL | Some(v) => {
|
||||
LL | map.set(String::new()); // Both AST and MIR error here
|
||||
| ^^^ mutable borrow occurs here
|
||||
...
|
||||
LL | return v;
|
||||
| - borrow later used here
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0502`.
|
||||
|
@ -1,7 +1,7 @@
|
||||
error[E0597]: `b1` does not live long enough
|
||||
--> $DIR/dropck_arr_cycle_checked.rs:111:24
|
||||
error[E0597]: `b3` does not live long enough
|
||||
--> $DIR/dropck_arr_cycle_checked.rs:105:24
|
||||
|
|
||||
LL | b3.a[0].v.set(Some(&b1));
|
||||
LL | b1.a[1].v.set(Some(&b3));
|
||||
| ^^^ borrowed value does not live long enough
|
||||
...
|
||||
LL | }
|
||||
@ -22,10 +22,10 @@ LL | }
|
||||
| borrowed value only lives until here
|
||||
| borrow later used here, when `b1` is dropped
|
||||
|
||||
error[E0597]: `b3` does not live long enough
|
||||
--> $DIR/dropck_arr_cycle_checked.rs:105:24
|
||||
error[E0597]: `b1` does not live long enough
|
||||
--> $DIR/dropck_arr_cycle_checked.rs:111:24
|
||||
|
|
||||
LL | b1.a[1].v.set(Some(&b3));
|
||||
LL | b3.a[0].v.set(Some(&b1));
|
||||
| ^^^ borrowed value does not live long enough
|
||||
...
|
||||
LL | }
|
||||
|
@ -1,17 +1,3 @@
|
||||
error[E0597]: `d1` does not live long enough
|
||||
--> $DIR/dropck_direct_cycle_with_drop.rs:48:19
|
||||
|
|
||||
LL | d2.p.set(Some(&d1));
|
||||
| ^^^ borrowed value does not live long enough
|
||||
LL | //~^ ERROR `d1` does not live long enough
|
||||
LL | }
|
||||
| -
|
||||
| |
|
||||
| borrowed value only lives until here
|
||||
| borrow later used here, when `d1` is dropped
|
||||
|
|
||||
= note: values in a scope are dropped in the opposite order they are defined
|
||||
|
||||
error[E0597]: `d2` does not live long enough
|
||||
--> $DIR/dropck_direct_cycle_with_drop.rs:46:19
|
||||
|
|
||||
@ -26,6 +12,20 @@ LL | }
|
||||
|
|
||||
= note: values in a scope are dropped in the opposite order they are defined
|
||||
|
||||
error[E0597]: `d1` does not live long enough
|
||||
--> $DIR/dropck_direct_cycle_with_drop.rs:48:19
|
||||
|
|
||||
LL | d2.p.set(Some(&d1));
|
||||
| ^^^ borrowed value does not live long enough
|
||||
LL | //~^ ERROR `d1` does not live long enough
|
||||
LL | }
|
||||
| -
|
||||
| |
|
||||
| borrowed value only lives until here
|
||||
| borrow later used here, when `d1` is dropped
|
||||
|
|
||||
= note: values in a scope are dropped in the opposite order they are defined
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0597`.
|
||||
|
@ -1,7 +1,7 @@
|
||||
error[E0597]: `c1` does not live long enough
|
||||
--> $DIR/dropck_vec_cycle_checked.rs:121:24
|
||||
error[E0597]: `c3` does not live long enough
|
||||
--> $DIR/dropck_vec_cycle_checked.rs:115:24
|
||||
|
|
||||
LL | c3.v[0].v.set(Some(&c1));
|
||||
LL | c1.v[1].v.set(Some(&c3));
|
||||
| ^^^ borrowed value does not live long enough
|
||||
...
|
||||
LL | }
|
||||
@ -22,10 +22,10 @@ LL | }
|
||||
| borrowed value only lives until here
|
||||
| borrow later used here, when `c1` is dropped
|
||||
|
||||
error[E0597]: `c3` does not live long enough
|
||||
--> $DIR/dropck_vec_cycle_checked.rs:115:24
|
||||
error[E0597]: `c1` does not live long enough
|
||||
--> $DIR/dropck_vec_cycle_checked.rs:121:24
|
||||
|
|
||||
LL | c1.v[1].v.set(Some(&c3));
|
||||
LL | c3.v[0].v.set(Some(&c1));
|
||||
| ^^^ borrowed value does not live long enough
|
||||
...
|
||||
LL | }
|
||||
|
@ -1,15 +1,3 @@
|
||||
error[E0597]: `c1` does not live long enough
|
||||
--> $DIR/vec-must-not-hide-type-from-dropck.rs:129:24
|
||||
|
|
||||
LL | c2.v[0].v.set(Some(&c1));
|
||||
| ^^^ borrowed value does not live long enough
|
||||
LL | //~^ ERROR `c1` does not live long enough
|
||||
LL | }
|
||||
| -
|
||||
| |
|
||||
| borrowed value only lives until here
|
||||
| borrow later used here, when `c1` is dropped
|
||||
|
||||
error[E0597]: `c2` does not live long enough
|
||||
--> $DIR/vec-must-not-hide-type-from-dropck.rs:127:24
|
||||
|
|
||||
@ -22,6 +10,18 @@ LL | }
|
||||
| borrowed value only lives until here
|
||||
| borrow later used here, when `c1` is dropped
|
||||
|
||||
error[E0597]: `c1` does not live long enough
|
||||
--> $DIR/vec-must-not-hide-type-from-dropck.rs:129:24
|
||||
|
|
||||
LL | c2.v[0].v.set(Some(&c1));
|
||||
| ^^^ borrowed value does not live long enough
|
||||
LL | //~^ ERROR `c1` does not live long enough
|
||||
LL | }
|
||||
| -
|
||||
| |
|
||||
| borrowed value only lives until here
|
||||
| borrow later used here, when `c1` is dropped
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0597`.
|
||||
|
@ -6,7 +6,7 @@ version = "0.0.0"
|
||||
[dependencies]
|
||||
diff = "0.1.10"
|
||||
env_logger = { version = "0.5", default-features = false }
|
||||
filetime = "0.1"
|
||||
filetime = "0.2"
|
||||
getopts = "0.2"
|
||||
log = "0.4"
|
||||
regex = "0.2"
|
||||
|
Loading…
Reference in New Issue
Block a user