From 9928baa786f645a22072fd2fb4b68173eced61f9 Mon Sep 17 00:00:00 2001 From: F001 Date: Mon, 7 May 2018 15:24:45 +0800 Subject: [PATCH 01/10] implement rfc 1789 --- src/libcore/cell.rs | 147 ++++++++++++------ .../run-pass/rfc-1789-as-cell/from-mut.rs | 22 +++ 2 files changed, 125 insertions(+), 44 deletions(-) create mode 100644 src/test/run-pass/rfc-1789-as-cell/from-mut.rs diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 2292617f51e6b..3536588f9dfaa 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -200,8 +200,9 @@ use cmp::Ordering; use fmt::{self, Debug, Display}; use marker::Unsize; use mem; -use ops::{Deref, DerefMut, CoerceUnsized}; +use ops::{Deref, DerefMut, CoerceUnsized, Index}; use ptr; +use slice::SliceIndex; /// A mutable memory location. /// @@ -236,7 +237,7 @@ use ptr; /// See the [module-level documentation](index.html) for more. #[stable(feature = "rust1", since = "1.0.0")] #[repr(transparent)] -pub struct Cell { +pub struct Cell { value: UnsafeCell, } @@ -287,10 +288,10 @@ impl Cell { } #[stable(feature = "rust1", since = "1.0.0")] -unsafe impl Send for Cell where T: Send {} +unsafe impl Send for Cell where T: Send {} #[stable(feature = "rust1", since = "1.0.0")] -impl !Sync for Cell {} +impl !Sync for Cell {} #[stable(feature = "rust1", since = "1.0.0")] impl Clone for Cell { @@ -381,46 +382,6 @@ impl Cell { } } - /// Returns a raw pointer to the underlying data in this cell. - /// - /// # Examples - /// - /// ``` - /// use std::cell::Cell; - /// - /// let c = Cell::new(5); - /// - /// let ptr = c.as_ptr(); - /// ``` - #[inline] - #[stable(feature = "cell_as_ptr", since = "1.12.0")] - pub fn as_ptr(&self) -> *mut T { - self.value.get() - } - - /// Returns a mutable reference to the underlying data. - /// - /// This call borrows `Cell` mutably (at compile-time) which guarantees - /// that we possess the only reference. - /// - /// # Examples - /// - /// ``` - /// use std::cell::Cell; - /// - /// let mut c = Cell::new(5); - /// *c.get_mut() += 1; - /// - /// assert_eq!(c.get(), 6); - /// ``` - #[inline] - #[stable(feature = "cell_get_mut", since = "1.11.0")] - pub fn get_mut(&mut self) -> &mut T { - unsafe { - &mut *self.value.get() - } - } - /// Sets the contained value. /// /// # Examples @@ -499,6 +460,90 @@ impl Cell { } } +impl Cell { + /// Returns a raw pointer to the underlying data in this cell. + /// + /// # Examples + /// + /// ``` + /// use std::cell::Cell; + /// + /// let c = Cell::new(5); + /// + /// let ptr = c.as_ptr(); + /// ``` + #[inline] + #[stable(feature = "cell_as_ptr", since = "1.12.0")] + pub fn as_ptr(&self) -> *mut T { + self.value.get() + } + + /// Returns a mutable reference to the underlying data. + /// + /// This call borrows `Cell` mutably (at compile-time) which guarantees + /// that we possess the only reference. + /// + /// # Examples + /// + /// ``` + /// use std::cell::Cell; + /// + /// let mut c = Cell::new(5); + /// *c.get_mut() += 1; + /// + /// assert_eq!(c.get(), 6); + /// ``` + #[inline] + #[stable(feature = "cell_get_mut", since = "1.11.0")] + pub fn get_mut(&mut self) -> &mut T { + unsafe { + &mut *self.value.get() + } + } + + /// Returns a `&Cell` from a `&mut T` + /// + /// # Examples + /// + /// ``` + /// #![feature(as_cell)] + /// use std::cell::Cell; + /// let slice: &mut [i32] = &mut [1,2,3]; + /// let cell_slice: &Cell<[i32]> = Cell::from_mut(slice); + /// + /// assert_eq!(cell_slice.get_with(|v|v.len()), 3) + /// ``` + #[inline] + #[unstable(feature = "as_cell", issue="43038")] + pub fn from_mut<'a>(t: &'a mut T) -> &'a Cell { + unsafe { + &*(t as *mut T as *const Cell) + } + } + + /// Returns a value by applying a function on contained value + /// + /// # Examples + /// + /// ``` + /// #![feature(as_cell)] + /// use std::cell::Cell; + /// let c : Cell> = Cell::new(vec![1,2,3]); + /// let sum : i32 = c.get_with(|v|v.iter().sum()); + /// assert_eq!(sum, 6_i32); + /// ``` + #[inline] + #[unstable(feature = "as_cell", issue="43038")] + pub fn get_with(&self, f: F) -> U + where + F: Fn(&T) -> U, U: 'static + { + unsafe { + f(&*self.value.get()) + } + } +} + impl Cell { /// Takes the value of the cell, leaving `Default::default()` in its place. /// @@ -522,6 +567,20 @@ impl Cell { #[unstable(feature = "coerce_unsized", issue = "27732")] impl, U> CoerceUnsized> for Cell {} +#[unstable(feature = "as_cell", issue="43038")] +impl Index for Cell<[T]> +where + I: SliceIndex<[Cell]> +{ + type Output = I::Output; + + fn index(&self, index: I) -> &Self::Output { + unsafe { + Index::index(&*(self as *const Cell<[T]> as *const [Cell]), index) + } + } +} + /// A mutable memory location with dynamically checked borrow rules /// /// See the [module-level documentation](index.html) for more. diff --git a/src/test/run-pass/rfc-1789-as-cell/from-mut.rs b/src/test/run-pass/rfc-1789-as-cell/from-mut.rs new file mode 100644 index 0000000000000..33257124f57ae --- /dev/null +++ b/src/test/run-pass/rfc-1789-as-cell/from-mut.rs @@ -0,0 +1,22 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(as_cell)] + +use std::cell::Cell; + +fn main() { + let slice: &mut [i32] = &mut [1,2,3]; + let cell_slice: &Cell<[i32]> = Cell::from_mut(slice); + assert_eq!(cell_slice.get_with(|v|v.len()), 3); + + let sub_slice : &[Cell] = &cell_slice[1..]; + assert_eq!(sub_slice.len(), 2); +} From 20b50f591f6ba43958c9d51cc43f1e7b421994bb Mon Sep 17 00:00:00 2001 From: F001 Date: Tue, 8 May 2018 09:00:05 +0800 Subject: [PATCH 02/10] add repr transparent --- src/libcore/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index bbe6ae8619fec..368c9208d8d88 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -112,6 +112,7 @@ #![feature(unwind_attributes)] #![feature(doc_alias)] #![feature(inclusive_range_methods)] +#![feature(repr_transparent)] #![feature(mmx_target_feature)] #![feature(tbm_target_feature)] #![feature(sse4a_target_feature)] From 4bf8b57950ff6e1a447156f19461eeed480499e8 Mon Sep 17 00:00:00 2001 From: F001 Date: Sat, 26 May 2018 19:55:40 +0800 Subject: [PATCH 03/10] remove "get_with" method --- src/libcore/cell.rs | 26 ++----------------- .../run-pass/rfc-1789-as-cell/from-mut.rs | 2 -- 2 files changed, 2 insertions(+), 26 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 3536588f9dfaa..78ae134617587 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -510,8 +510,8 @@ impl Cell { /// use std::cell::Cell; /// let slice: &mut [i32] = &mut [1,2,3]; /// let cell_slice: &Cell<[i32]> = Cell::from_mut(slice); - /// - /// assert_eq!(cell_slice.get_with(|v|v.len()), 3) + /// let slice_cell : &[Cell] = &cell_slice[..]; + /// assert_eq!(slice_cell.len(), 3) /// ``` #[inline] #[unstable(feature = "as_cell", issue="43038")] @@ -520,28 +520,6 @@ impl Cell { &*(t as *mut T as *const Cell) } } - - /// Returns a value by applying a function on contained value - /// - /// # Examples - /// - /// ``` - /// #![feature(as_cell)] - /// use std::cell::Cell; - /// let c : Cell> = Cell::new(vec![1,2,3]); - /// let sum : i32 = c.get_with(|v|v.iter().sum()); - /// assert_eq!(sum, 6_i32); - /// ``` - #[inline] - #[unstable(feature = "as_cell", issue="43038")] - pub fn get_with(&self, f: F) -> U - where - F: Fn(&T) -> U, U: 'static - { - unsafe { - f(&*self.value.get()) - } - } } impl Cell { diff --git a/src/test/run-pass/rfc-1789-as-cell/from-mut.rs b/src/test/run-pass/rfc-1789-as-cell/from-mut.rs index 33257124f57ae..28b6d8213f714 100644 --- a/src/test/run-pass/rfc-1789-as-cell/from-mut.rs +++ b/src/test/run-pass/rfc-1789-as-cell/from-mut.rs @@ -15,8 +15,6 @@ use std::cell::Cell; fn main() { let slice: &mut [i32] = &mut [1,2,3]; let cell_slice: &Cell<[i32]> = Cell::from_mut(slice); - assert_eq!(cell_slice.get_with(|v|v.len()), 3); - let sub_slice : &[Cell] = &cell_slice[1..]; assert_eq!(sub_slice.len(), 2); } From 4d99957ce30b6c5021d14c2812b12e817ec60c59 Mon Sep 17 00:00:00 2001 From: F001 Date: Sun, 27 May 2018 20:07:10 +0800 Subject: [PATCH 04/10] use lifetime elision for consistency --- src/libcore/cell.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 78ae134617587..97fee5d06f45d 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -515,7 +515,7 @@ impl Cell { /// ``` #[inline] #[unstable(feature = "as_cell", issue="43038")] - pub fn from_mut<'a>(t: &'a mut T) -> &'a Cell { + pub fn from_mut(t: &mut T) -> &Cell { unsafe { &*(t as *mut T as *const Cell) } From bdf86300b4170abef1399bb9b7bc63bac52a0092 Mon Sep 17 00:00:00 2001 From: F001 Date: Mon, 28 May 2018 07:52:39 +0800 Subject: [PATCH 05/10] impl `Deref` instead of `Index` --- src/libcore/cell.rs | 18 ++++++++---------- src/test/run-pass/rfc-1789-as-cell/from-mut.rs | 1 + 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 97fee5d06f45d..85ef417ea15c2 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -200,9 +200,8 @@ use cmp::Ordering; use fmt::{self, Debug, Display}; use marker::Unsize; use mem; -use ops::{Deref, DerefMut, CoerceUnsized, Index}; +use ops::{Deref, DerefMut, CoerceUnsized}; use ptr; -use slice::SliceIndex; /// A mutable memory location. /// @@ -510,8 +509,9 @@ impl Cell { /// use std::cell::Cell; /// let slice: &mut [i32] = &mut [1,2,3]; /// let cell_slice: &Cell<[i32]> = Cell::from_mut(slice); + /// assert_eq!(cell_slice.len(), 3); /// let slice_cell : &[Cell] = &cell_slice[..]; - /// assert_eq!(slice_cell.len(), 3) + /// assert_eq!(slice_cell.len(), 3); /// ``` #[inline] #[unstable(feature = "as_cell", issue="43038")] @@ -546,15 +546,13 @@ impl Cell { impl, U> CoerceUnsized> for Cell {} #[unstable(feature = "as_cell", issue="43038")] -impl Index for Cell<[T]> -where - I: SliceIndex<[Cell]> -{ - type Output = I::Output; +impl Deref for Cell<[T]> { + type Target = [Cell]; - fn index(&self, index: I) -> &Self::Output { + #[inline] + fn deref(&self) -> &[Cell] { unsafe { - Index::index(&*(self as *const Cell<[T]> as *const [Cell]), index) + &*(self as *const Cell<[T]> as *const [Cell]) } } } diff --git a/src/test/run-pass/rfc-1789-as-cell/from-mut.rs b/src/test/run-pass/rfc-1789-as-cell/from-mut.rs index 28b6d8213f714..9989690bc7907 100644 --- a/src/test/run-pass/rfc-1789-as-cell/from-mut.rs +++ b/src/test/run-pass/rfc-1789-as-cell/from-mut.rs @@ -15,6 +15,7 @@ use std::cell::Cell; fn main() { let slice: &mut [i32] = &mut [1,2,3]; let cell_slice: &Cell<[i32]> = Cell::from_mut(slice); + assert_eq!(cell_slice.len(), 3); let sub_slice : &[Cell] = &cell_slice[1..]; assert_eq!(sub_slice.len(), 2); } From b1344abc58f0bd2eb6a8c9e664f8318864f640fe Mon Sep 17 00:00:00 2001 From: F001 Date: Mon, 28 May 2018 14:35:12 +0800 Subject: [PATCH 06/10] code style fixes --- src/libcore/cell.rs | 6 ++++-- src/test/run-pass/rfc-1789-as-cell/from-mut.rs | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 85ef417ea15c2..a85eee8545095 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -507,10 +507,12 @@ impl Cell { /// ``` /// #![feature(as_cell)] /// use std::cell::Cell; - /// let slice: &mut [i32] = &mut [1,2,3]; + /// + /// let slice: &mut [i32] = &mut [1, 2, 3]; /// let cell_slice: &Cell<[i32]> = Cell::from_mut(slice); /// assert_eq!(cell_slice.len(), 3); - /// let slice_cell : &[Cell] = &cell_slice[..]; + /// + /// let slice_cell: &[Cell] = &cell_slice[..]; /// assert_eq!(slice_cell.len(), 3); /// ``` #[inline] diff --git a/src/test/run-pass/rfc-1789-as-cell/from-mut.rs b/src/test/run-pass/rfc-1789-as-cell/from-mut.rs index 9989690bc7907..8c7317b0e9a59 100644 --- a/src/test/run-pass/rfc-1789-as-cell/from-mut.rs +++ b/src/test/run-pass/rfc-1789-as-cell/from-mut.rs @@ -13,9 +13,10 @@ use std::cell::Cell; fn main() { - let slice: &mut [i32] = &mut [1,2,3]; + let slice: &mut [i32] = &mut [1, 2, 3]; let cell_slice: &Cell<[i32]> = Cell::from_mut(slice); assert_eq!(cell_slice.len(), 3); - let sub_slice : &[Cell] = &cell_slice[1..]; + + let sub_slice: &[Cell] = &cell_slice[1..]; assert_eq!(sub_slice.len(), 2); } From 3eee486e270347f39e41f4429cdb253b40219b89 Mon Sep 17 00:00:00 2001 From: F001 Date: Thu, 7 Jun 2018 17:47:55 +0800 Subject: [PATCH 07/10] impl DerefMut for Cell<[T]> --- src/libcore/cell.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index a85eee8545095..7e2ece0f02c1c 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -559,6 +559,16 @@ impl Deref for Cell<[T]> { } } +#[unstable(feature = "as_cell", issue="43038")] +impl DerefMut for Cell<[T]> { + #[inline] + fn deref_mut(&mut self) -> &mut [Cell] { + unsafe { + &mut *(self as *mut Cell<[T]> as *mut [Cell]) + } + } +} + /// A mutable memory location with dynamically checked borrow rules /// /// See the [module-level documentation](index.html) for more. From 7e1b983579ec582dfbe409342756252f6b080918 Mon Sep 17 00:00:00 2001 From: F001 Date: Fri, 6 Jul 2018 17:43:30 +0800 Subject: [PATCH 08/10] remove useless feature(repr_transparent) --- src/libcore/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 368c9208d8d88..bbe6ae8619fec 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -112,7 +112,6 @@ #![feature(unwind_attributes)] #![feature(doc_alias)] #![feature(inclusive_range_methods)] -#![feature(repr_transparent)] #![feature(mmx_target_feature)] #![feature(tbm_target_feature)] #![feature(sse4a_target_feature)] From 8812c6bae92d1a8e3a255d3eacd40cd9b65bb7f6 Mon Sep 17 00:00:00 2001 From: F001 Date: Tue, 17 Jul 2018 11:30:17 +0800 Subject: [PATCH 09/10] revert Deref --- src/libcore/cell.rs | 26 +++++++------------ .../run-pass/rfc-1789-as-cell/from-mut.rs | 2 +- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 7e2ece0f02c1c..8a0f499b598a5 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -200,8 +200,9 @@ use cmp::Ordering; use fmt::{self, Debug, Display}; use marker::Unsize; use mem; -use ops::{Deref, DerefMut, CoerceUnsized}; +use ops::{Deref, DerefMut, CoerceUnsized, Index}; use ptr; +use slice::SliceIndex; /// A mutable memory location. /// @@ -510,7 +511,7 @@ impl Cell { /// /// let slice: &mut [i32] = &mut [1, 2, 3]; /// let cell_slice: &Cell<[i32]> = Cell::from_mut(slice); - /// assert_eq!(cell_slice.len(), 3); + /// assert_eq!(cell_slice[..].len(), 3); /// /// let slice_cell: &[Cell] = &cell_slice[..]; /// assert_eq!(slice_cell.len(), 3); @@ -548,23 +549,14 @@ impl Cell { impl, U> CoerceUnsized> for Cell {} #[unstable(feature = "as_cell", issue="43038")] -impl Deref for Cell<[T]> { - type Target = [Cell]; +impl Index for Cell<[T]> + where I: SliceIndex<[Cell]> +{ + type Output = I::Output; - #[inline] - fn deref(&self) -> &[Cell] { - unsafe { - &*(self as *const Cell<[T]> as *const [Cell]) - } - } -} - -#[unstable(feature = "as_cell", issue="43038")] -impl DerefMut for Cell<[T]> { - #[inline] - fn deref_mut(&mut self) -> &mut [Cell] { + fn index(&self, index: I) -> &Self::Output { unsafe { - &mut *(self as *mut Cell<[T]> as *mut [Cell]) + Index::index(&*(self as *const Cell<[T]> as *const [Cell]), index) } } } diff --git a/src/test/run-pass/rfc-1789-as-cell/from-mut.rs b/src/test/run-pass/rfc-1789-as-cell/from-mut.rs index 8c7317b0e9a59..bd00f305cc49a 100644 --- a/src/test/run-pass/rfc-1789-as-cell/from-mut.rs +++ b/src/test/run-pass/rfc-1789-as-cell/from-mut.rs @@ -15,7 +15,7 @@ use std::cell::Cell; fn main() { let slice: &mut [i32] = &mut [1, 2, 3]; let cell_slice: &Cell<[i32]> = Cell::from_mut(slice); - assert_eq!(cell_slice.len(), 3); + assert_eq!(cell_slice[..].len(), 3); let sub_slice: &[Cell] = &cell_slice[1..]; assert_eq!(sub_slice.len(), 2); From 489101cc45d21d3909a728d16864e26599c12bee Mon Sep 17 00:00:00 2001 From: F001 Date: Mon, 23 Jul 2018 19:20:50 +0800 Subject: [PATCH 10/10] use inherent method instead --- src/libcore/cell.rs | 32 ++++++++++++------- .../run-pass/rfc-1789-as-cell/from-mut.rs | 5 ++- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 8a0f499b598a5..b6087628ea6a4 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -200,9 +200,8 @@ use cmp::Ordering; use fmt::{self, Debug, Display}; use marker::Unsize; use mem; -use ops::{Deref, DerefMut, CoerceUnsized, Index}; +use ops::{Deref, DerefMut, CoerceUnsized}; use ptr; -use slice::SliceIndex; /// A mutable memory location. /// @@ -511,9 +510,8 @@ impl Cell { /// /// let slice: &mut [i32] = &mut [1, 2, 3]; /// let cell_slice: &Cell<[i32]> = Cell::from_mut(slice); - /// assert_eq!(cell_slice[..].len(), 3); + /// let slice_cell: &[Cell] = cell_slice.as_slice_of_cells(); /// - /// let slice_cell: &[Cell] = &cell_slice[..]; /// assert_eq!(slice_cell.len(), 3); /// ``` #[inline] @@ -548,15 +546,25 @@ impl Cell { #[unstable(feature = "coerce_unsized", issue = "27732")] impl, U> CoerceUnsized> for Cell {} -#[unstable(feature = "as_cell", issue="43038")] -impl Index for Cell<[T]> - where I: SliceIndex<[Cell]> -{ - type Output = I::Output; - - fn index(&self, index: I) -> &Self::Output { +impl Cell<[T]> { + /// Returns a `&[Cell]` from a `&Cell<[T]>` + /// + /// # Examples + /// + /// ``` + /// #![feature(as_cell)] + /// use std::cell::Cell; + /// + /// let slice: &mut [i32] = &mut [1, 2, 3]; + /// let cell_slice: &Cell<[i32]> = Cell::from_mut(slice); + /// let slice_cell: &[Cell] = cell_slice.as_slice_of_cells(); + /// + /// assert_eq!(slice_cell.len(), 3); + /// ``` + #[unstable(feature = "as_cell", issue="43038")] + pub fn as_slice_of_cells(&self) -> &[Cell] { unsafe { - Index::index(&*(self as *const Cell<[T]> as *const [Cell]), index) + &*(self as *const Cell<[T]> as *const [Cell]) } } } diff --git a/src/test/run-pass/rfc-1789-as-cell/from-mut.rs b/src/test/run-pass/rfc-1789-as-cell/from-mut.rs index bd00f305cc49a..88f7fbc86df6e 100644 --- a/src/test/run-pass/rfc-1789-as-cell/from-mut.rs +++ b/src/test/run-pass/rfc-1789-as-cell/from-mut.rs @@ -15,8 +15,7 @@ use std::cell::Cell; fn main() { let slice: &mut [i32] = &mut [1, 2, 3]; let cell_slice: &Cell<[i32]> = Cell::from_mut(slice); - assert_eq!(cell_slice[..].len(), 3); + let slice_cell: &[Cell] = cell_slice.as_slice_of_cells(); - let sub_slice: &[Cell] = &cell_slice[1..]; - assert_eq!(sub_slice.len(), 2); + assert_eq!(slice_cell.len(), 3); }