mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-10 05:53:10 +00:00
Auto merge of #24737 - P1start:dst-cell, r=alexcrichton
This + DST coercions (#24619) would allow code like `Rc<RefCell<Box<Trait>>>` to be simplified to `Rc<RefCell<Trait>>`.
This commit is contained in:
commit
1a60dc4fc4
@ -144,7 +144,7 @@
|
|||||||
use clone::Clone;
|
use clone::Clone;
|
||||||
use cmp::PartialEq;
|
use cmp::PartialEq;
|
||||||
use default::Default;
|
use default::Default;
|
||||||
use marker::{Copy, Send, Sync};
|
use marker::{Copy, Send, Sync, Sized};
|
||||||
use ops::{Deref, DerefMut, Drop};
|
use ops::{Deref, DerefMut, Drop};
|
||||||
use option::Option;
|
use option::Option;
|
||||||
use option::Option::{None, Some};
|
use option::Option::{None, Some};
|
||||||
@ -266,9 +266,9 @@ impl<T:PartialEq + Copy> PartialEq for Cell<T> {
|
|||||||
///
|
///
|
||||||
/// See the [module-level documentation](index.html) for more.
|
/// See the [module-level documentation](index.html) for more.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub struct RefCell<T> {
|
pub struct RefCell<T: ?Sized> {
|
||||||
value: UnsafeCell<T>,
|
|
||||||
borrow: Cell<BorrowFlag>,
|
borrow: Cell<BorrowFlag>,
|
||||||
|
value: UnsafeCell<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An enumeration of values returned from the `state` method on a `RefCell<T>`.
|
/// An enumeration of values returned from the `state` method on a `RefCell<T>`.
|
||||||
@ -328,7 +328,9 @@ impl<T> RefCell<T> {
|
|||||||
debug_assert!(self.borrow.get() == UNUSED);
|
debug_assert!(self.borrow.get() == UNUSED);
|
||||||
unsafe { self.value.into_inner() }
|
unsafe { self.value.into_inner() }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized> RefCell<T> {
|
||||||
/// Query the current state of this `RefCell`
|
/// Query the current state of this `RefCell`
|
||||||
///
|
///
|
||||||
/// The returned value can be dispatched on to determine if a call to
|
/// The returned value can be dispatched on to determine if a call to
|
||||||
@ -449,7 +451,7 @@ impl<T> RefCell<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
unsafe impl<T> Send for RefCell<T> where T: Send {}
|
unsafe impl<T: ?Sized> Send for RefCell<T> where T: Send {}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T: Clone> Clone for RefCell<T> {
|
impl<T: Clone> Clone for RefCell<T> {
|
||||||
@ -469,7 +471,7 @@ impl<T:Default> Default for RefCell<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T: PartialEq> PartialEq for RefCell<T> {
|
impl<T: ?Sized + PartialEq> PartialEq for RefCell<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn eq(&self, other: &RefCell<T>) -> bool {
|
fn eq(&self, other: &RefCell<T>) -> bool {
|
||||||
*self.borrow() == *other.borrow()
|
*self.borrow() == *other.borrow()
|
||||||
@ -519,7 +521,7 @@ impl<'b> Clone for BorrowRef<'b> {
|
|||||||
///
|
///
|
||||||
/// See the [module-level documentation](index.html) for more.
|
/// See the [module-level documentation](index.html) for more.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub struct Ref<'b, T:'b> {
|
pub struct Ref<'b, T: ?Sized + 'b> {
|
||||||
// FIXME #12808: strange name to try to avoid interfering with
|
// FIXME #12808: strange name to try to avoid interfering with
|
||||||
// field accesses of the contained type via Deref
|
// field accesses of the contained type via Deref
|
||||||
_value: &'b T,
|
_value: &'b T,
|
||||||
@ -527,7 +529,7 @@ pub struct Ref<'b, T:'b> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<'b, T> Deref for Ref<'b, T> {
|
impl<'b, T: ?Sized> Deref for Ref<'b, T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -582,7 +584,7 @@ impl<'b> BorrowRefMut<'b> {
|
|||||||
///
|
///
|
||||||
/// See the [module-level documentation](index.html) for more.
|
/// See the [module-level documentation](index.html) for more.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub struct RefMut<'b, T:'b> {
|
pub struct RefMut<'b, T: ?Sized + 'b> {
|
||||||
// FIXME #12808: strange name to try to avoid interfering with
|
// FIXME #12808: strange name to try to avoid interfering with
|
||||||
// field accesses of the contained type via Deref
|
// field accesses of the contained type via Deref
|
||||||
_value: &'b mut T,
|
_value: &'b mut T,
|
||||||
@ -590,7 +592,7 @@ pub struct RefMut<'b, T:'b> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<'b, T> Deref for RefMut<'b, T> {
|
impl<'b, T: ?Sized> Deref for RefMut<'b, T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -600,7 +602,7 @@ impl<'b, T> Deref for RefMut<'b, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<'b, T> DerefMut for RefMut<'b, T> {
|
impl<'b, T: ?Sized> DerefMut for RefMut<'b, T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn deref_mut<'a>(&'a mut self) -> &'a mut T {
|
fn deref_mut<'a>(&'a mut self) -> &'a mut T {
|
||||||
self._value
|
self._value
|
||||||
@ -633,7 +635,7 @@ impl<'b, T> DerefMut for RefMut<'b, T> {
|
|||||||
/// recommended to access its fields directly, `get` should be used instead.
|
/// recommended to access its fields directly, `get` should be used instead.
|
||||||
#[lang="unsafe_cell"]
|
#[lang="unsafe_cell"]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub struct UnsafeCell<T> {
|
pub struct UnsafeCell<T: ?Sized> {
|
||||||
/// Wrapped value
|
/// Wrapped value
|
||||||
///
|
///
|
||||||
/// This field should not be accessed directly, it is made public for static
|
/// This field should not be accessed directly, it is made public for static
|
||||||
@ -642,7 +644,7 @@ pub struct UnsafeCell<T> {
|
|||||||
pub value: T,
|
pub value: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> !Sync for UnsafeCell<T> {}
|
impl<T: ?Sized> !Sync for UnsafeCell<T> {}
|
||||||
|
|
||||||
impl<T> UnsafeCell<T> {
|
impl<T> UnsafeCell<T> {
|
||||||
/// Constructs a new instance of `UnsafeCell` which will wrap the specified
|
/// Constructs a new instance of `UnsafeCell` which will wrap the specified
|
||||||
@ -664,25 +666,6 @@ impl<T> UnsafeCell<T> {
|
|||||||
UnsafeCell { value: value }
|
UnsafeCell { value: value }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a mutable pointer to the wrapped value.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::cell::UnsafeCell;
|
|
||||||
///
|
|
||||||
/// let uc = UnsafeCell::new(5);
|
|
||||||
///
|
|
||||||
/// let five = uc.get();
|
|
||||||
/// ```
|
|
||||||
#[inline]
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
pub fn get(&self) -> *mut T {
|
|
||||||
// FIXME(#23542) Replace with type ascription.
|
|
||||||
#![allow(trivial_casts)]
|
|
||||||
&self.value as *const T as *mut T
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Unwraps the value.
|
/// Unwraps the value.
|
||||||
///
|
///
|
||||||
/// # Unsafety
|
/// # Unsafety
|
||||||
@ -703,3 +686,25 @@ impl<T> UnsafeCell<T> {
|
|||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub unsafe fn into_inner(self) -> T { self.value }
|
pub unsafe fn into_inner(self) -> T { self.value }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized> UnsafeCell<T> {
|
||||||
|
/// Gets a mutable pointer to the wrapped value.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::cell::UnsafeCell;
|
||||||
|
///
|
||||||
|
/// let uc = UnsafeCell::new(5);
|
||||||
|
///
|
||||||
|
/// let five = uc.get();
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
pub fn get(&self) -> *mut T {
|
||||||
|
// FIXME(#23542) Replace with type ascription.
|
||||||
|
#![allow(trivial_casts)]
|
||||||
|
&self.value as *const T as *mut T
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -1062,7 +1062,7 @@ impl<T: Copy + Debug> Debug for Cell<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T: Debug> Debug for RefCell<T> {
|
impl<T: ?Sized + Debug> Debug for RefCell<T> {
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||||
match self.borrow_state() {
|
match self.borrow_state() {
|
||||||
BorrowState::Unused | BorrowState::Reading => {
|
BorrowState::Unused | BorrowState::Reading => {
|
||||||
@ -1074,14 +1074,14 @@ impl<T: Debug> Debug for RefCell<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<'b, T: Debug> Debug for Ref<'b, T> {
|
impl<'b, T: ?Sized + Debug> Debug for Ref<'b, T> {
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||||
Debug::fmt(&**self, f)
|
Debug::fmt(&**self, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<'b, T: Debug> Debug for RefMut<'b, T> {
|
impl<'b, T: ?Sized + Debug> Debug for RefMut<'b, T> {
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||||
Debug::fmt(&*(self.deref()), f)
|
Debug::fmt(&*(self.deref()), f)
|
||||||
}
|
}
|
||||||
|
@ -159,3 +159,27 @@ fn refcell_default() {
|
|||||||
let cell: RefCell<u64> = Default::default();
|
let cell: RefCell<u64> = Default::default();
|
||||||
assert_eq!(0, *cell.borrow());
|
assert_eq!(0, *cell.borrow());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn unsafe_cell_unsized() {
|
||||||
|
let cell: &UnsafeCell<[i32]> = &UnsafeCell::new([1, 2, 3]);
|
||||||
|
{
|
||||||
|
let val: &mut [i32] = unsafe { &mut *cell.get() };
|
||||||
|
val[0] = 4;
|
||||||
|
val[2] = 5;
|
||||||
|
}
|
||||||
|
let comp: &mut [i32] = &mut [4, 2, 5];
|
||||||
|
assert_eq!(unsafe { &mut *cell.get() }, comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn refcell_unsized() {
|
||||||
|
let cell: &RefCell<[i32]> = &RefCell::new([1, 2, 3]);
|
||||||
|
{
|
||||||
|
let b = &mut *cell.borrow_mut();
|
||||||
|
b[0] = 4;
|
||||||
|
b[2] = 5;
|
||||||
|
}
|
||||||
|
let comp: &mut [i32] = &mut [4, 2, 5];
|
||||||
|
assert_eq!(&*cell.borrow(), comp);
|
||||||
|
}
|
||||||
|
@ -112,7 +112,7 @@ use sys_common::poison::{self, TryLockError, TryLockResult, LockResult};
|
|||||||
/// *guard += 1;
|
/// *guard += 1;
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub struct Mutex<T> {
|
pub struct Mutex<T: ?Sized> {
|
||||||
// Note that this static mutex is in a *box*, not inlined into the struct
|
// Note that this static mutex is in a *box*, not inlined into the struct
|
||||||
// itself. Once a native mutex has been used once, its address can never
|
// itself. Once a native mutex has been used once, its address can never
|
||||||
// change (it can't be moved). This mutex type can be safely moved at any
|
// change (it can't be moved). This mutex type can be safely moved at any
|
||||||
@ -124,9 +124,9 @@ pub struct Mutex<T> {
|
|||||||
|
|
||||||
// these are the only places where `T: Send` matters; all other
|
// these are the only places where `T: Send` matters; all other
|
||||||
// functionality works fine on a single thread.
|
// functionality works fine on a single thread.
|
||||||
unsafe impl<T: Send> Send for Mutex<T> { }
|
unsafe impl<T: ?Sized + Send> Send for Mutex<T> { }
|
||||||
|
|
||||||
unsafe impl<T: Send> Sync for Mutex<T> { }
|
unsafe impl<T: ?Sized + Send> Sync for Mutex<T> { }
|
||||||
|
|
||||||
/// The static mutex type is provided to allow for static allocation of mutexes.
|
/// The static mutex type is provided to allow for static allocation of mutexes.
|
||||||
///
|
///
|
||||||
@ -164,7 +164,7 @@ pub struct StaticMutex {
|
|||||||
/// `Deref` and `DerefMut` implementations
|
/// `Deref` and `DerefMut` implementations
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub struct MutexGuard<'a, T: 'a> {
|
pub struct MutexGuard<'a, T: ?Sized + 'a> {
|
||||||
// funny underscores due to how Deref/DerefMut currently work (they
|
// funny underscores due to how Deref/DerefMut currently work (they
|
||||||
// disregard field privacy).
|
// disregard field privacy).
|
||||||
__lock: &'a StaticMutex,
|
__lock: &'a StaticMutex,
|
||||||
@ -172,7 +172,7 @@ pub struct MutexGuard<'a, T: 'a> {
|
|||||||
__poison: poison::Guard,
|
__poison: poison::Guard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> !marker::Send for MutexGuard<'a, T> {}
|
impl<'a, T: ?Sized> !marker::Send for MutexGuard<'a, T> {}
|
||||||
|
|
||||||
/// Static initialization of a mutex. This constant can be used to initialize
|
/// Static initialization of a mutex. This constant can be used to initialize
|
||||||
/// other mutex constants.
|
/// other mutex constants.
|
||||||
@ -192,7 +192,9 @@ impl<T> Mutex<T> {
|
|||||||
data: UnsafeCell::new(t),
|
data: UnsafeCell::new(t),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized> Mutex<T> {
|
||||||
/// Acquires a mutex, blocking the current task until it is able to do so.
|
/// Acquires a mutex, blocking the current task until it is able to do so.
|
||||||
///
|
///
|
||||||
/// This function will block the local task until it is available to acquire
|
/// This function will block the local task until it is available to acquire
|
||||||
@ -245,7 +247,7 @@ impl<T> Mutex<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T> Drop for Mutex<T> {
|
impl<T: ?Sized> Drop for Mutex<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
// This is actually safe b/c we know that there is no further usage of
|
// This is actually safe b/c we know that there is no further usage of
|
||||||
// this mutex (it's up to the user to arrange for a mutex to get
|
// this mutex (it's up to the user to arrange for a mutex to get
|
||||||
@ -255,12 +257,12 @@ impl<T> Drop for Mutex<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T: fmt::Debug + 'static> fmt::Debug for Mutex<T> {
|
impl<T: ?Sized + fmt::Debug + 'static> fmt::Debug for Mutex<T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self.try_lock() {
|
match self.try_lock() {
|
||||||
Ok(guard) => write!(f, "Mutex {{ data: {:?} }}", *guard),
|
Ok(guard) => write!(f, "Mutex {{ data: {:?} }}", &*guard),
|
||||||
Err(TryLockError::Poisoned(err)) => {
|
Err(TryLockError::Poisoned(err)) => {
|
||||||
write!(f, "Mutex {{ data: Poisoned({:?}) }}", **err.get_ref())
|
write!(f, "Mutex {{ data: Poisoned({:?}) }}", &**err.get_ref())
|
||||||
},
|
},
|
||||||
Err(TryLockError::WouldBlock) => write!(f, "Mutex {{ <locked> }}")
|
Err(TryLockError::WouldBlock) => write!(f, "Mutex {{ <locked> }}")
|
||||||
}
|
}
|
||||||
@ -310,7 +312,7 @@ impl StaticMutex {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'mutex, T> MutexGuard<'mutex, T> {
|
impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> {
|
||||||
|
|
||||||
fn new(lock: &'mutex StaticMutex, data: &'mutex UnsafeCell<T>)
|
fn new(lock: &'mutex StaticMutex, data: &'mutex UnsafeCell<T>)
|
||||||
-> LockResult<MutexGuard<'mutex, T>> {
|
-> LockResult<MutexGuard<'mutex, T>> {
|
||||||
@ -325,7 +327,7 @@ impl<'mutex, T> MutexGuard<'mutex, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<'mutex, T> Deref for MutexGuard<'mutex, T> {
|
impl<'mutex, T: ?Sized> Deref for MutexGuard<'mutex, T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
fn deref<'a>(&'a self) -> &'a T {
|
fn deref<'a>(&'a self) -> &'a T {
|
||||||
@ -333,14 +335,14 @@ impl<'mutex, T> Deref for MutexGuard<'mutex, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<'mutex, T> DerefMut for MutexGuard<'mutex, T> {
|
impl<'mutex, T: ?Sized> DerefMut for MutexGuard<'mutex, T> {
|
||||||
fn deref_mut<'a>(&'a mut self) -> &'a mut T {
|
fn deref_mut<'a>(&'a mut self) -> &'a mut T {
|
||||||
unsafe { &mut *self.__data.get() }
|
unsafe { &mut *self.__data.get() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<'a, T> Drop for MutexGuard<'a, T> {
|
impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -350,11 +352,11 @@ impl<'a, T> Drop for MutexGuard<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn guard_lock<'a, T>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex {
|
pub fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex {
|
||||||
&guard.__lock.lock
|
&guard.__lock.lock
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn guard_poison<'a, T>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag {
|
pub fn guard_poison<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag {
|
||||||
&guard.__lock.poison
|
&guard.__lock.poison
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,4 +530,16 @@ mod tests {
|
|||||||
let lock = arc.lock().unwrap();
|
let lock = arc.lock().unwrap();
|
||||||
assert_eq!(*lock, 2);
|
assert_eq!(*lock, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_mutex_unsized() {
|
||||||
|
let mutex: &Mutex<[i32]> = &Mutex::new([1, 2, 3]);
|
||||||
|
{
|
||||||
|
let b = &mut *mutex.lock().unwrap();
|
||||||
|
b[0] = 4;
|
||||||
|
b[2] = 5;
|
||||||
|
}
|
||||||
|
let comp: &[i32] = &[4, 2, 5];
|
||||||
|
assert_eq!(&*mutex.lock().unwrap(), comp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,13 +60,13 @@ use sys_common::rwlock as sys;
|
|||||||
/// } // write lock is dropped here
|
/// } // write lock is dropped here
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub struct RwLock<T> {
|
pub struct RwLock<T: ?Sized> {
|
||||||
inner: Box<StaticRwLock>,
|
inner: Box<StaticRwLock>,
|
||||||
data: UnsafeCell<T>,
|
data: UnsafeCell<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<T: Send + Sync> Send for RwLock<T> {}
|
unsafe impl<T: ?Sized + Send + Sync> Send for RwLock<T> {}
|
||||||
unsafe impl<T: Send + Sync> Sync for RwLock<T> {}
|
unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
|
||||||
|
|
||||||
/// Structure representing a statically allocated RwLock.
|
/// Structure representing a statically allocated RwLock.
|
||||||
///
|
///
|
||||||
@ -111,24 +111,24 @@ pub const RW_LOCK_INIT: StaticRwLock = StaticRwLock {
|
|||||||
/// dropped.
|
/// dropped.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub struct RwLockReadGuard<'a, T: 'a> {
|
pub struct RwLockReadGuard<'a, T: ?Sized + 'a> {
|
||||||
__lock: &'a StaticRwLock,
|
__lock: &'a StaticRwLock,
|
||||||
__data: &'a UnsafeCell<T>,
|
__data: &'a UnsafeCell<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> !marker::Send for RwLockReadGuard<'a, T> {}
|
impl<'a, T: ?Sized> !marker::Send for RwLockReadGuard<'a, T> {}
|
||||||
|
|
||||||
/// RAII structure used to release the exclusive write access of a lock when
|
/// RAII structure used to release the exclusive write access of a lock when
|
||||||
/// dropped.
|
/// dropped.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub struct RwLockWriteGuard<'a, T: 'a> {
|
pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> {
|
||||||
__lock: &'a StaticRwLock,
|
__lock: &'a StaticRwLock,
|
||||||
__data: &'a UnsafeCell<T>,
|
__data: &'a UnsafeCell<T>,
|
||||||
__poison: poison::Guard,
|
__poison: poison::Guard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> !marker::Send for RwLockWriteGuard<'a, T> {}
|
impl<'a, T: ?Sized> !marker::Send for RwLockWriteGuard<'a, T> {}
|
||||||
|
|
||||||
impl<T> RwLock<T> {
|
impl<T> RwLock<T> {
|
||||||
/// Creates a new instance of an `RwLock<T>` which is unlocked.
|
/// Creates a new instance of an `RwLock<T>` which is unlocked.
|
||||||
@ -144,7 +144,9 @@ impl<T> RwLock<T> {
|
|||||||
pub fn new(t: T) -> RwLock<T> {
|
pub fn new(t: T) -> RwLock<T> {
|
||||||
RwLock { inner: box RW_LOCK_INIT, data: UnsafeCell::new(t) }
|
RwLock { inner: box RW_LOCK_INIT, data: UnsafeCell::new(t) }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized> RwLock<T> {
|
||||||
/// Locks this rwlock with shared read access, blocking the current thread
|
/// Locks this rwlock with shared read access, blocking the current thread
|
||||||
/// until it can be acquired.
|
/// until it can be acquired.
|
||||||
///
|
///
|
||||||
@ -250,19 +252,19 @@ impl<T> RwLock<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T> Drop for RwLock<T> {
|
impl<T: ?Sized> Drop for RwLock<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe { self.inner.lock.destroy() }
|
unsafe { self.inner.lock.destroy() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T: fmt::Debug> fmt::Debug for RwLock<T> {
|
impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLock<T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self.try_read() {
|
match self.try_read() {
|
||||||
Ok(guard) => write!(f, "RwLock {{ data: {:?} }}", *guard),
|
Ok(guard) => write!(f, "RwLock {{ data: {:?} }}", &*guard),
|
||||||
Err(TryLockError::Poisoned(err)) => {
|
Err(TryLockError::Poisoned(err)) => {
|
||||||
write!(f, "RwLock {{ data: Poisoned({:?}) }}", **err.get_ref())
|
write!(f, "RwLock {{ data: Poisoned({:?}) }}", &**err.get_ref())
|
||||||
},
|
},
|
||||||
Err(TryLockError::WouldBlock) => write!(f, "RwLock {{ <locked> }}")
|
Err(TryLockError::WouldBlock) => write!(f, "RwLock {{ <locked> }}")
|
||||||
}
|
}
|
||||||
@ -341,8 +343,7 @@ impl StaticRwLock {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'rwlock, T> RwLockReadGuard<'rwlock, T> {
|
impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
|
||||||
|
|
||||||
fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell<T>)
|
fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell<T>)
|
||||||
-> LockResult<RwLockReadGuard<'rwlock, T>> {
|
-> LockResult<RwLockReadGuard<'rwlock, T>> {
|
||||||
poison::map_result(lock.poison.borrow(), |_| {
|
poison::map_result(lock.poison.borrow(), |_| {
|
||||||
@ -353,8 +354,8 @@ impl<'rwlock, T> RwLockReadGuard<'rwlock, T> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'rwlock, T> RwLockWriteGuard<'rwlock, T> {
|
|
||||||
|
|
||||||
|
impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
|
||||||
fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell<T>)
|
fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell<T>)
|
||||||
-> LockResult<RwLockWriteGuard<'rwlock, T>> {
|
-> LockResult<RwLockWriteGuard<'rwlock, T>> {
|
||||||
poison::map_result(lock.poison.borrow(), |guard| {
|
poison::map_result(lock.poison.borrow(), |guard| {
|
||||||
@ -368,33 +369,35 @@ impl<'rwlock, T> RwLockWriteGuard<'rwlock, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<'rwlock, T> Deref for RwLockReadGuard<'rwlock, T> {
|
impl<'rwlock, T: ?Sized> Deref for RwLockReadGuard<'rwlock, T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
fn deref(&self) -> &T { unsafe { &*self.__data.get() } }
|
fn deref(&self) -> &T { unsafe { &*self.__data.get() } }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<'rwlock, T> Deref for RwLockWriteGuard<'rwlock, T> {
|
impl<'rwlock, T: ?Sized> Deref for RwLockWriteGuard<'rwlock, T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
fn deref(&self) -> &T { unsafe { &*self.__data.get() } }
|
fn deref(&self) -> &T { unsafe { &*self.__data.get() } }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<'rwlock, T> DerefMut for RwLockWriteGuard<'rwlock, T> {
|
impl<'rwlock, T: ?Sized> DerefMut for RwLockWriteGuard<'rwlock, T> {
|
||||||
fn deref_mut(&mut self) -> &mut T {
|
fn deref_mut(&mut self) -> &mut T {
|
||||||
unsafe { &mut *self.__data.get() }
|
unsafe { &mut *self.__data.get() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<'a, T> Drop for RwLockReadGuard<'a, T> {
|
impl<'a, T: ?Sized> Drop for RwLockReadGuard<'a, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe { self.__lock.lock.read_unlock(); }
|
unsafe { self.__lock.lock.read_unlock(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<'a, T> Drop for RwLockWriteGuard<'a, T> {
|
impl<'a, T: ?Sized> Drop for RwLockWriteGuard<'a, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.__lock.poison.done(&self.__poison);
|
self.__lock.poison.done(&self.__poison);
|
||||||
unsafe { self.__lock.lock.write_unlock(); }
|
unsafe { self.__lock.lock.write_unlock(); }
|
||||||
@ -562,4 +565,16 @@ mod tests {
|
|||||||
let lock = arc.read().unwrap();
|
let lock = arc.read().unwrap();
|
||||||
assert_eq!(*lock, 2);
|
assert_eq!(*lock, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_rwlock_unsized() {
|
||||||
|
let rw: &RwLock<[i32]> = &RwLock::new([1, 2, 3]);
|
||||||
|
{
|
||||||
|
let b = &mut *rw.write().unwrap();
|
||||||
|
b[0] = 4;
|
||||||
|
b[2] = 5;
|
||||||
|
}
|
||||||
|
let comp: &[i32] = &[4, 2, 5];
|
||||||
|
assert_eq!(&*rw.read().unwrap(), comp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,14 +8,10 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use std::cell::RefCell;
|
|
||||||
|
|
||||||
trait Trait {}
|
trait Trait {}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let x: Vec<Trait + Sized> = Vec::new();
|
let x: Vec<Trait + Sized> = Vec::new();
|
||||||
//~^ ERROR the trait `core::marker::Sized` is not implemented
|
//~^ ERROR the trait `core::marker::Sized` is not implemented
|
||||||
//~^^ ERROR the trait `core::marker::Sized` is not implemented
|
//~^^ ERROR the trait `core::marker::Sized` is not implemented
|
||||||
let x: Vec<Box<RefCell<Trait + Sized>>> = Vec::new();
|
|
||||||
//~^ ERROR the trait `core::marker::Sized` is not implemented
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user