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
This commit is contained in:
commit
207ed1b185
18 changed files with 175 additions and 63 deletions
|
@ -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) => {
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
///
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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")]
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
///
|
||||
/// ```
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
22
tests/ui/macros/macro-metavar-expr-concat/repetitions.stderr
Normal file
22
tests/ui/macros/macro-metavar-expr-concat/repetitions.stderr
Normal file
|
@ -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
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue