Skip to content

Commit 00204c2

Browse files
committed
Auto merge of #50494 - F001:as_cell, r=alexcrichton
Implement rfc 1789: Conversions from `&mut T` to `&Cell<T>` I'm surprised that RFC 1789 has not been implemented for several months. Tracking issue: #43038 Please note: when I was writing tests for `&Cell<[i32]>`, I found it is not easy to get the length of the contained slice. So I designed a `get_with` method which might be useful for similar cases. This method is not designed in the RFC, and it certainly needs to be reviewed by core team. I think it has some connections with `Cell::update` #50186 , which is also in design phase.
2 parents 8dbbd81 + 489101c commit 00204c2

File tree

2 files changed

+111
-43
lines changed

2 files changed

+111
-43
lines changed

src/libcore/cell.rs

+90-43
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ use ptr;
236236
/// See the [module-level documentation](index.html) for more.
237237
#[stable(feature = "rust1", since = "1.0.0")]
238238
#[repr(transparent)]
239-
pub struct Cell<T> {
239+
pub struct Cell<T: ?Sized> {
240240
value: UnsafeCell<T>,
241241
}
242242

@@ -287,10 +287,10 @@ impl<T:Copy> Cell<T> {
287287
}
288288

289289
#[stable(feature = "rust1", since = "1.0.0")]
290-
unsafe impl<T> Send for Cell<T> where T: Send {}
290+
unsafe impl<T: ?Sized> Send for Cell<T> where T: Send {}
291291

292292
#[stable(feature = "rust1", since = "1.0.0")]
293-
impl<T> !Sync for Cell<T> {}
293+
impl<T: ?Sized> !Sync for Cell<T> {}
294294

295295
#[stable(feature = "rust1", since = "1.0.0")]
296296
impl<T:Copy> Clone for Cell<T> {
@@ -381,46 +381,6 @@ impl<T> Cell<T> {
381381
}
382382
}
383383

384-
/// Returns a raw pointer to the underlying data in this cell.
385-
///
386-
/// # Examples
387-
///
388-
/// ```
389-
/// use std::cell::Cell;
390-
///
391-
/// let c = Cell::new(5);
392-
///
393-
/// let ptr = c.as_ptr();
394-
/// ```
395-
#[inline]
396-
#[stable(feature = "cell_as_ptr", since = "1.12.0")]
397-
pub fn as_ptr(&self) -> *mut T {
398-
self.value.get()
399-
}
400-
401-
/// Returns a mutable reference to the underlying data.
402-
///
403-
/// This call borrows `Cell` mutably (at compile-time) which guarantees
404-
/// that we possess the only reference.
405-
///
406-
/// # Examples
407-
///
408-
/// ```
409-
/// use std::cell::Cell;
410-
///
411-
/// let mut c = Cell::new(5);
412-
/// *c.get_mut() += 1;
413-
///
414-
/// assert_eq!(c.get(), 6);
415-
/// ```
416-
#[inline]
417-
#[stable(feature = "cell_get_mut", since = "1.11.0")]
418-
pub fn get_mut(&mut self) -> &mut T {
419-
unsafe {
420-
&mut *self.value.get()
421-
}
422-
}
423-
424384
/// Sets the contained value.
425385
///
426386
/// # Examples
@@ -499,6 +459,70 @@ impl<T> Cell<T> {
499459
}
500460
}
501461

462+
impl<T: ?Sized> Cell<T> {
463+
/// Returns a raw pointer to the underlying data in this cell.
464+
///
465+
/// # Examples
466+
///
467+
/// ```
468+
/// use std::cell::Cell;
469+
///
470+
/// let c = Cell::new(5);
471+
///
472+
/// let ptr = c.as_ptr();
473+
/// ```
474+
#[inline]
475+
#[stable(feature = "cell_as_ptr", since = "1.12.0")]
476+
pub fn as_ptr(&self) -> *mut T {
477+
self.value.get()
478+
}
479+
480+
/// Returns a mutable reference to the underlying data.
481+
///
482+
/// This call borrows `Cell` mutably (at compile-time) which guarantees
483+
/// that we possess the only reference.
484+
///
485+
/// # Examples
486+
///
487+
/// ```
488+
/// use std::cell::Cell;
489+
///
490+
/// let mut c = Cell::new(5);
491+
/// *c.get_mut() += 1;
492+
///
493+
/// assert_eq!(c.get(), 6);
494+
/// ```
495+
#[inline]
496+
#[stable(feature = "cell_get_mut", since = "1.11.0")]
497+
pub fn get_mut(&mut self) -> &mut T {
498+
unsafe {
499+
&mut *self.value.get()
500+
}
501+
}
502+
503+
/// Returns a `&Cell<T>` from a `&mut T`
504+
///
505+
/// # Examples
506+
///
507+
/// ```
508+
/// #![feature(as_cell)]
509+
/// use std::cell::Cell;
510+
///
511+
/// let slice: &mut [i32] = &mut [1, 2, 3];
512+
/// let cell_slice: &Cell<[i32]> = Cell::from_mut(slice);
513+
/// let slice_cell: &[Cell<i32>] = cell_slice.as_slice_of_cells();
514+
///
515+
/// assert_eq!(slice_cell.len(), 3);
516+
/// ```
517+
#[inline]
518+
#[unstable(feature = "as_cell", issue="43038")]
519+
pub fn from_mut(t: &mut T) -> &Cell<T> {
520+
unsafe {
521+
&*(t as *mut T as *const Cell<T>)
522+
}
523+
}
524+
}
525+
502526
impl<T: Default> Cell<T> {
503527
/// Takes the value of the cell, leaving `Default::default()` in its place.
504528
///
@@ -522,6 +546,29 @@ impl<T: Default> Cell<T> {
522546
#[unstable(feature = "coerce_unsized", issue = "27732")]
523547
impl<T: CoerceUnsized<U>, U> CoerceUnsized<Cell<U>> for Cell<T> {}
524548

549+
impl<T> Cell<[T]> {
550+
/// Returns a `&[Cell<T>]` from a `&Cell<[T]>`
551+
///
552+
/// # Examples
553+
///
554+
/// ```
555+
/// #![feature(as_cell)]
556+
/// use std::cell::Cell;
557+
///
558+
/// let slice: &mut [i32] = &mut [1, 2, 3];
559+
/// let cell_slice: &Cell<[i32]> = Cell::from_mut(slice);
560+
/// let slice_cell: &[Cell<i32>] = cell_slice.as_slice_of_cells();
561+
///
562+
/// assert_eq!(slice_cell.len(), 3);
563+
/// ```
564+
#[unstable(feature = "as_cell", issue="43038")]
565+
pub fn as_slice_of_cells(&self) -> &[Cell<T>] {
566+
unsafe {
567+
&*(self as *const Cell<[T]> as *const [Cell<T>])
568+
}
569+
}
570+
}
571+
525572
/// A mutable memory location with dynamically checked borrow rules
526573
///
527574
/// See the [module-level documentation](index.html) for more.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(as_cell)]
12+
13+
use std::cell::Cell;
14+
15+
fn main() {
16+
let slice: &mut [i32] = &mut [1, 2, 3];
17+
let cell_slice: &Cell<[i32]> = Cell::from_mut(slice);
18+
let slice_cell: &[Cell<i32>] = cell_slice.as_slice_of_cells();
19+
20+
assert_eq!(slice_cell.len(), 3);
21+
}

0 commit comments

Comments
 (0)