Skip to content

Commit 5069717

Browse files
authored
Doc update (#8)
* Doc update and fixes * Misc doc fixes and changes
1 parent d7b34d9 commit 5069717

File tree

7 files changed

+45
-61
lines changed

7 files changed

+45
-61
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "clone_cell"
3-
version = "0.3.0"
3+
version = "0.3.1"
44
edition = "2018"
55
authors = ["Vektorlynk"]
66
license = "MIT OR Apache-2.0"

README.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# clone_cell
22

3-
clone_cell provides a `Cell` implementation that works with types whose `Clone` implementations are
3+
clone_cell provides a `Cell` implementation that works with types whose `clone` methods are
44
guaranteed not to mutate the `Cell` content through the `&self` reference. This is enforced with the
55
provided `PureClone` trait, which is a subtrait of `Clone` (and a logical supertrait of `Copy`). It
6-
is only implemented for types with compliant `clone` methods.
6+
is only implemented for types with a compliant `clone` method.
77

88
## Overview
99

@@ -82,12 +82,14 @@ See the [`clone`] module documentation for more information.
8282
- Similar to `std::cell::Cell`, this `Cell` is `!Sync`.
8383
- Since a new trait `PureClone` is used, there is no out-of-the-box support for types from third-party crates.
8484

85-
## Soundness
85+
## Safety
8686

87-
I believe this is sound, because `PureClone` is unsafe to implement. This trait is implemented for:
87+
This is safe to use, because `PureClone` is an `unsafe` trait, and all `PureClone` implementations
88+
are checked. This trait is implemented for:
8889
- `Copy` types;
8990
- Types that perform a shallow clone such as `Rc` and `Weak`; and
90-
- Types whose `clone` methods are otherwise known to be safe, such as compound types that only contain `PureClone` types.
91+
- Types whose `clone` methods are otherwise known to be safe, such as compound types that only
92+
contain `PureClone` types.
9193

9294
See the [documentation] for more information. Please let me know if you find any soundness issues!
9395

src/cell.rs

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,14 @@
22
//!
33
//! # When to use `Cell`
44
//!
5-
//! [`Cell::get`] only requires `T` to be [`PureClone`]. This is useful when working
6-
//! with with shared `struct`s whose fields are of types `Rc<T>`, `Weak<T>`,
7-
//! `Option<T: PureClone>`, etc.
5+
//! [`Cell::get`] only requires `T` to be [`PureClone`](crate::clone::PureClone). This is useful
6+
//! when working with with shared `struct`s whose fields are of types `Rc<T>`, `Weak<T>`, `Option<T:
7+
//! PureClone>`, etc.
88
//!
9-
//! Note that just because there can be any number of readers and writers to a
10-
//! [`Cell`] does not mean it is always a good pattern. In most cases, it may not
11-
//! make sense to have more than one writer at a time. But the user can easily build
12-
//! zero-cost abstractions on top of a `Cell` to enforce this. For example, this may be
13-
//! useful when implementing the observer pattern.
14-
//!
15-
//! [`PureClone`]: crate::clone::PureClone
9+
//! Note that just because there can be any number of readers and writers to a [`Cell`] does not
10+
//! mean it is always a good pattern. In most cases, it may not make sense to have more than one
11+
//! writer at a time. But the user can easily build zero-cost abstractions on top of a `Cell` to
12+
//! enforce this. For example, this may be useful when implementing the observer pattern.
1613
1714
use core::{
1815
cell::UnsafeCell,
@@ -24,11 +21,8 @@ use core::{
2421

2522
use crate::clone::PureClone;
2623

27-
/// A mutable memory location with a [`get`] method that works with [`PureClone`]
28-
/// types.
29-
///
30-
/// [`PureClone`]: crate::clone::PureClone
31-
/// [`get`]: Cell::get
24+
/// A mutable memory location with a [`get`](Cell::get) method that works with
25+
/// [`PureClone`](crate::clone::PureClone) types.
3226
///
3327
/// # Examples
3428
///
@@ -86,8 +80,8 @@ impl<T> Cell<T> {
8680
drop(old);
8781
}
8882

89-
/// Swaps the values of two `Cell`s. Unlike `std::mem::swap`, this does not
90-
/// require a `&mut` reference.
83+
/// Swaps the values of two `Cell`s. Unlike `std::mem::swap`, this does not require a `&mut`
84+
/// reference.
9185
///
9286
/// # Examples
9387
///
@@ -213,8 +207,8 @@ where
213207
self.value.get()
214208
}
215209

216-
/// Returns a mutable reference to the underlying data. This method requires
217-
/// `&mut self`, ensuring the caller has the only reference to it.
210+
/// Returns a mutable reference to the underlying data. This method requires `&mut self`,
211+
/// ensuring the caller has the only reference to it.
218212
///
219213
/// # Examples
220214
///

src/clone.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
//! Provides the [`PureClone`] trait, which is a restrictive form of `Clone` that does not mutate
2-
//! the containing [`Cell`].
2+
//! the containing [`Cell`](crate::cell::Cell).
33
//!
4-
//! Conceptually, the relationship between [`Copy`], [`Clone`], and `PureClone` can be
5-
//! thought of as follows:
4+
//! Conceptually, the relationship between [`Copy`], [`Clone`], and `PureClone` can be thought of as
5+
//! follows:
66
//! ```text
77
//! Copy: PureClone: Clone
88
//! ```
99
//!
10-
//! `PureClone` is `unsafe` because the `clone` implementation must not mutate the
11-
//! content of `Cell` through the `&self` reference it gets with interior
12-
//! mutability. See this [Stack Overflow answer] and this [Rust forum thread] for
13-
//! details.
10+
//! `PureClone` is `unsafe` because the `clone` implementation must not mutate the content of `Cell`
11+
//! through the `&self` reference it gets with interior mutability. See this [Stack Overflow answer]
12+
//! and this [Rust forum thread] for details.
1413
//!
1514
//! When this [`crate`] is built with the `"derive"` feature, the [`PureClone`](derive@PureClone)
1615
//! proc macro can be used to derive `PureClone` for user types.
1716
//!
18-
//! [`Cell`]: crate::cell::Cell
1917
//! [Rust forum thread]:
2018
//! https://users.rust-lang.org/t/why-does-cell-require-copy-instead-of-clone/5769/3
2119
//! [Stack Overflow answer]:
@@ -61,9 +59,7 @@ pub use crate::derive::PureClone;
6159

6260
/// The `PureClone` trait, which is a subtrait of [`Clone`].
6361
///
64-
/// See the [module] documentation for more information.
65-
///
66-
/// [module]: self
62+
/// See the [module](self) documentation for more information.
6763
pub unsafe trait PureClone: Clone {
6864
/// The `pure_clone` method.
6965
#[inline]

src/lib.rs

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,22 @@
1-
//! This crate provides a [`Cell`](cell::Cell) implementation that works with types whose `Clone`
2-
//! implementations are guaranteed not to mutate the `Cell` content using the `&self`
3-
//! reference. This is enforced with the provided [`PureClone`] trait, which is a subtrait of
4-
//! [`Clone`] (and a logical supertrait of [`Copy`]). It is only implemented for types with
5-
//! compliant `clone` methods.
1+
//! This crate provides a [`Cell`](cell::Cell) implementation that works with types whose `clone`
2+
//! methods are guaranteed not to mutate the `Cell` content using the `&self` reference. This is
3+
//! enforced with the provided [`PureClone`] trait, which is a subtrait of [`Clone`] (and a logical
4+
//! supertrait of [`Copy`]). It is only implemented for types with a compliant `clone` method.
65
//!
76
//! See the [`cell`](module@cell) module documentation for more information on how to use it.
87
//!
98
//! # Background
109
//!
11-
//! This crate was largely inspired by the Swift programming language's class properties (fields in
12-
//! Rust speak), which have value semantics. In Swift, class types themselves have reference
13-
//! semantics and are shared. But methods on class types are mutating. My observation is that the
14-
//! Swift compiler is able to guarantee memory safety in a single-threaded context because copy
15-
//! constructors are not defined by the user. Intead, the compiler automatically generates ones that
16-
//! simply perform a field-wise clone.
17-
//!
18-
//! In Rust, to enable interiorly mutating methods on a `struct` stored in an [`Rc`](alloc::rc::Rc)
19-
//! without the overhead of a [`RefCell`](core::cell::RefCell), we can wrap each of the fields in a
20-
//! [`core::cell::Cell`]. But its [`get`](core::cell::Cell::get) method is only implemented for
21-
//! types that are `Copy`. This is because if the `clone` method obtains a reference to the `Cell`'s
22-
//! interior, it may be able to mutate its state. This can cause undefined behavior, as demonstrated
23-
//! in this [example].
10+
//! To enable interiorly mutating methods on a type stored in an [`Rc`](alloc::rc::Rc) without the
11+
//! overhead of a [`RefCell`](core::cell::RefCell), we can wrap each of its fields in a
12+
//! [`core::cell::Cell`]. But `Cell`'s [`get`](core::cell::Cell::get) method is only implemented for
13+
//! types that are `Copy`. This is because if the `clone` method obtains a reference to the
14+
//! containing `Cell`, it may be able to mutate its state. This can cause undefined behavior, as
15+
//! demonstrated in this [example].
2416
//!
2517
//! By restricting ourselves to a checked subset of `Clone` implementations that do not exploit
2618
//! interior mutability to mutate the `Cell` content, it becomes possible to provide a `Cell` with a
27-
//! `get` method that does not require `Copy` types.
19+
//! `get` method that does not require the type to be `Copy`.
2820
//!
2921
//! See the documentation for [`PureClone`] for a list of implemented types and the [`clone`] module
3022
//! documentation for more details.
@@ -43,8 +35,8 @@
4335
//! ## Interaction with specialization
4436
//!
4537
//! The [`PureClone`](derive@clone::PureClone) proc macro generates:
46-
//! 1. A non-`default` `Clone` impl with trait bounds that ensure any fields with generics are also
47-
//! `Clone`; and
38+
//! 1. A non-`default` `Clone` impl with trait bounds that ensure any fields with generic parameters
39+
//! are also `Clone`; and
4840
//! 1. A `PureClone` impl that only compiles if all fields are also `PureClone`.
4941
//!
5042
//! Item 1 is non-`default` and hence cannot be further specialized.

tests/ui/field_not_clone.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ error[E0277]: the trait bound `Foo: PureClone` is not satisfied
1414
| ^^^ the trait `PureClone` is not implemented for `Foo`
1515
|
1616
note: required by `pure_clone`
17-
--> $DIR/clone.rs:70:5
17+
--> $DIR/clone.rs:66:5
1818
|
19-
70 | fn pure_clone(&self) -> Self {
19+
66 | fn pure_clone(&self) -> Self {
2020
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

tests/ui/field_not_pure_clone.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ error[E0277]: the trait bound `Foo: PureClone` is not satisfied
55
| ^^^ the trait `PureClone` is not implemented for `Foo`
66
|
77
note: required by `pure_clone`
8-
--> $DIR/clone.rs:70:5
8+
--> $DIR/clone.rs:66:5
99
|
10-
70 | fn pure_clone(&self) -> Self {
10+
66 | fn pure_clone(&self) -> Self {
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

0 commit comments

Comments
 (0)