Skip to content

Commit c22693d

Browse files
committed
Auto merge of #24737 - P1start:dst-cell, r=luqmana
This + DST coercions (#24619) would allow code like `Rc<RefCell<Box<Trait>>>` to be simplified to `Rc<RefCell<Trait>>`.
2 parents 5c710b5 + 17876ec commit c22693d

File tree

5 files changed

+122
-64
lines changed

5 files changed

+122
-64
lines changed

src/libcore/cell.rs

+32-27
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@
144144
use clone::Clone;
145145
use cmp::PartialEq;
146146
use default::Default;
147-
use marker::{Copy, Send, Sync};
147+
use marker::{Copy, Send, Sync, Sized};
148148
use ops::{Deref, DerefMut, Drop};
149149
use option::Option;
150150
use option::Option::{None, Some};
@@ -266,9 +266,9 @@ impl<T:PartialEq + Copy> PartialEq for Cell<T> {
266266
///
267267
/// See the [module-level documentation](index.html) for more.
268268
#[stable(feature = "rust1", since = "1.0.0")]
269-
pub struct RefCell<T> {
270-
value: UnsafeCell<T>,
269+
pub struct RefCell<T: ?Sized> {
271270
borrow: Cell<BorrowFlag>,
271+
value: UnsafeCell<T>,
272272
}
273273

274274
/// An enumeration of values returned from the `state` method on a `RefCell<T>`.
@@ -328,7 +328,9 @@ impl<T> RefCell<T> {
328328
debug_assert!(self.borrow.get() == UNUSED);
329329
unsafe { self.value.into_inner() }
330330
}
331+
}
331332

333+
impl<T: ?Sized> RefCell<T> {
332334
/// Query the current state of this `RefCell`
333335
///
334336
/// The returned value can be dispatched on to determine if a call to
@@ -449,7 +451,7 @@ impl<T> RefCell<T> {
449451
}
450452

451453
#[stable(feature = "rust1", since = "1.0.0")]
452-
unsafe impl<T> Send for RefCell<T> where T: Send {}
454+
unsafe impl<T: ?Sized> Send for RefCell<T> where T: Send {}
453455

454456
#[stable(feature = "rust1", since = "1.0.0")]
455457
impl<T: Clone> Clone for RefCell<T> {
@@ -469,7 +471,7 @@ impl<T:Default> Default for RefCell<T> {
469471
}
470472

471473
#[stable(feature = "rust1", since = "1.0.0")]
472-
impl<T: PartialEq> PartialEq for RefCell<T> {
474+
impl<T: ?Sized + PartialEq> PartialEq for RefCell<T> {
473475
#[inline]
474476
fn eq(&self, other: &RefCell<T>) -> bool {
475477
*self.borrow() == *other.borrow()
@@ -519,15 +521,15 @@ impl<'b> Clone for BorrowRef<'b> {
519521
///
520522
/// See the [module-level documentation](index.html) for more.
521523
#[stable(feature = "rust1", since = "1.0.0")]
522-
pub struct Ref<'b, T:'b> {
524+
pub struct Ref<'b, T: ?Sized + 'b> {
523525
// FIXME #12808: strange name to try to avoid interfering with
524526
// field accesses of the contained type via Deref
525527
_value: &'b T,
526528
_borrow: BorrowRef<'b>,
527529
}
528530

529531
#[stable(feature = "rust1", since = "1.0.0")]
530-
impl<'b, T> Deref for Ref<'b, T> {
532+
impl<'b, T: ?Sized> Deref for Ref<'b, T> {
531533
type Target = T;
532534

533535
#[inline]
@@ -582,15 +584,15 @@ impl<'b> BorrowRefMut<'b> {
582584
///
583585
/// See the [module-level documentation](index.html) for more.
584586
#[stable(feature = "rust1", since = "1.0.0")]
585-
pub struct RefMut<'b, T:'b> {
587+
pub struct RefMut<'b, T: ?Sized + 'b> {
586588
// FIXME #12808: strange name to try to avoid interfering with
587589
// field accesses of the contained type via Deref
588590
_value: &'b mut T,
589591
_borrow: BorrowRefMut<'b>,
590592
}
591593

592594
#[stable(feature = "rust1", since = "1.0.0")]
593-
impl<'b, T> Deref for RefMut<'b, T> {
595+
impl<'b, T: ?Sized> Deref for RefMut<'b, T> {
594596
type Target = T;
595597

596598
#[inline]
@@ -600,7 +602,7 @@ impl<'b, T> Deref for RefMut<'b, T> {
600602
}
601603

602604
#[stable(feature = "rust1", since = "1.0.0")]
603-
impl<'b, T> DerefMut for RefMut<'b, T> {
605+
impl<'b, T: ?Sized> DerefMut for RefMut<'b, T> {
604606
#[inline]
605607
fn deref_mut<'a>(&'a mut self) -> &'a mut T {
606608
self._value
@@ -633,7 +635,7 @@ impl<'b, T> DerefMut for RefMut<'b, T> {
633635
/// recommended to access its fields directly, `get` should be used instead.
634636
#[lang="unsafe_cell"]
635637
#[stable(feature = "rust1", since = "1.0.0")]
636-
pub struct UnsafeCell<T> {
638+
pub struct UnsafeCell<T: ?Sized> {
637639
/// Wrapped value
638640
///
639641
/// This field should not be accessed directly, it is made public for static
@@ -642,7 +644,7 @@ pub struct UnsafeCell<T> {
642644
pub value: T,
643645
}
644646

645-
impl<T> !Sync for UnsafeCell<T> {}
647+
impl<T: ?Sized> !Sync for UnsafeCell<T> {}
646648

647649
impl<T> UnsafeCell<T> {
648650
/// Constructs a new instance of `UnsafeCell` which will wrap the specified
@@ -664,7 +666,12 @@ impl<T> UnsafeCell<T> {
664666
UnsafeCell { value: value }
665667
}
666668

667-
/// Gets a mutable pointer to the wrapped value.
669+
/// Unwraps the value.
670+
///
671+
/// # Unsafety
672+
///
673+
/// This function is unsafe because there is no guarantee that this or other threads are
674+
/// currently inspecting the inner value.
668675
///
669676
/// # Examples
670677
///
@@ -673,22 +680,15 @@ impl<T> UnsafeCell<T> {
673680
///
674681
/// let uc = UnsafeCell::new(5);
675682
///
676-
/// let five = uc.get();
683+
/// let five = unsafe { uc.into_inner() };
677684
/// ```
678685
#[inline]
679686
#[stable(feature = "rust1", since = "1.0.0")]
680-
pub fn get(&self) -> *mut T {
681-
// FIXME(#23542) Replace with type ascription.
682-
#![allow(trivial_casts)]
683-
&self.value as *const T as *mut T
684-
}
687+
pub unsafe fn into_inner(self) -> T { self.value }
688+
}
685689

686-
/// Unwraps the value.
687-
///
688-
/// # Unsafety
689-
///
690-
/// This function is unsafe because there is no guarantee that this or other threads are
691-
/// currently inspecting the inner value.
690+
impl<T: ?Sized> UnsafeCell<T> {
691+
/// Gets a mutable pointer to the wrapped value.
692692
///
693693
/// # Examples
694694
///
@@ -697,9 +697,14 @@ impl<T> UnsafeCell<T> {
697697
///
698698
/// let uc = UnsafeCell::new(5);
699699
///
700-
/// let five = unsafe { uc.into_inner() };
700+
/// let five = uc.get();
701701
/// ```
702702
#[inline]
703703
#[stable(feature = "rust1", since = "1.0.0")]
704-
pub unsafe fn into_inner(self) -> T { self.value }
704+
pub fn get(&self) -> *mut T {
705+
// FIXME(#23542) Replace with type ascription.
706+
#![allow(trivial_casts)]
707+
&self.value as *const T as *mut T
708+
}
709+
705710
}

src/libcore/fmt/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1062,7 +1062,7 @@ impl<T: Copy + Debug> Debug for Cell<T> {
10621062
}
10631063

10641064
#[stable(feature = "rust1", since = "1.0.0")]
1065-
impl<T: Debug> Debug for RefCell<T> {
1065+
impl<T: ?Sized + Debug> Debug for RefCell<T> {
10661066
fn fmt(&self, f: &mut Formatter) -> Result {
10671067
match self.borrow_state() {
10681068
BorrowState::Unused | BorrowState::Reading => {
@@ -1074,14 +1074,14 @@ impl<T: Debug> Debug for RefCell<T> {
10741074
}
10751075

10761076
#[stable(feature = "rust1", since = "1.0.0")]
1077-
impl<'b, T: Debug> Debug for Ref<'b, T> {
1077+
impl<'b, T: ?Sized + Debug> Debug for Ref<'b, T> {
10781078
fn fmt(&self, f: &mut Formatter) -> Result {
10791079
Debug::fmt(&**self, f)
10801080
}
10811081
}
10821082

10831083
#[stable(feature = "rust1", since = "1.0.0")]
1084-
impl<'b, T: Debug> Debug for RefMut<'b, T> {
1084+
impl<'b, T: ?Sized + Debug> Debug for RefMut<'b, T> {
10851085
fn fmt(&self, f: &mut Formatter) -> Result {
10861086
Debug::fmt(&*(self.deref()), f)
10871087
}

src/libcoretest/cell.rs

+24
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,27 @@ fn refcell_default() {
159159
let cell: RefCell<u64> = Default::default();
160160
assert_eq!(0, *cell.borrow());
161161
}
162+
163+
#[test]
164+
fn unsafe_cell_unsized() {
165+
let cell: &UnsafeCell<[i32]> = &UnsafeCell::new([1, 2, 3]);
166+
{
167+
let val: &mut [i32] = unsafe { &mut *cell.get() };
168+
val[0] = 4;
169+
val[2] = 5;
170+
}
171+
let comp: &mut [i32] = &mut [4, 5, 3];
172+
assert_eq!(unsafe { &mut *cell.get() }, comp);
173+
}
174+
175+
#[test]
176+
fn refcell_unsized() {
177+
let cell: &RefCell<[i32]> = &RefCell::new([1, 2, 3]);
178+
{
179+
let b = &mut *cell.borrow_mut();
180+
b[0] = 4;
181+
b[2] = 5;
182+
}
183+
let comp: &mut [i32] = &mut [4, 2, 5];
184+
assert_eq!(&*cell.borrow(), comp);
185+
}

src/libstd/sync/mutex.rs

+29-15
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ use sys_common::poison::{self, TryLockError, TryLockResult, LockResult};
112112
/// *guard += 1;
113113
/// ```
114114
#[stable(feature = "rust1", since = "1.0.0")]
115-
pub struct Mutex<T> {
115+
pub struct Mutex<T: ?Sized> {
116116
// Note that this static mutex is in a *box*, not inlined into the struct
117117
// itself. Once a native mutex has been used once, its address can never
118118
// change (it can't be moved). This mutex type can be safely moved at any
@@ -124,9 +124,9 @@ pub struct Mutex<T> {
124124

125125
// these are the only places where `T: Send` matters; all other
126126
// functionality works fine on a single thread.
127-
unsafe impl<T: Send> Send for Mutex<T> { }
127+
unsafe impl<T: ?Sized + Send> Send for Mutex<T> { }
128128

129-
unsafe impl<T: Send> Sync for Mutex<T> { }
129+
unsafe impl<T: ?Sized + Send> Sync for Mutex<T> { }
130130

131131
/// The static mutex type is provided to allow for static allocation of mutexes.
132132
///
@@ -164,15 +164,15 @@ pub struct StaticMutex {
164164
/// `Deref` and `DerefMut` implementations
165165
#[must_use]
166166
#[stable(feature = "rust1", since = "1.0.0")]
167-
pub struct MutexGuard<'a, T: 'a> {
167+
pub struct MutexGuard<'a, T: ?Sized + 'a> {
168168
// funny underscores due to how Deref/DerefMut currently work (they
169169
// disregard field privacy).
170170
__lock: &'a StaticMutex,
171171
__data: &'a UnsafeCell<T>,
172172
__poison: poison::Guard,
173173
}
174174

175-
impl<'a, T> !marker::Send for MutexGuard<'a, T> {}
175+
impl<'a, T: ?Sized> !marker::Send for MutexGuard<'a, T> {}
176176

177177
/// Static initialization of a mutex. This constant can be used to initialize
178178
/// other mutex constants.
@@ -192,7 +192,9 @@ impl<T> Mutex<T> {
192192
data: UnsafeCell::new(t),
193193
}
194194
}
195+
}
195196

197+
impl<T: ?Sized> Mutex<T> {
196198
/// Acquires a mutex, blocking the current task until it is able to do so.
197199
///
198200
/// This function will block the local task until it is available to acquire
@@ -245,7 +247,7 @@ impl<T> Mutex<T> {
245247
}
246248

247249
#[stable(feature = "rust1", since = "1.0.0")]
248-
impl<T> Drop for Mutex<T> {
250+
impl<T: ?Sized> Drop for Mutex<T> {
249251
fn drop(&mut self) {
250252
// This is actually safe b/c we know that there is no further usage of
251253
// 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> {
255257
}
256258

257259
#[stable(feature = "rust1", since = "1.0.0")]
258-
impl<T: fmt::Debug + 'static> fmt::Debug for Mutex<T> {
260+
impl<T: ?Sized + fmt::Debug + 'static> fmt::Debug for Mutex<T> {
259261
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
260262
match self.try_lock() {
261-
Ok(guard) => write!(f, "Mutex {{ data: {:?} }}", *guard),
263+
Ok(guard) => write!(f, "Mutex {{ data: {:?} }}", &*guard),
262264
Err(TryLockError::Poisoned(err)) => {
263-
write!(f, "Mutex {{ data: Poisoned({:?}) }}", **err.get_ref())
265+
write!(f, "Mutex {{ data: Poisoned({:?}) }}", &**err.get_ref())
264266
},
265267
Err(TryLockError::WouldBlock) => write!(f, "Mutex {{ <locked> }}")
266268
}
@@ -310,7 +312,7 @@ impl StaticMutex {
310312
}
311313
}
312314

313-
impl<'mutex, T> MutexGuard<'mutex, T> {
315+
impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> {
314316

315317
fn new(lock: &'mutex StaticMutex, data: &'mutex UnsafeCell<T>)
316318
-> LockResult<MutexGuard<'mutex, T>> {
@@ -325,22 +327,22 @@ impl<'mutex, T> MutexGuard<'mutex, T> {
325327
}
326328

327329
#[stable(feature = "rust1", since = "1.0.0")]
328-
impl<'mutex, T> Deref for MutexGuard<'mutex, T> {
330+
impl<'mutex, T: ?Sized> Deref for MutexGuard<'mutex, T> {
329331
type Target = T;
330332

331333
fn deref<'a>(&'a self) -> &'a T {
332334
unsafe { &*self.__data.get() }
333335
}
334336
}
335337
#[stable(feature = "rust1", since = "1.0.0")]
336-
impl<'mutex, T> DerefMut for MutexGuard<'mutex, T> {
338+
impl<'mutex, T: ?Sized> DerefMut for MutexGuard<'mutex, T> {
337339
fn deref_mut<'a>(&'a mut self) -> &'a mut T {
338340
unsafe { &mut *self.__data.get() }
339341
}
340342
}
341343

342344
#[stable(feature = "rust1", since = "1.0.0")]
343-
impl<'a, T> Drop for MutexGuard<'a, T> {
345+
impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> {
344346
#[inline]
345347
fn drop(&mut self) {
346348
unsafe {
@@ -350,11 +352,11 @@ impl<'a, T> Drop for MutexGuard<'a, T> {
350352
}
351353
}
352354

353-
pub fn guard_lock<'a, T>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex {
355+
pub fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex {
354356
&guard.__lock.lock
355357
}
356358

357-
pub fn guard_poison<'a, T>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag {
359+
pub fn guard_poison<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag {
358360
&guard.__lock.poison
359361
}
360362

@@ -528,4 +530,16 @@ mod tests {
528530
let lock = arc.lock().unwrap();
529531
assert_eq!(*lock, 2);
530532
}
533+
534+
#[test]
535+
fn test_mutex_unsized() {
536+
let mutex: &Mutex<[i32]> = &Mutex::new([1, 2, 3]);
537+
{
538+
let b = &mut *mutex.lock().unwrap();
539+
b[0] = 4;
540+
b[2] = 5;
541+
}
542+
let comp: &[i32] = &[4, 2, 5];
543+
assert_eq!(&*mutex.lock().unwrap(), comp);
544+
}
531545
}

0 commit comments

Comments
 (0)