diff --git a/turbopack/crates/turbo-tasks/src/rcstr.rs b/turbopack/crates/turbo-tasks/src/rcstr.rs index 65c946ffd7b3b..caca34d1937d7 100644 --- a/turbopack/crates/turbo-tasks/src/rcstr.rs +++ b/turbopack/crates/turbo-tasks/src/rcstr.rs @@ -12,11 +12,36 @@ use turbo_tasks_hash::{DeterministicHash, DeterministicHasher}; use crate::debug::{ValueDebugFormat, ValueDebugFormatString}; -/// A reference counted [`String`], similar to [`Arc`][std::sync::Arc]. +/// An immutable reference counted [`String`], similar to [`Arc`][std::sync::Arc]. /// -/// This type is intentionally opaque to allow for optimizations to the -/// underlying representation. Future implementations may use inline -/// representations or interning. +/// This is the preferred immutable string type for [`turbo_task::function`][macro@crate::function] +/// arguments and inside of [`turbo_task::value`][macro@crate::value]. +/// +/// As turbo-tasks must store copies of function arguments to enable caching, non-reference counted +/// [`String`]s would incur frequent cloning. Reference counting typically decreases memory +/// consumption and CPU time in these cases. +/// +/// ## Conversion +/// +/// Converting a `String` or `&str` to an `RcStr` can be perfomed using `.into()` or +/// `RcStr::from(...)`: +/// +/// ``` +/// # use turbo_tasks::RcStr; +/// # +/// let s = "foo"; +/// let rc_s1: RcStr = s.into(); +/// let rc_s2 = RcStr::from(s); +/// assert_eq!(rc_s1, rc_s2); +/// ``` +/// +/// Converting from an [`RcStr`] to a `&str` should be done with [`RcStr::as_str`]. Converting to a +/// `String` should be done with [`RcStr::into_owned`]. +/// +/// ## Future Optimizations +/// +/// This type is intentionally opaque to allow for optimizations to the underlying representation. +/// Future implementations may use inline representations or interning. // // If you want to change the underlying string type to `Arc`, please ensure that you profile // performance. The current implementation offers very cheap `String -> RcStr -> String`, meaning we @@ -30,11 +55,17 @@ impl RcStr { self.0.as_str() } - /// This implementation is more efficient than `.to_string()` + /// Returns an owned mutable [`String`]. + /// + /// This implementation is more efficient than [`ToString::to_string`]: + /// + /// - If the reference count is 1, the `Arc` can be unwrapped, giving ownership of the + /// underlying string without cloning in `O(1)` time. + /// - This avoids some of the potential overhead of the `Display` trait. pub fn into_owned(self) -> String { match Arc::try_unwrap(self.0) { Ok(v) => v, - Err(arc) => arc.to_string(), + Err(arc) => (*arc).clone(), } }