Skip to content

Commit eadae1c

Browse files
committed
Auto merge of rust-lang#142432 - matthiaskrgr:rollup-ziuls9y, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - rust-lang#138016 (Added `Clone` implementation for `ChunkBy`) - rust-lang#141162 (refactor `AttributeGate` and `rustc_attr!` to emit notes during feature checking) - rust-lang#141474 (Add `ParseMode::Diagnostic` and fix multiline spans in diagnostic attribute lints) - rust-lang#141947 (Specify that "option-like" enums must be `#[repr(Rust)]` to be ABI-compatible with their non-1ZST field.) - rust-lang#142252 (Improve clarity of `core::sync::atomic` docs about "Considerations" in regards to CAS operations) - rust-lang#142337 (miri: add flag to suppress float non-determinism) r? `@ghost` `@rustbot` modify labels: rollup
2 parents a78ed82 + 058c23d commit eadae1c

File tree

4 files changed

+169
-33
lines changed

4 files changed

+169
-33
lines changed

alloctests/tests/slice.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1636,6 +1636,19 @@ fn test_chunk_by() {
16361636
assert_eq!(iter.next_back(), Some(&[1][..]));
16371637
assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
16381638
assert_eq!(iter.next_back(), None);
1639+
1640+
let mut iter = slice.chunk_by(|a, b| a == b);
1641+
assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
1642+
assert_eq!(iter.next(), Some(&[3, 3][..]));
1643+
let mut iter_clone = iter.clone();
1644+
assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
1645+
assert_eq!(iter.next(), Some(&[1][..]));
1646+
assert_eq!(iter.next(), Some(&[0][..]));
1647+
assert_eq!(iter.next(), None);
1648+
assert_eq!(iter_clone.next(), Some(&[2, 2, 2][..]));
1649+
assert_eq!(iter_clone.next(), Some(&[1][..]));
1650+
assert_eq!(iter_clone.next(), Some(&[0][..]));
1651+
assert_eq!(iter_clone.next(), None);
16391652
}
16401653

16411654
#[test]

core/src/primitive_docs.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1847,6 +1847,8 @@ mod prim_ref {}
18471847
/// - If `T` is guaranteed to be subject to the [null pointer
18481848
/// optimization](option/index.html#representation), and `E` is an enum satisfying the following
18491849
/// requirements, then `T` and `E` are ABI-compatible. Such an enum `E` is called "option-like".
1850+
/// - The enum `E` uses the [`Rust` representation], and is not modified by the `align` or
1851+
/// `packed` representation modifiers.
18501852
/// - The enum `E` has exactly two variants.
18511853
/// - One variant has exactly one field, of type `T`.
18521854
/// - All fields of the other variant are zero-sized with 1-byte alignment.
@@ -1920,6 +1922,7 @@ mod prim_ref {}
19201922
/// [`Pointer`]: fmt::Pointer
19211923
/// [`UnwindSafe`]: panic::UnwindSafe
19221924
/// [`RefUnwindSafe`]: panic::RefUnwindSafe
1925+
/// [`Rust` representation]: <https://doc.rust-lang.org/reference/type-layout.html#the-rust-representation>
19231926
///
19241927
/// In addition, all *safe* function pointers implement [`Fn`], [`FnMut`], and [`FnOnce`], because
19251928
/// these traits are specially known to the compiler.

core/src/slice/iter.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3376,6 +3376,13 @@ where
33763376
#[stable(feature = "slice_group_by", since = "1.77.0")]
33773377
impl<'a, T: 'a, P> FusedIterator for ChunkBy<'a, T, P> where P: FnMut(&T, &T) -> bool {}
33783378

3379+
#[stable(feature = "slice_group_by_clone", since = "CURRENT_RUSTC_VERSION")]
3380+
impl<'a, T: 'a, P: Clone> Clone for ChunkBy<'a, T, P> {
3381+
fn clone(&self) -> Self {
3382+
Self { slice: self.slice, predicate: self.predicate.clone() }
3383+
}
3384+
}
3385+
33793386
#[stable(feature = "slice_group_by", since = "1.77.0")]
33803387
impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for ChunkBy<'a, T, P> {
33813388
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {

core/src/sync/atomic.rs

Lines changed: 146 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,19 @@ impl AtomicBool {
891891
/// Err(false));
892892
/// assert_eq!(some_bool.load(Ordering::Relaxed), false);
893893
/// ```
894+
///
895+
/// # Considerations
896+
///
897+
/// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
898+
/// of CAS operations. In particular, a load of the value followed by a successful
899+
/// `compare_exchange` with the previous load *does not ensure* that other threads have not
900+
/// changed the value in the interim. This is usually important when the *equality* check in
901+
/// the `compare_exchange` is being used to check the *identity* of a value, but equality
902+
/// does not necessarily imply identity. In this case, `compare_exchange` can lead to the
903+
/// [ABA problem].
904+
///
905+
/// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
906+
/// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
894907
#[inline]
895908
#[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
896909
#[doc(alias = "compare_and_swap")]
@@ -973,6 +986,19 @@ impl AtomicBool {
973986
/// }
974987
/// }
975988
/// ```
989+
///
990+
/// # Considerations
991+
///
992+
/// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
993+
/// of CAS operations. In particular, a load of the value followed by a successful
994+
/// `compare_exchange` with the previous load *does not ensure* that other threads have not
995+
/// changed the value in the interim. This is usually important when the *equality* check in
996+
/// the `compare_exchange` is being used to check the *identity* of a value, but equality
997+
/// does not necessarily imply identity. In this case, `compare_exchange` can lead to the
998+
/// [ABA problem].
999+
///
1000+
/// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
1001+
/// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
9761002
#[inline]
9771003
#[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
9781004
#[doc(alias = "compare_and_swap")]
@@ -1271,11 +1297,14 @@ impl AtomicBool {
12711297
///
12721298
/// # Considerations
12731299
///
1274-
/// This method is not magic; it is not provided by the hardware.
1275-
/// It is implemented in terms of [`AtomicBool::compare_exchange_weak`], and suffers from the same drawbacks.
1276-
/// In particular, this method will not circumvent the [ABA Problem].
1300+
/// This method is not magic; it is not provided by the hardware, and does not act like a
1301+
/// critical section or mutex.
1302+
///
1303+
/// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
1304+
/// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem].
12771305
///
12781306
/// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
1307+
/// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
12791308
///
12801309
/// # Examples
12811310
///
@@ -1338,11 +1367,14 @@ impl AtomicBool {
13381367
///
13391368
/// # Considerations
13401369
///
1341-
/// This method is not magic; it is not provided by the hardware.
1342-
/// It is implemented in terms of [`AtomicBool::compare_exchange_weak`], and suffers from the same drawbacks.
1343-
/// In particular, this method will not circumvent the [ABA Problem].
1370+
/// This method is not magic; it is not provided by the hardware, and does not act like a
1371+
/// critical section or mutex.
1372+
///
1373+
/// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
1374+
/// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem].
13441375
///
13451376
/// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
1377+
/// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
13461378
///
13471379
/// # Examples
13481380
///
@@ -1393,11 +1425,14 @@ impl AtomicBool {
13931425
///
13941426
/// # Considerations
13951427
///
1396-
/// This method is not magic; it is not provided by the hardware.
1397-
/// It is implemented in terms of [`AtomicBool::compare_exchange_weak`], and suffers from the same drawbacks.
1398-
/// In particular, this method will not circumvent the [ABA Problem].
1428+
/// This method is not magic; it is not provided by the hardware, and does not act like a
1429+
/// critical section or mutex.
1430+
///
1431+
/// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
1432+
/// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem].
13991433
///
14001434
/// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
1435+
/// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
14011436
///
14021437
/// # Examples
14031438
///
@@ -1825,6 +1860,20 @@ impl<T> AtomicPtr<T> {
18251860
/// let value = some_ptr.compare_exchange(ptr, other_ptr,
18261861
/// Ordering::SeqCst, Ordering::Relaxed);
18271862
/// ```
1863+
///
1864+
/// # Considerations
1865+
///
1866+
/// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
1867+
/// of CAS operations. In particular, a load of the value followed by a successful
1868+
/// `compare_exchange` with the previous load *does not ensure* that other threads have not
1869+
/// changed the value in the interim. This is usually important when the *equality* check in
1870+
/// the `compare_exchange` is being used to check the *identity* of a value, but equality
1871+
/// does not necessarily imply identity. This is a particularly common case for pointers, as
1872+
/// a pointer holding the same address does not imply that the same object exists at that
1873+
/// address! In this case, `compare_exchange` can lead to the [ABA problem].
1874+
///
1875+
/// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
1876+
/// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
18281877
#[inline]
18291878
#[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
18301879
#[cfg(target_has_atomic = "ptr")]
@@ -1874,6 +1923,20 @@ impl<T> AtomicPtr<T> {
18741923
/// }
18751924
/// }
18761925
/// ```
1926+
///
1927+
/// # Considerations
1928+
///
1929+
/// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
1930+
/// of CAS operations. In particular, a load of the value followed by a successful
1931+
/// `compare_exchange` with the previous load *does not ensure* that other threads have not
1932+
/// changed the value in the interim. This is usually important when the *equality* check in
1933+
/// the `compare_exchange` is being used to check the *identity* of a value, but equality
1934+
/// does not necessarily imply identity. This is a particularly common case for pointers, as
1935+
/// a pointer holding the same address does not imply that the same object exists at that
1936+
/// address! In this case, `compare_exchange` can lead to the [ABA problem].
1937+
///
1938+
/// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
1939+
/// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
18771940
#[inline]
18781941
#[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
18791942
#[cfg(target_has_atomic = "ptr")]
@@ -1917,11 +1980,15 @@ impl<T> AtomicPtr<T> {
19171980
///
19181981
/// # Considerations
19191982
///
1920-
/// This method is not magic; it is not provided by the hardware.
1921-
/// It is implemented in terms of [`AtomicPtr::compare_exchange_weak`], and suffers from the same drawbacks.
1922-
/// In particular, this method will not circumvent the [ABA Problem].
1983+
/// This method is not magic; it is not provided by the hardware, and does not act like a
1984+
/// critical section or mutex.
1985+
///
1986+
/// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
1987+
/// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem],
1988+
/// which is a particularly common pitfall for pointers!
19231989
///
19241990
/// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
1991+
/// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
19251992
///
19261993
/// # Examples
19271994
///
@@ -1992,11 +2059,15 @@ impl<T> AtomicPtr<T> {
19922059
///
19932060
/// # Considerations
19942061
///
1995-
/// This method is not magic; it is not provided by the hardware.
1996-
/// It is implemented in terms of [`AtomicPtr::compare_exchange_weak`], and suffers from the same drawbacks.
1997-
/// In particular, this method will not circumvent the [ABA Problem].
2062+
/// This method is not magic; it is not provided by the hardware, and does not act like a
2063+
/// critical section or mutex.
2064+
///
2065+
/// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
2066+
/// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem],
2067+
/// which is a particularly common pitfall for pointers!
19982068
///
19992069
/// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
2070+
/// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
20002071
///
20012072
/// # Examples
20022073
///
@@ -2057,11 +2128,15 @@ impl<T> AtomicPtr<T> {
20572128
///
20582129
/// # Considerations
20592130
///
2060-
/// This method is not magic; it is not provided by the hardware.
2061-
/// It is implemented in terms of [`AtomicPtr::compare_exchange_weak`], and suffers from the same drawbacks.
2062-
/// In particular, this method will not circumvent the [ABA Problem].
2131+
/// This method is not magic; it is not provided by the hardware, and does not act like a
2132+
/// critical section or mutex.
2133+
///
2134+
/// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
2135+
/// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem],
2136+
/// which is a particularly common pitfall for pointers!
20632137
///
20642138
/// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
2139+
/// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
20652140
///
20662141
/// # Examples
20672142
///
@@ -2967,6 +3042,20 @@ macro_rules! atomic_int {
29673042
/// Err(10));
29683043
/// assert_eq!(some_var.load(Ordering::Relaxed), 10);
29693044
/// ```
3045+
///
3046+
/// # Considerations
3047+
///
3048+
/// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
3049+
/// of CAS operations. In particular, a load of the value followed by a successful
3050+
/// `compare_exchange` with the previous load *does not ensure* that other threads have not
3051+
/// changed the value in the interim! This is usually important when the *equality* check in
3052+
/// the `compare_exchange` is being used to check the *identity* of a value, but equality
3053+
/// does not necessarily imply identity. This is a particularly common case for pointers, as
3054+
/// a pointer holding the same address does not imply that the same object exists at that
3055+
/// address! In this case, `compare_exchange` can lead to the [ABA problem].
3056+
///
3057+
/// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
3058+
/// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
29703059
#[inline]
29713060
#[$stable_cxchg]
29723061
#[$cfg_cas]
@@ -3016,6 +3105,20 @@ macro_rules! atomic_int {
30163105
/// }
30173106
/// }
30183107
/// ```
3108+
///
3109+
/// # Considerations
3110+
///
3111+
/// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
3112+
/// of CAS operations. In particular, a load of the value followed by a successful
3113+
/// `compare_exchange` with the previous load *does not ensure* that other threads have not
3114+
/// changed the value in the interim. This is usually important when the *equality* check in
3115+
/// the `compare_exchange` is being used to check the *identity* of a value, but equality
3116+
/// does not necessarily imply identity. This is a particularly common case for pointers, as
3117+
/// a pointer holding the same address does not imply that the same object exists at that
3118+
/// address! In this case, `compare_exchange` can lead to the [ABA problem].
3119+
///
3120+
/// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
3121+
/// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
30193122
#[inline]
30203123
#[$stable_cxchg]
30213124
#[$cfg_cas]
@@ -3246,13 +3349,16 @@ macro_rules! atomic_int {
32463349
///
32473350
/// # Considerations
32483351
///
3249-
/// This method is not magic; it is not provided by the hardware.
3250-
/// It is implemented in terms of
3251-
#[doc = concat!("[`", stringify!($atomic_type), "::compare_exchange_weak`],")]
3252-
/// and suffers from the same drawbacks.
3253-
/// In particular, this method will not circumvent the [ABA Problem].
3352+
/// This method is not magic; it is not provided by the hardware, and does not act like a
3353+
/// critical section or mutex.
3354+
///
3355+
/// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
3356+
/// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
3357+
/// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
3358+
/// of the atomic is not in and of itself sufficient to ensure any required preconditions.
32543359
///
32553360
/// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
3361+
/// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
32563362
///
32573363
/// # Examples
32583364
///
@@ -3309,13 +3415,16 @@ macro_rules! atomic_int {
33093415
///
33103416
/// # Considerations
33113417
///
3312-
/// This method is not magic; it is not provided by the hardware.
3313-
/// It is implemented in terms of
3314-
#[doc = concat!("[`", stringify!($atomic_type), "::compare_exchange_weak`],")]
3315-
/// and suffers from the same drawbacks.
3316-
/// In particular, this method will not circumvent the [ABA Problem].
3418+
/// This method is not magic; it is not provided by the hardware, and does not act like a
3419+
/// critical section or mutex.
3420+
///
3421+
/// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
3422+
/// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
3423+
/// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
3424+
/// of the atomic is not in and of itself sufficient to ensure any required preconditions.
33173425
///
33183426
/// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
3427+
/// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
33193428
///
33203429
/// # Examples
33213430
///
@@ -3367,13 +3476,17 @@ macro_rules! atomic_int {
33673476
///
33683477
/// # Considerations
33693478
///
3370-
/// This method is not magic; it is not provided by the hardware.
3371-
/// It is implemented in terms of
3372-
#[doc = concat!("[`", stringify!($atomic_type), "::compare_exchange_weak`],")]
3373-
/// and suffers from the same drawbacks.
3374-
/// In particular, this method will not circumvent the [ABA Problem].
3479+
/// [CAS operation]: https://en.wikipedia.org/wiki/Compare-and-swap
3480+
/// This method is not magic; it is not provided by the hardware, and does not act like a
3481+
/// critical section or mutex.
3482+
///
3483+
/// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
3484+
/// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
3485+
/// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
3486+
/// of the atomic is not in and of itself sufficient to ensure any required preconditions.
33753487
///
33763488
/// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
3489+
/// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
33773490
///
33783491
/// # Examples
33793492
///

0 commit comments

Comments
 (0)