Skip to content

Commit

Permalink
Auto merge of #95798 - Dylan-DPC:rollup-51hx1wl, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 7 pull requests

Successful merges:

 - #95102 (Add known-bug for #95034)
 - #95579 (Add `<[[T; N]]>::flatten{_mut}`)
 - #95634 (Mailmap update)
 - #95705 (Promote x86_64-unknown-none target to Tier 2 and distribute build artifacts)
 - #95761 (Kickstart the inner usage of `macro_metavar_expr`)
 - #95782 (Windows: Increase a pipe's buffer capacity to 64kb)
 - #95791 (hide an #[allow] directive from the Arc::new_cyclic doc example)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Apr 8, 2022
2 parents 6e336a0 + 38be9f8 commit dea6a76
Show file tree
Hide file tree
Showing 11 changed files with 184 additions and 119 deletions.
1 change: 1 addition & 0 deletions alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
#![feature(trusted_len)]
#![feature(trusted_random_access)]
#![feature(try_trait_v2)]
#![feature(unchecked_math)]
#![feature(unicode_internals)]
#![feature(unsize)]
//
Expand Down
2 changes: 1 addition & 1 deletion alloc/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ impl<T> Arc<T> {
///
/// # Example
/// ```
/// #![allow(dead_code)]
/// # #![allow(dead_code)]
/// use std::sync::{Arc, Weak};
///
/// struct Gadget {
Expand Down
45 changes: 45 additions & 0 deletions alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2274,6 +2274,51 @@ impl<T: Clone, A: Allocator> Vec<T, A> {
}
}

impl<T, A: Allocator, const N: usize> Vec<[T; N], A> {
/// Takes a `Vec<[T; N]>` and flattens it into a `Vec<T>`.
///
/// # Panics
///
/// Panics if the length of the resulting vector would overflow a `usize`.
///
/// This is only possible when flattening a vector of arrays of zero-sized
/// types, and thus tends to be irrelevant in practice. If
/// `size_of::<T>() > 0`, this will never panic.
///
/// # Examples
///
/// ```
/// #![feature(slice_flatten)]
///
/// let mut vec = vec![[1, 2, 3], [4, 5, 6], [7, 8, 9]];
/// assert_eq!(vec.pop(), Some([7, 8, 9]));
///
/// let mut flattened = vec.into_flattened();
/// assert_eq!(flattened.pop(), Some(6));
/// ```
#[unstable(feature = "slice_flatten", issue = "95629")]
pub fn into_flattened(self) -> Vec<T, A> {
let (ptr, len, cap, alloc) = self.into_raw_parts_with_alloc();
let (new_len, new_cap) = if mem::size_of::<T>() == 0 {
(len.checked_mul(N).expect("vec len overflow"), usize::MAX)
} else {
// SAFETY:
// - `cap * N` cannot overflow because the allocation is already in
// the address space.
// - Each `[T; N]` has `N` valid elements, so there are `len * N`
// valid elements in the allocation.
unsafe { (len.unchecked_mul(N), cap.unchecked_mul(N)) }
};
// SAFETY:
// - `ptr` was allocated by `self`
// - `ptr` is well-aligned because `[T; N]` has the same alignment as `T`.
// - `new_cap` refers to the same sized allocation as `cap` because
// `new_cap * size_of::<T>()` == `cap * size_of::<[T; N]>()`
// - `len` <= `cap`, so `len * N` <= `cap * N`.
unsafe { Vec::<T, A>::from_raw_parts_in(ptr.cast(), new_len, new_cap, alloc) }
}
}

// This code generalizes `extend_with_{element,default}`.
trait ExtendWith<T> {
fn next(&mut self) -> T;
Expand Down
1 change: 1 addition & 0 deletions alloc/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#![feature(const_str_from_utf8)]
#![feature(nonnull_slice_from_raw_parts)]
#![feature(panic_update_hook)]
#![feature(slice_flatten)]

use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
Expand Down
7 changes: 7 additions & 0 deletions alloc/tests/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2408,3 +2408,10 @@ fn test_extend_from_within_panicing_clone() {

assert_eq!(count.load(Ordering::SeqCst), 4);
}

#[test]
#[should_panic = "vec len overflow"]
fn test_into_flattened_size_overflow() {
let v = vec![[(); usize::MAX]; 2];
let _ = v.into_flattened();
}
1 change: 1 addition & 0 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@
#![feature(intrinsics)]
#![feature(lang_items)]
#![feature(link_llvm_intrinsics)]
#![feature(macro_metavar_expr)]
#![feature(min_specialization)]
#![feature(mixed_integer_ops)]
#![feature(must_not_suspend)]
Expand Down
82 changes: 82 additions & 0 deletions core/src/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3992,6 +3992,88 @@ impl<T> [T] {
}
}

#[cfg(not(bootstrap))]
impl<T, const N: usize> [[T; N]] {
/// Takes a `&[[T; N]]`, and flattens it to a `&[T]`.
///
/// # Panics
///
/// This panics if the length of the resulting slice would overflow a `usize`.
///
/// This is only possible when flattening a slice of arrays of zero-sized
/// types, and thus tends to be irrelevant in practice. If
/// `size_of::<T>() > 0`, this will never panic.
///
/// # Examples
///
/// ```
/// #![feature(slice_flatten)]
///
/// assert_eq!([[1, 2, 3], [4, 5, 6]].flatten(), &[1, 2, 3, 4, 5, 6]);
///
/// assert_eq!(
/// [[1, 2, 3], [4, 5, 6]].flatten(),
/// [[1, 2], [3, 4], [5, 6]].flatten(),
/// );
///
/// let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
/// assert!(slice_of_empty_arrays.flatten().is_empty());
///
/// let empty_slice_of_arrays: &[[u32; 10]] = &[];
/// assert!(empty_slice_of_arrays.flatten().is_empty());
/// ```
#[unstable(feature = "slice_flatten", issue = "95629")]
pub fn flatten(&self) -> &[T] {
let len = if crate::mem::size_of::<T>() == 0 {
self.len().checked_mul(N).expect("slice len overflow")
} else {
// SAFETY: `self.len() * N` cannot overflow because `self` is
// already in the address space.
unsafe { self.len().unchecked_mul(N) }
};
// SAFETY: `[T]` is layout-identical to `[T; N]`
unsafe { from_raw_parts(self.as_ptr().cast(), len) }
}

/// Takes a `&mut [[T; N]]`, and flattens it to a `&mut [T]`.
///
/// # Panics
///
/// This panics if the length of the resulting slice would overflow a `usize`.
///
/// This is only possible when flattening a slice of arrays of zero-sized
/// types, and thus tends to be irrelevant in practice. If
/// `size_of::<T>() > 0`, this will never panic.
///
/// # Examples
///
/// ```
/// #![feature(slice_flatten)]
///
/// fn add_5_to_all(slice: &mut [i32]) {
/// for i in slice {
/// *i += 5;
/// }
/// }
///
/// let mut array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
/// add_5_to_all(array.flatten_mut());
/// assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
/// ```
#[unstable(feature = "slice_flatten", issue = "95629")]
pub fn flatten_mut(&mut self) -> &mut [T] {
let len = if crate::mem::size_of::<T>() == 0 {
self.len().checked_mul(N).expect("slice len overflow")
} else {
// SAFETY: `self.len() * N` cannot overflow because `self` is
// already in the address space.
unsafe { self.len().unchecked_mul(N) }
};
// SAFETY: `[T]` is layout-identical to `[T; N]`
unsafe { from_raw_parts_mut(self.as_mut_ptr().cast(), len) }
}
}

trait CloneFromSpec<T> {
fn spec_clone_from(&mut self, src: &[T]);
}
Expand Down
140 changes: 24 additions & 116 deletions core/src/tuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,17 @@ use crate::cmp::*;

// macro for implementing n-ary tuple functions and operations
macro_rules! tuple_impls {
($(
$Tuple:ident {
$(($idx:tt) -> $T:ident)+
}
)+) => {
( $( $Tuple:ident( $( $T:ident )+ ) )+ ) => {
$(
#[stable(feature = "rust1", since = "1.0.0")]
impl<$($T:PartialEq),+> PartialEq for ($($T,)+) where last_type!($($T,)+): ?Sized {
#[inline]
fn eq(&self, other: &($($T,)+)) -> bool {
$(self.$idx == other.$idx)&&+
$( ${ignore(T)} self.${index()} == other.${index()} )&&+
}
#[inline]
fn ne(&self, other: &($($T,)+)) -> bool {
$(self.$idx != other.$idx)||+
$( ${ignore(T)} self.${index()} != other.${index()} )||+
}
}

Expand All @@ -28,34 +24,36 @@ macro_rules! tuple_impls {

#[stable(feature = "rust1", since = "1.0.0")]
impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+)
where last_type!($($T,)+): ?Sized {
where
last_type!($($T,)+): ?Sized
{
#[inline]
fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
lexical_partial_cmp!($(self.$idx, other.$idx),+)
lexical_partial_cmp!($( ${ignore(T)} self.${index()}, other.${index()} ),+)
}
#[inline]
fn lt(&self, other: &($($T,)+)) -> bool {
lexical_ord!(lt, $(self.$idx, other.$idx),+)
lexical_ord!(lt, $( ${ignore(T)} self.${index()}, other.${index()} ),+)
}
#[inline]
fn le(&self, other: &($($T,)+)) -> bool {
lexical_ord!(le, $(self.$idx, other.$idx),+)
lexical_ord!(le, $( ${ignore(T)} self.${index()}, other.${index()} ),+)
}
#[inline]
fn ge(&self, other: &($($T,)+)) -> bool {
lexical_ord!(ge, $(self.$idx, other.$idx),+)
lexical_ord!(ge, $( ${ignore(T)} self.${index()}, other.${index()} ),+)
}
#[inline]
fn gt(&self, other: &($($T,)+)) -> bool {
lexical_ord!(gt, $(self.$idx, other.$idx),+)
lexical_ord!(gt, $( ${ignore(T)} self.${index()}, other.${index()} ),+)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<$($T:Ord),+> Ord for ($($T,)+) where last_type!($($T,)+): ?Sized {
#[inline]
fn cmp(&self, other: &($($T,)+)) -> Ordering {
lexical_cmp!($(self.$idx, other.$idx),+)
lexical_cmp!($( ${ignore(T)} self.${index()}, other.${index()} ),+)
}
}

Expand Down Expand Up @@ -108,106 +106,16 @@ macro_rules! last_type {
}

tuple_impls! {
Tuple1 {
(0) -> A
}
Tuple2 {
(0) -> A
(1) -> B
}
Tuple3 {
(0) -> A
(1) -> B
(2) -> C
}
Tuple4 {
(0) -> A
(1) -> B
(2) -> C
(3) -> D
}
Tuple5 {
(0) -> A
(1) -> B
(2) -> C
(3) -> D
(4) -> E
}
Tuple6 {
(0) -> A
(1) -> B
(2) -> C
(3) -> D
(4) -> E
(5) -> F
}
Tuple7 {
(0) -> A
(1) -> B
(2) -> C
(3) -> D
(4) -> E
(5) -> F
(6) -> G
}
Tuple8 {
(0) -> A
(1) -> B
(2) -> C
(3) -> D
(4) -> E
(5) -> F
(6) -> G
(7) -> H
}
Tuple9 {
(0) -> A
(1) -> B
(2) -> C
(3) -> D
(4) -> E
(5) -> F
(6) -> G
(7) -> H
(8) -> I
}
Tuple10 {
(0) -> A
(1) -> B
(2) -> C
(3) -> D
(4) -> E
(5) -> F
(6) -> G
(7) -> H
(8) -> I
(9) -> J
}
Tuple11 {
(0) -> A
(1) -> B
(2) -> C
(3) -> D
(4) -> E
(5) -> F
(6) -> G
(7) -> H
(8) -> I
(9) -> J
(10) -> K
}
Tuple12 {
(0) -> A
(1) -> B
(2) -> C
(3) -> D
(4) -> E
(5) -> F
(6) -> G
(7) -> H
(8) -> I
(9) -> J
(10) -> K
(11) -> L
}
Tuple1(A)
Tuple2(A B)
Tuple3(A B C)
Tuple4(A B C D)
Tuple5(A B C D E)
Tuple6(A B C D E F)
Tuple7(A B C D E F G)
Tuple8(A B C D E F G H)
Tuple9(A B C D E F G H I)
Tuple10(A B C D E F G H I J)
Tuple11(A B C D E F G H I J K)
Tuple12(A B C D E F G H I J K L)
}
1 change: 1 addition & 0 deletions core/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
#![feature(const_array_from_ref)]
#![feature(const_slice_from_ref)]
#![feature(waker_getters)]
#![feature(slice_flatten)]
#![deny(unsafe_op_in_unsafe_fn)]

extern crate test;
Expand Down
Loading

0 comments on commit dea6a76

Please sign in to comment.