about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-12-27 03:28:21 +0000
committerbors <bors@rust-lang.org>2024-12-27 03:28:21 +0000
commit207ed1b18538b3bc77177b162ca8a05223e5e797 (patch)
treeed01c67c5cb97757acf928a81383043c23beb082
parent917bfa78478cbcc77406e5ea37b24c3eedefacf4 (diff)
parentc1447e34495fd72dc8d70cb7deea50c457686f69 (diff)
downloadrust-207ed1b18538b3bc77177b162ca8a05223e5e797.tar.gz
rust-207ed1b18538b3bc77177b162ca8a05223e5e797.zip
Auto merge of #134812 - jhpratt:rollup-a9klvez, r=jhpratt
Rollup of 8 pull requests

Successful merges:

 - #131522 ([macro_metavar_expr_concat] Fix #128346)
 - #134379 (Add `into_array` conversion destructors for `Box`, `Rc`, and `Arc`.)
 - #134644 (Document collection `From` and `FromIterator` impls that drop duplicate keys.)
 - #134649 (Fix forgetting to save statx availability on success)
 - #134728 (Use scoped threads in `std::sync::Barrier` examples)
 - #134782 (Update Code Example for `Iterator::rposition`)
 - #134789 (unwinding: bump version to fix naked_asm on Xous)
 - #134791 (docs: inline `std::ffi::c_str` types to `std::ffi`)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_expand/src/mbe/transcribe.rs6
-rw-r--r--library/Cargo.lock4
-rw-r--r--library/alloc/src/boxed.rs20
-rw-r--r--library/alloc/src/collections/btree/map.rs9
-rw-r--r--library/alloc/src/collections/btree/set.rs5
-rw-r--r--library/alloc/src/rc.rs20
-rw-r--r--library/alloc/src/sync.rs20
-rw-r--r--library/core/src/ffi/mod.rs4
-rw-r--r--library/core/src/iter/traits/iterator.rs1
-rw-r--r--library/std/src/collections/hash/map.rs9
-rw-r--r--library/std/src/collections/hash/set.rs5
-rw-r--r--library/std/src/ffi/mod.rs10
-rw-r--r--library/std/src/sync/barrier.rs60
-rw-r--r--library/std/src/sys/pal/unix/fs.rs6
-rw-r--r--library/unwind/Cargo.toml2
-rw-r--r--tests/crashes/128346.rs13
-rw-r--r--tests/ui/macros/macro-metavar-expr-concat/repetitions.rs22
-rw-r--r--tests/ui/macros/macro-metavar-expr-concat/repetitions.stderr22
18 files changed, 175 insertions, 63 deletions
diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs
index 4fb1eadd486..ef209c2bce1 100644
--- a/compiler/rustc_expand/src/mbe/transcribe.rs
+++ b/compiler/rustc_expand/src/mbe/transcribe.rs
@@ -697,8 +697,10 @@ fn transcribe_metavar_expr<'a>(
                     MetaVarExprConcatElem::Var(ident) => {
                         match matched_from_ident(dcx, *ident, interp)? {
                             NamedMatch::MatchedSeq(named_matches) => {
-                                let curr_idx = repeats.last().unwrap().0;
-                                match &named_matches[curr_idx] {
+                                let Some((curr_idx, _)) = repeats.last() else {
+                                    return Err(dcx.struct_span_err(sp.entire(), "invalid syntax"));
+                                };
+                                match &named_matches[*curr_idx] {
                                     // FIXME(c410-f3r) Nested repetitions are unimplemented
                                     MatchedSeq(_) => unimplemented!(),
                                     MatchedSingle(pnr) => {
diff --git a/library/Cargo.lock b/library/Cargo.lock
index 22f6e1edf21..15ca4cbff7b 100644
--- a/library/Cargo.lock
+++ b/library/Cargo.lock
@@ -403,9 +403,9 @@ dependencies = [
 
 [[package]]
 name = "unwinding"
-version = "0.2.4"
+version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2c6cb20f236dae10c69b0b45d82ef50af8b7e45c10e429e7901d26b49b4dbf3"
+checksum = "51f06a05848f650946acef3bf525fe96612226b61f74ae23ffa4e98bfbb8ab3c"
 dependencies = [
  "compiler_builtins",
  "gimli 0.31.1",
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index 23b85fbd4eb..ca3bd24a420 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -761,6 +761,26 @@ impl<T> Box<[T]> {
         };
         unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, Global).into_box(len)) }
     }
+
+    /// Converts the boxed slice into a boxed array.
+    ///
+    /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type.
+    ///
+    /// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
+    #[unstable(feature = "slice_as_array", issue = "133508")]
+    #[inline]
+    #[must_use]
+    pub fn into_array<const N: usize>(self) -> Option<Box<[T; N]>> {
+        if self.len() == N {
+            let ptr = Self::into_raw(self) as *mut [T; N];
+
+            // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length.
+            let me = unsafe { Box::from_raw(ptr) };
+            Some(me)
+        } else {
+            None
+        }
+    }
 }
 
 impl<T, A: Allocator> Box<[T], A> {
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index d1ce4e215ed..6d305386dbf 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -2289,6 +2289,10 @@ impl<K, V> FusedIterator for RangeMut<'_, K, V> {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K: Ord, V> FromIterator<(K, V)> for BTreeMap<K, V> {
+    /// Constructs a `BTreeMap<K, V>` from an iterator of key-value pairs.
+    ///
+    /// If the iterator produces any pairs with equal keys,
+    /// all but one of the corresponding values will be dropped.
     fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> BTreeMap<K, V> {
         let mut inputs: Vec<_> = iter.into_iter().collect();
 
@@ -2403,7 +2407,10 @@ where
 
 #[stable(feature = "std_collections_from_array", since = "1.56.0")]
 impl<K: Ord, V, const N: usize> From<[(K, V); N]> for BTreeMap<K, V> {
-    /// Converts a `[(K, V); N]` into a `BTreeMap<(K, V)>`.
+    /// Converts a `[(K, V); N]` into a `BTreeMap<K, V>`.
+    ///
+    /// If any entries in the array have equal keys,
+    /// all but one of the corresponding values will be dropped.
     ///
     /// ```
     /// use std::collections::BTreeMap;
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs
index 6f8c3b2d152..9660023d694 100644
--- a/library/alloc/src/collections/btree/set.rs
+++ b/library/alloc/src/collections/btree/set.rs
@@ -1491,6 +1491,11 @@ impl<T: Ord, A: Allocator + Clone> BTreeSet<T, A> {
 impl<T: Ord, const N: usize> From<[T; N]> for BTreeSet<T> {
     /// Converts a `[T; N]` into a `BTreeSet<T>`.
     ///
+    /// If the array contains any equal values,
+    /// all but one will be dropped.
+    ///
+    /// # Examples
+    ///
     /// ```
     /// use std::collections::BTreeSet;
     ///
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index b7ec3af9818..e014404eff3 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -1084,6 +1084,26 @@ impl<T> Rc<[T]> {
             ))
         }
     }
+
+    /// Converts the reference-counted slice into a reference-counted array.
+    ///
+    /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type.
+    ///
+    /// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
+    #[unstable(feature = "slice_as_array", issue = "133508")]
+    #[inline]
+    #[must_use]
+    pub fn into_array<const N: usize>(self) -> Option<Rc<[T; N]>> {
+        if self.len() == N {
+            let ptr = Self::into_raw(self) as *const [T; N];
+
+            // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length.
+            let me = unsafe { Rc::from_raw(ptr) };
+            Some(me)
+        } else {
+            None
+        }
+    }
 }
 
 impl<T, A: Allocator> Rc<[T], A> {
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 9be0b3e3e88..b34a6d3f660 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -1203,6 +1203,26 @@ impl<T> Arc<[T]> {
             ))
         }
     }
+
+    /// Converts the reference-counted slice into a reference-counted array.
+    ///
+    /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type.
+    ///
+    /// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
+    #[unstable(feature = "slice_as_array", issue = "133508")]
+    #[inline]
+    #[must_use]
+    pub fn into_array<const N: usize>(self) -> Option<Arc<[T; N]>> {
+        if self.len() == N {
+            let ptr = Self::into_raw(self) as *const [T; N];
+
+            // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length.
+            let me = unsafe { Arc::from_raw(ptr) };
+            Some(me)
+        } else {
+            None
+        }
+    }
 }
 
 impl<T, A: Allocator> Arc<[T], A> {
diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs
index 7a161f595f4..5f32775822b 100644
--- a/library/core/src/ffi/mod.rs
+++ b/library/core/src/ffi/mod.rs
@@ -12,10 +12,10 @@
 #[doc(inline)]
 #[stable(feature = "core_c_str", since = "1.64.0")]
 pub use self::c_str::CStr;
-#[doc(no_inline)]
+#[doc(inline)]
 #[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")]
 pub use self::c_str::FromBytesUntilNulError;
-#[doc(no_inline)]
+#[doc(inline)]
 #[stable(feature = "core_c_str", since = "1.64.0")]
 pub use self::c_str::FromBytesWithNulError;
 use crate::fmt;
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index ff39e8ac25f..91c3a4b29b5 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -3051,6 +3051,7 @@ pub trait Iterator {
     ///
     /// // we can still use `iter`, as there are more elements.
     /// assert_eq!(iter.next(), Some(&-1));
+    /// assert_eq!(iter.next_back(), Some(&3));
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index 109bc394634..56d734ba2fb 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -1446,6 +1446,11 @@ impl<K, V, const N: usize> From<[(K, V); N]> for HashMap<K, V, RandomState>
 where
     K: Eq + Hash,
 {
+    /// Converts a `[(K, V); N]` into a `HashMap<K, V>`.
+    ///
+    /// If any entries in the array have equal keys,
+    /// all but one of the corresponding values will be dropped.
+    ///
     /// # Examples
     ///
     /// ```
@@ -3219,6 +3224,10 @@ where
     K: Eq + Hash,
     S: BuildHasher + Default,
 {
+    /// Constructs a `HashMap<K, V>` from an iterator of key-value pairs.
+    ///
+    /// If the iterator produces any pairs with equal keys,
+    /// all but one of the corresponding values will be dropped.
     fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> HashMap<K, V, S> {
         let mut map = HashMap::with_hasher(Default::default());
         map.extend(iter);
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index 4c81aaff458..bcf6d6b4ccf 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -1091,6 +1091,11 @@ impl<T, const N: usize> From<[T; N]> for HashSet<T, RandomState>
 where
     T: Eq + Hash,
 {
+    /// Converts a `[T; N]` into a `HashSet<T>`.
+    ///
+    /// If the array contains any equal values,
+    /// all but one will be dropped.
+    ///
     /// # Examples
     ///
     /// ```
diff --git a/library/std/src/ffi/mod.rs b/library/std/src/ffi/mod.rs
index 469136be883..7d7cce09a3f 100644
--- a/library/std/src/ffi/mod.rs
+++ b/library/std/src/ffi/mod.rs
@@ -179,19 +179,19 @@ pub use core::ffi::{
     c_ulong, c_ulonglong, c_ushort,
 };
 
-#[doc(no_inline)]
+#[doc(inline)]
 #[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")]
 pub use self::c_str::FromBytesUntilNulError;
-#[doc(no_inline)]
+#[doc(inline)]
 #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
 pub use self::c_str::FromBytesWithNulError;
-#[doc(no_inline)]
+#[doc(inline)]
 #[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
 pub use self::c_str::FromVecWithNulError;
-#[doc(no_inline)]
+#[doc(inline)]
 #[stable(feature = "cstring_into", since = "1.7.0")]
 pub use self::c_str::IntoStringError;
-#[doc(no_inline)]
+#[doc(inline)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::c_str::NulError;
 #[doc(inline)]
diff --git a/library/std/src/sync/barrier.rs b/library/std/src/sync/barrier.rs
index 82cc13a74b7..14e4a9abe6f 100644
--- a/library/std/src/sync/barrier.rs
+++ b/library/std/src/sync/barrier.rs
@@ -10,26 +10,22 @@ use crate::sync::{Condvar, Mutex};
 /// # Examples
 ///
 /// ```
-/// use std::sync::{Arc, Barrier};
+/// use std::sync::Barrier;
 /// use std::thread;
 ///
 /// let n = 10;
-/// let mut handles = Vec::with_capacity(n);
-/// let barrier = Arc::new(Barrier::new(n));
-/// for _ in 0..n {
-///     let c = Arc::clone(&barrier);
-///     // The same messages will be printed together.
-///     // You will NOT see any interleaving.
-///     handles.push(thread::spawn(move || {
-///         println!("before wait");
-///         c.wait();
-///         println!("after wait");
-///     }));
-/// }
-/// // Wait for other threads to finish.
-/// for handle in handles {
-///     handle.join().unwrap();
-/// }
+/// let barrier = Barrier::new(n);
+/// thread::scope(|s| {
+///     for _ in 0..n {
+///         // The same messages will be printed together.
+///         // You will NOT see any interleaving.
+///         s.spawn(|| {
+///             println!("before wait");
+///             barrier.wait();
+///             println!("after wait");
+///         });
+///     }
+/// });
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Barrier {
@@ -105,26 +101,22 @@ impl Barrier {
     /// # Examples
     ///
     /// ```
-    /// use std::sync::{Arc, Barrier};
+    /// use std::sync::Barrier;
     /// use std::thread;
     ///
     /// let n = 10;
-    /// let mut handles = Vec::with_capacity(n);
-    /// let barrier = Arc::new(Barrier::new(n));
-    /// for _ in 0..n {
-    ///     let c = Arc::clone(&barrier);
-    ///     // The same messages will be printed together.
-    ///     // You will NOT see any interleaving.
-    ///     handles.push(thread::spawn(move || {
-    ///         println!("before wait");
-    ///         c.wait();
-    ///         println!("after wait");
-    ///     }));
-    /// }
-    /// // Wait for other threads to finish.
-    /// for handle in handles {
-    ///     handle.join().unwrap();
-    /// }
+    /// let barrier = Barrier::new(n);
+    /// thread::scope(|s| {
+    ///     for _ in 0..n {
+    ///         // The same messages will be printed together.
+    ///         // You will NOT see any interleaving.
+    ///         s.spawn(|| {
+    ///             println!("before wait");
+    ///             barrier.wait();
+    ///             println!("after wait");
+    ///         });
+    ///     }
+    /// });
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn wait(&self) -> BarrierWaitResult {
diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs
index 37029bcd36e..408f8020c56 100644
--- a/library/std/src/sys/pal/unix/fs.rs
+++ b/library/std/src/sys/pal/unix/fs.rs
@@ -168,7 +168,8 @@ cfg_has_statx! {{
             ) -> c_int
         }
 
-        if STATX_SAVED_STATE.load(Ordering::Relaxed) == STATX_STATE::Unavailable as u8 {
+        let statx_availability = STATX_SAVED_STATE.load(Ordering::Relaxed);
+        if statx_availability == STATX_STATE::Unavailable as u8 {
             return None;
         }
 
@@ -200,6 +201,9 @@ cfg_has_statx! {{
                 return None;
             }
         }
+        if statx_availability == STATX_STATE::Unknown as u8 {
+            STATX_SAVED_STATE.store(STATX_STATE::Present as u8, Ordering::Relaxed);
+        }
 
         // We cannot fill `stat64` exhaustively because of private padding fields.
         let mut stat: stat64 = mem::zeroed();
diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml
index 96ddae16f0a..e13c9a06c05 100644
--- a/library/unwind/Cargo.toml
+++ b/library/unwind/Cargo.toml
@@ -22,7 +22,7 @@ cfg-if = "1.0"
 libc = { version = "0.2.140", features = ['rustc-dep-of-std'], default-features = false }
 
 [target.'cfg(target_os = "xous")'.dependencies]
-unwinding = { version = "0.2.3", features = ['rustc-dep-of-std', 'unwinder', 'fde-custom'], default-features = false }
+unwinding = { version = "0.2.5", features = ['rustc-dep-of-std', 'unwinder', 'fde-custom'], default-features = false }
 
 [features]
 
diff --git a/tests/crashes/128346.rs b/tests/crashes/128346.rs
deleted file mode 100644
index 93d9c40a544..00000000000
--- a/tests/crashes/128346.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-//@ known-bug: rust-lang/rust#128346
-
-macro_rules! one_rep {
-    ( $($a:ident)* ) => {
-        A(
-            const ${concat($a, Z)}: i32 = 3;
-        )*
-    };
-}
-
-fn main() {
-    one_rep!(A B C);
-}
diff --git a/tests/ui/macros/macro-metavar-expr-concat/repetitions.rs b/tests/ui/macros/macro-metavar-expr-concat/repetitions.rs
index 781443207ac..52a7d5cd8a7 100644
--- a/tests/ui/macros/macro-metavar-expr-concat/repetitions.rs
+++ b/tests/ui/macros/macro-metavar-expr-concat/repetitions.rs
@@ -1,5 +1,3 @@
-//@ run-pass
-
 #![feature(macro_metavar_expr_concat)]
 
 macro_rules! one_rep {
@@ -10,9 +8,29 @@ macro_rules! one_rep {
     };
 }
 
+macro_rules! issue_128346 {
+    ( $($a:ident)* ) => {
+        A(
+            const ${concat($a, Z)}: i32 = 3;
+            //~^ ERROR invalid syntax
+        )*
+    };
+}
+
+macro_rules! issue_131393 {
+    ($t:ident $($en:ident)?) => {
+        read::<${concat($t, $en)}>()
+        //~^ ERROR invalid syntax
+        //~| ERROR invalid syntax
+    }
+}
+
 fn main() {
     one_rep!(A B C);
     assert_eq!(AZ, 3);
     assert_eq!(BZ, 3);
     assert_eq!(CZ, 3);
+    issue_128346!(A B C);
+    issue_131393!(u8);
+    issue_131393!(u16 le);
 }
diff --git a/tests/ui/macros/macro-metavar-expr-concat/repetitions.stderr b/tests/ui/macros/macro-metavar-expr-concat/repetitions.stderr
new file mode 100644
index 00000000000..c3006c4be5d
--- /dev/null
+++ b/tests/ui/macros/macro-metavar-expr-concat/repetitions.stderr
@@ -0,0 +1,22 @@
+error: invalid syntax
+  --> $DIR/repetitions.rs:14:20
+   |
+LL |             const ${concat($a, Z)}: i32 = 3;
+   |                    ^^^^^^^^^^^^^^^
+
+error: invalid syntax
+  --> $DIR/repetitions.rs:22:17
+   |
+LL |         read::<${concat($t, $en)}>()
+   |                 ^^^^^^^^^^^^^^^^^
+
+error: invalid syntax
+  --> $DIR/repetitions.rs:22:17
+   |
+LL |         read::<${concat($t, $en)}>()
+   |                 ^^^^^^^^^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 3 previous errors
+