From bd7cbaecd32aa59ea5d14b3b35490a058512b92a Mon Sep 17 00:00:00 2001 From: Camelid Date: Sun, 30 Aug 2020 18:40:56 -0700 Subject: [PATCH 1/3] Explain fully qualified syntax for `Rc` and `Arc` --- library/alloc/src/rc.rs | 25 ++++++++++++++++++------- library/alloc/src/sync.rs | 16 ++++++++++++++-- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 72e5e0a82424b..fdf64953e2abc 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -11,7 +11,7 @@ //! is no exception: you cannot generally obtain a mutable reference to //! something inside an [`Rc`]. If you need mutability, put a [`Cell`] //! or [`RefCell`] inside the [`Rc`]; see [an example of mutability -//! inside an Rc][mutability]. +//! inside an `Rc`][mutability]. //! //! [`Rc`] uses non-atomic reference counting. This means that overhead is very //! low, but an [`Rc`] cannot be sent between threads, and consequently [`Rc`] @@ -35,15 +35,26 @@ //! `Rc` automatically dereferences to `T` (via the [`Deref`] trait), //! so you can call `T`'s methods on a value of type [`Rc`][`Rc`]. To avoid name //! clashes with `T`'s methods, the methods of [`Rc`][`Rc`] itself are associated -//! functions, called using function-like syntax: +//! functions, called using [fully qualified syntax]: //! //! ``` //! use std::rc::Rc; -//! let my_rc = Rc::new(()); //! +//! let my_rc = Rc::new(()); //! Rc::downgrade(&my_rc); //! ``` //! +//! `Rc`'s implementations of traits like `Clone` should also be called using +//! fully qualified syntax to avoid confusion as to whether the *reference* is being +//! cloned or the *backing data* (`T`) is being cloned: +//! +//! ``` +//! use std::rc::Rc; +//! +//! let my_rc = Rc::new(()); +//! let your_rc = Rc::clone(&my_rc); +//! ``` +//! //! [`Weak`][`Weak`] does not auto-dereference to `T`, because the inner value may have //! already been dropped. //! @@ -54,6 +65,7 @@ //! //! ``` //! use std::rc::Rc; +//! //! let foo = Rc::new(vec![1.0, 2.0, 3.0]); //! // The two syntaxes below are equivalent. //! let a = foo.clone(); @@ -218,7 +230,7 @@ //! [`Cell`]: core::cell::Cell //! [`RefCell`]: core::cell::RefCell //! [send]: core::marker::Send -//! [arc]: ../../std/sync/struct.Arc.html +//! [arc]: alloc::sync::Arc //! [`Deref`]: core::ops::Deref //! [downgrade]: Rc::downgrade //! [upgrade]: Weak::upgrade @@ -272,10 +284,9 @@ struct RcBox { /// /// The inherent methods of `Rc` are all associated functions, which means /// that you have to call them as e.g., [`Rc::get_mut(&mut value)`][get_mut] instead of -/// `value.get_mut()`. This avoids conflicts with methods of the inner -/// type `T`. +/// `value.get_mut()`. This avoids conflicts with methods of the inner type `T`. /// -/// [get_mut]: #method.get_mut +/// [get_mut]: Rc::get_mut #[cfg_attr(not(test), rustc_diagnostic_item = "Rc")] #[stable(feature = "rust1", since = "1.0.0")] pub struct Rc { diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 73ff795c01aa8..5ec7d4e3c81ee 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -129,15 +129,26 @@ macro_rules! acquire { /// `Arc` automatically dereferences to `T` (via the [`Deref`][deref] trait), /// so you can call `T`'s methods on a value of type `Arc`. To avoid name /// clashes with `T`'s methods, the methods of `Arc` itself are associated -/// functions, called using function-like syntax: +/// functions, called using [fully qualified syntax]: /// /// ``` /// use std::sync::Arc; -/// let my_arc = Arc::new(()); /// +/// let my_arc = Arc::new(()); /// Arc::downgrade(&my_arc); /// ``` /// +/// `Arc`'s implementations of traits like `Clone` should also be called using +/// fully qualified syntax to avoid confusion as to whether the *reference* is being +/// cloned or the *backing data* (`T`) is being cloned: +/// +/// ``` +/// use std::sync::Arc; +/// +/// let my_arc = Arc::new(()); +/// let your_arc = Arc::clone(&my_arc); +/// ``` +/// /// [`Weak`][Weak] does not auto-dereference to `T`, because the inner value may have /// already been dropped. /// @@ -154,6 +165,7 @@ macro_rules! acquire { /// [`RefCell`]: core::cell::RefCell /// [`std::sync`]: ../../std/sync/index.html /// [`Arc::clone(&from)`]: Arc::clone +/// [fully qualified syntax]: https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#fully-qualified-syntax-for-disambiguation-calling-methods-with-the-same-name /// /// # Examples /// From e0eed3c55836292907ec4ea5ce0a3b62e62bed38 Mon Sep 17 00:00:00 2001 From: Camelid Date: Sun, 30 Aug 2020 21:22:10 -0700 Subject: [PATCH 2/3] Fix broken intra-doc link --- library/alloc/src/rc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index fdf64953e2abc..eaf67cfda25ad 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -230,7 +230,7 @@ //! [`Cell`]: core::cell::Cell //! [`RefCell`]: core::cell::RefCell //! [send]: core::marker::Send -//! [arc]: alloc::sync::Arc +//! [arc]: crate::sync::Arc //! [`Deref`]: core::ops::Deref //! [downgrade]: Rc::downgrade //! [upgrade]: Weak::upgrade From 4e30e10f25ed39453ef69666a98e9650c7222c52 Mon Sep 17 00:00:00 2001 From: Camelid Date: Wed, 28 Oct 2020 16:47:05 -0700 Subject: [PATCH 3/3] Don't say you "should" use fully qualified syntax That recommendation was removed last year; there isn't a particular style that is officially recommended anymore. --- library/alloc/src/rc.rs | 13 ++++++++----- library/alloc/src/sync.rs | 13 ++++++++----- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index eaf67cfda25ad..6dcd0c6056c30 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -44,15 +44,18 @@ //! Rc::downgrade(&my_rc); //! ``` //! -//! `Rc`'s implementations of traits like `Clone` should also be called using -//! fully qualified syntax to avoid confusion as to whether the *reference* is being -//! cloned or the *backing data* (`T`) is being cloned: +//! `Rc`'s implementations of traits like `Clone` may also be called using +//! fully qualified syntax. Some people prefer to use fully qualified syntax, +//! while others prefer using method-call syntax. //! //! ``` //! use std::rc::Rc; //! -//! let my_rc = Rc::new(()); -//! let your_rc = Rc::clone(&my_rc); +//! let rc = Rc::new(()); +//! // Method-call syntax +//! let rc2 = rc.clone(); +//! // Fully qualified syntax +//! let rc3 = Rc::clone(&rc); //! ``` //! //! [`Weak`][`Weak`] does not auto-dereference to `T`, because the inner value may have diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 5ec7d4e3c81ee..5ab930a520884 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -138,15 +138,18 @@ macro_rules! acquire { /// Arc::downgrade(&my_arc); /// ``` /// -/// `Arc`'s implementations of traits like `Clone` should also be called using -/// fully qualified syntax to avoid confusion as to whether the *reference* is being -/// cloned or the *backing data* (`T`) is being cloned: +/// `Arc`'s implementations of traits like `Clone` may also be called using +/// fully qualified syntax. Some people prefer to use fully qualified syntax, +/// while others prefer using method-call syntax. /// /// ``` /// use std::sync::Arc; /// -/// let my_arc = Arc::new(()); -/// let your_arc = Arc::clone(&my_arc); +/// let arc = Arc::new(()); +/// // Method-call syntax +/// let arc2 = arc.clone(); +/// // Fully qualified syntax +/// let arc3 = Arc::clone(&arc); /// ``` /// /// [`Weak`][Weak] does not auto-dereference to `T`, because the inner value may have