about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--library/core/src/clone.rs39
1 files changed, 37 insertions, 2 deletions
diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs
index c237ac84cf4..2c0662c9629 100644
--- a/library/core/src/clone.rs
+++ b/library/core/src/clone.rs
@@ -38,7 +38,16 @@
 
 mod uninit;
 
-/// A common trait for the ability to explicitly duplicate an object.
+/// A common trait that allows explicit creation of a duplicate value.
+///
+/// Calling [`clone`] always produces a new value.
+/// However, for types that are references to other data (such as smart pointers or references),
+/// the new value may still point to the same underlying data, rather than duplicating it.
+/// See [`Clone::clone`] for more details.
+///
+/// This distinction is especially important when using `#[derive(Clone)]` on structs containing
+/// smart pointers like `Arc<Mutex<T>>` - the cloned struct will share mutable state with the
+/// original.
 ///
 /// Differs from [`Copy`] in that [`Copy`] is implicit and an inexpensive bit-wise copy, while
 /// `Clone` is always explicit and may or may not be expensive. In order to enforce
@@ -147,7 +156,16 @@ mod uninit;
 #[rustc_diagnostic_item = "Clone"]
 #[rustc_trivial_field_reads]
 pub trait Clone: Sized {
-    /// Returns a copy of the value.
+    /// Returns a duplicate of the value.
+    ///
+    /// Note that what "duplicate" means varies by type:
+    /// - For most types, this creates a deep, independent copy
+    /// - For reference types like `&T`, this creates another reference to the same value
+    /// - For smart pointers like [`Arc`] or [`Rc`], this increments the reference count
+    ///   but still points to the same underlying data
+    ///
+    /// [`Arc`]: ../../std/sync/struct.Arc.html
+    /// [`Rc`]: ../../std/rc/struct.Rc.html
     ///
     /// # Examples
     ///
@@ -157,6 +175,23 @@ pub trait Clone: Sized {
     ///
     /// assert_eq!("Hello", hello.clone());
     /// ```
+    ///
+    /// Example with a reference-counted type:
+    ///
+    /// ```
+    /// use std::sync::{Arc, Mutex};
+    ///
+    /// let data = Arc::new(Mutex::new(vec![1, 2, 3]));
+    /// let data_clone = data.clone(); // Creates another Arc pointing to the same Mutex
+    ///
+    /// {
+    ///     let mut lock = data.lock().unwrap();
+    ///     lock.push(4);
+    /// }
+    ///
+    /// // Changes are visible through the clone because they share the same underlying data
+    /// assert_eq!(*data_clone.lock().unwrap(), vec![1, 2, 3, 4]);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[must_use = "cloning is often expensive and is not expected to have side effects"]
     // Clone::clone is special because the compiler generates MIR to implement it for some types.