Skip to content

Commit 978d2cf

Browse files
committed
Auto merge of #41887 - steveklabnik:rollup, r=steveklabnik
Rollup of 5 pull requests - Successful merges: #41531, #41536, #41809, #41854, #41886 - Failed merges:
2 parents 25a1617 + 19f1146 commit 978d2cf

File tree

4 files changed

+212
-79
lines changed

4 files changed

+212
-79
lines changed

src/liballoc/arc.rs

+29-10
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,33 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize;
5454
/// exception. If you need to mutate through an `Arc`, use [`Mutex`][mutex],
5555
/// [`RwLock`][rwlock], or one of the [`Atomic`][atomic] types.
5656
///
57-
/// `Arc` uses atomic operations for reference counting, so `Arc`s can be
58-
/// sent between threads. In other words, `Arc<T>` implements [`Send`]
59-
/// as long as `T` implements [`Send`] and [`Sync`][sync]. The disadvantage is
60-
/// that atomic operations are more expensive than ordinary memory accesses.
61-
/// If you are not sharing reference-counted values between threads, consider
62-
/// using [`rc::Rc`][`Rc`] for lower overhead. [`Rc`] is a safe default, because
63-
/// the compiler will catch any attempt to send an [`Rc`] between threads.
64-
/// However, a library might choose `Arc` in order to give library consumers
57+
/// ## Thread Safety
58+
///
59+
/// Unlike [`Rc<T>`], `Arc<T>` uses atomic operations for its reference
60+
/// counting This means that it is thread-safe. The disadvantage is that
61+
/// atomic operations are more expensive than ordinary memory accesses. If you
62+
/// are not sharing reference-counted values between threads, consider using
63+
/// [`Rc<T>`] for lower overhead. [`Rc<T>`] is a safe default, because the
64+
/// compiler will catch any attempt to send an [`Rc<T>`] between threads.
65+
/// However, a library might choose `Arc<T>` in order to give library consumers
6566
/// more flexibility.
6667
///
68+
/// `Arc<T>` will implement [`Send`] and [`Sync`] as long as the `T` implements
69+
/// [`Send`] and [`Sync`]. Why can't you put a non-thread-safe type `T` in an
70+
/// `Arc<T>` to make it thread-safe? This may be a bit counter-intuitive at
71+
/// first: after all, isn't the point of `Arc<T>` thread safety? The key is
72+
/// this: `Arc<T>` makes it thread safe to have multiple ownership of the same
73+
/// data, but it doesn't add thread safety to its data. Consider
74+
/// `Arc<RefCell<T>>`. `RefCell<T>` isn't [`Sync`], and if `Arc<T>` was always
75+
/// [`Send`], `Arc<RefCell<T>>` would be as well. But then we'd have a problem:
76+
/// `RefCell<T>` is not thread safe; it keeps track of the borrowing count using
77+
/// non-atomic operations.
78+
///
79+
/// In the end, this means that you may need to pair `Arc<T>` with some sort of
80+
/// `std::sync` type, usually `Mutex<T>`.
81+
///
82+
/// ## Breaking cycles with `Weak`
83+
///
6784
/// The [`downgrade`][downgrade] method can be used to create a non-owning
6885
/// [`Weak`][weak] pointer. A [`Weak`][weak] pointer can be [`upgrade`][upgrade]d
6986
/// to an `Arc`, but this will return [`None`] if the value has already been
@@ -74,6 +91,8 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize;
7491
/// strong `Arc` pointers from parent nodes to children, and [`Weak`][weak]
7592
/// pointers from children back to their parents.
7693
///
94+
/// ## `Deref` behavior
95+
///
7796
/// `Arc<T>` automatically dereferences to `T` (via the [`Deref`][deref] trait),
7897
/// so you can call `T`'s methods on a value of type `Arc<T>`. To avoid name
7998
/// clashes with `T`'s methods, the methods of `Arc<T>` itself are [associated
@@ -91,13 +110,13 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize;
91110
///
92111
/// [arc]: struct.Arc.html
93112
/// [weak]: struct.Weak.html
94-
/// [`Rc`]: ../../std/rc/struct.Rc.html
113+
/// [`Rc<T>`]: ../../std/rc/struct.Rc.html
95114
/// [clone]: ../../std/clone/trait.Clone.html#tymethod.clone
96115
/// [mutex]: ../../std/sync/struct.Mutex.html
97116
/// [rwlock]: ../../std/sync/struct.RwLock.html
98117
/// [atomic]: ../../std/sync/atomic/index.html
99118
/// [`Send`]: ../../std/marker/trait.Send.html
100-
/// [sync]: ../../std/marker/trait.Sync.html
119+
/// [`Sync`]: ../../std/marker/trait.Sync.html
101120
/// [deref]: ../../std/ops/trait.Deref.html
102121
/// [downgrade]: struct.Arc.html#method.downgrade
103122
/// [upgrade]: struct.Weak.html#method.upgrade

src/libcore/ptr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1005,7 +1005,7 @@ unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { }
10051005

10061006
#[unstable(feature = "unique", issue = "27730")]
10071007
impl<T: Sized> Unique<T> {
1008-
/// Creates a new `Shared` that is dangling, but well-aligned.
1008+
/// Creates a new `Unique` that is dangling, but well-aligned.
10091009
///
10101010
/// This is useful for initializing types which lazily allocate, like
10111011
/// `Vec::new` does.

src/libstd/path.rs

+35-1
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,17 @@
5151
//! ```
5252
//! use std::path::PathBuf;
5353
//!
54+
//! // This way works...
5455
//! let mut path = PathBuf::from("c:\\");
56+
//!
5557
//! path.push("windows");
5658
//! path.push("system32");
59+
//!
5760
//! path.set_extension("dll");
61+
//!
62+
//! // ... but push is best used if you don't know everything up
63+
//! // front. If you do, this way is better:
64+
//! let path: PathBuf = ["c:\\", "windows", "system32.dll"].iter().collect();
5865
//! ```
5966
//!
6067
//! [`Component`]: ../../std/path/enum.Component.html
@@ -63,6 +70,7 @@
6370
//! [`Path`]: ../../std/path/struct.Path.html
6471
//! [`push`]: ../../std/path/struct.PathBuf.html#method.push
6572
//! [`String`]: ../../std/string/struct.String.html
73+
//!
6674
//! [`str`]: ../../std/primitive.str.html
6775
//! [`OsString`]: ../../std/ffi/struct.OsString.html
6876
//! [`OsStr`]: ../../std/ffi/struct.OsStr.html
@@ -1036,14 +1044,40 @@ impl<'a> cmp::Ord for Components<'a> {
10361044
///
10371045
/// # Examples
10381046
///
1047+
/// You can use [`push`] to build up a `PathBuf` from
1048+
/// components:
1049+
///
10391050
/// ```
10401051
/// use std::path::PathBuf;
10411052
///
1042-
/// let mut path = PathBuf::from("c:\\");
1053+
/// let mut path = PathBuf::new();
1054+
///
1055+
/// path.push(r"C:\");
10431056
/// path.push("windows");
10441057
/// path.push("system32");
1058+
///
10451059
/// path.set_extension("dll");
10461060
/// ```
1061+
///
1062+
/// However, [`push`] is best used for dynamic situations. This is a better way
1063+
/// to do this when you know all of the components ahead of time:
1064+
///
1065+
/// ```
1066+
/// use std::path::PathBuf;
1067+
///
1068+
/// let path: PathBuf = [r"C:\", "windows", "system32.dll"].iter().collect();
1069+
/// ```
1070+
///
1071+
/// We can still do better than this! Since these are all strings, we can use
1072+
/// `From::from`:
1073+
///
1074+
/// ```
1075+
/// use std::path::PathBuf;
1076+
///
1077+
/// let path = PathBuf::from(r"C:\windows\system32.dll");
1078+
/// ```
1079+
///
1080+
/// Which method works best depends on what kind of situation you're in.
10471081
#[derive(Clone)]
10481082
#[stable(feature = "rust1", since = "1.0.0")]
10491083
pub struct PathBuf {

0 commit comments

Comments
 (0)