Auto merge of #89703 - GuillaumeGomez:rollup-g3ulo9x, r=GuillaumeGomez

Rollup of 6 pull requests

Successful merges:

 - #75644 (Add 'core::array::from_fn' and 'core::array::try_from_fn')
 - #87528 (stack overflow handler specific openbsd change.)
 - #88436 (std: Stabilize command_access)
 - #89614 (Update to Unicode 14.0)
 - #89664 (Add documentation to boxed conversions)
 - #89700 (Fix invalid HTML generation for higher bounds)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2021-10-09 16:01:30 +00:00
commit bc8ad24020
12 changed files with 927 additions and 608 deletions

View file

@ -1277,6 +1277,7 @@ impl<T> From<T> for Box<T> {
/// from the stack into it.
///
/// # Examples
///
/// ```rust
/// let x = 5;
/// let boxed = Box::new(5);
@ -1330,6 +1331,12 @@ impl<T: Copy> From<&[T]> for Box<[T]> {
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "box_from_cow", since = "1.45.0")]
impl<T: Copy> From<Cow<'_, [T]>> for Box<[T]> {
/// Converts a `Cow<'_, [T]>` into a `Box<[T]>`
///
/// When `cow` is the `Cow::Borrowed` variant, this
/// conversion allocates on the heap and copies the
/// underlying slice. Otherwise, it will try to reuse the owned
/// `Vec`'s allocation.
#[inline]
fn from(cow: Cow<'_, [T]>) -> Box<[T]> {
match cow {
@ -1348,6 +1355,7 @@ impl From<&str> for Box<str> {
/// and performs a copy of `s`.
///
/// # Examples
///
/// ```rust
/// let boxed: Box<str> = Box::from("hello");
/// println!("{}", boxed);
@ -1361,6 +1369,29 @@ impl From<&str> for Box<str> {
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "box_from_cow", since = "1.45.0")]
impl From<Cow<'_, str>> for Box<str> {
/// Converts a `Cow<'_, str>` into a `Box<str>`
///
/// When `cow` is the `Cow::Borrowed` variant, this
/// conversion allocates on the heap and copies the
/// underlying `str`. Otherwise, it will try to reuse the owned
/// `String`'s allocation.
///
/// # Examples
///
/// ```rust
/// use std::borrow::Cow;
///
/// let unboxed = Cow::Borrowed("hello");
/// let boxed: Box<str> = Box::from(unboxed);
/// println!("{}", boxed);
/// ```
///
/// ```rust
/// # use std::borrow::Cow;
/// let unboxed = Cow::Owned("hello".to_string());
/// let boxed: Box<str> = Box::from(unboxed);
/// println!("{}", boxed);
/// ```
#[inline]
fn from(cow: Cow<'_, str>) -> Box<str> {
match cow {
@ -1403,6 +1434,7 @@ impl<T, const N: usize> From<[T; N]> for Box<[T]> {
/// This conversion moves the array to newly heap-allocated memory.
///
/// # Examples
///
/// ```rust
/// let boxed: Box<[u8]> = Box::from([4, 2]);
/// println!("{:?}", boxed);
@ -1416,6 +1448,15 @@ impl<T, const N: usize> From<[T; N]> for Box<[T]> {
impl<T, const N: usize> TryFrom<Box<[T]>> for Box<[T; N]> {
type Error = Box<[T]>;
/// Attempts to convert a `Box<[T]>` into a `Box<[T; N]>`.
///
/// The conversion occurs in-place and does not require a
/// new memory allocation.
///
/// # Errors
///
/// Returns the old `Box<[T]>` in the `Err` variant if
/// `boxed_slice.len()` does not equal `N`.
fn try_from(boxed_slice: Box<[T]>) -> Result<Self, Self::Error> {
if boxed_slice.len() == N {
Ok(unsafe { Box::from_raw(Box::into_raw(boxed_slice) as *mut [T; N]) })

View file

@ -20,6 +20,69 @@ mod iter;
#[stable(feature = "array_value_iter", since = "1.51.0")]
pub use iter::IntoIter;
/// Creates an array `[T; N]` where each array element `T` is returned by the `cb` call.
///
/// # Arguments
///
/// * `cb`: Callback where the passed argument is the current array index.
///
/// # Example
///
/// ```rust
/// #![feature(array_from_fn)]
///
/// let array = core::array::from_fn(|i| i);
/// assert_eq!(array, [0, 1, 2, 3, 4]);
/// ```
#[inline]
#[unstable(feature = "array_from_fn", issue = "89379")]
pub fn from_fn<F, T, const N: usize>(mut cb: F) -> [T; N]
where
F: FnMut(usize) -> T,
{
let mut idx = 0;
[(); N].map(|_| {
let res = cb(idx);
idx += 1;
res
})
}
/// Creates an array `[T; N]` where each fallible array element `T` is returned by the `cb` call.
/// Unlike `core::array::from_fn`, where the element creation can't fail, this version will return an error
/// if any element creation was unsuccessful.
///
/// # Arguments
///
/// * `cb`: Callback where the passed argument is the current array index.
///
/// # Example
///
/// ```rust
/// #![feature(array_from_fn)]
///
/// #[derive(Debug, PartialEq)]
/// enum SomeError {
/// Foo,
/// }
///
/// let array = core::array::try_from_fn(|i| Ok::<_, SomeError>(i));
/// assert_eq!(array, Ok([0, 1, 2, 3, 4]));
///
/// let another_array = core::array::try_from_fn::<SomeError, _, (), 2>(|_| Err(SomeError::Foo));
/// assert_eq!(another_array, Err(SomeError::Foo));
/// ```
#[inline]
#[unstable(feature = "array_from_fn", issue = "89379")]
pub fn try_from_fn<E, F, T, const N: usize>(cb: F) -> Result<[T; N], E>
where
F: FnMut(usize) -> Result<T, E>,
{
// SAFETY: we know for certain that this iterator will yield exactly `N`
// items.
unsafe { collect_into_array_rslt_unchecked(&mut (0..N).map(cb)) }
}
/// Converts a reference to `T` into a reference to an array of length 1 (without copying).
#[stable(feature = "array_from_ref", since = "1.53.0")]
pub fn from_ref<T>(s: &T) -> &[T; 1] {
@ -448,13 +511,15 @@ impl<T, const N: usize> [T; N] {
///
/// It is up to the caller to guarantee that `iter` yields at least `N` items.
/// Violating this condition causes undefined behavior.
unsafe fn collect_into_array_unchecked<I, const N: usize>(iter: &mut I) -> [I::Item; N]
unsafe fn collect_into_array_rslt_unchecked<E, I, T, const N: usize>(
iter: &mut I,
) -> Result<[T; N], E>
where
// Note: `TrustedLen` here is somewhat of an experiment. This is just an
// internal function, so feel free to remove if this bound turns out to be a
// bad idea. In that case, remember to also remove the lower bound
// `debug_assert!` below!
I: Iterator + TrustedLen,
I: Iterator<Item = Result<T, E>> + TrustedLen,
{
debug_assert!(N <= iter.size_hint().1.unwrap_or(usize::MAX));
debug_assert!(N <= iter.size_hint().0);
@ -463,6 +528,21 @@ where
unsafe { collect_into_array(iter).unwrap_unchecked() }
}
// Infallible version of `collect_into_array_rslt_unchecked`.
unsafe fn collect_into_array_unchecked<I, const N: usize>(iter: &mut I) -> [I::Item; N]
where
I: Iterator + TrustedLen,
{
let mut map = iter.map(Ok::<_, Infallible>);
// SAFETY: The same safety considerations w.r.t. the iterator length
// apply for `collect_into_array_rslt_unchecked` as for
// `collect_into_array_unchecked`
match unsafe { collect_into_array_rslt_unchecked(&mut map) } {
Ok(array) => array,
}
}
/// Pulls `N` items from `iter` and returns them as an array. If the iterator
/// yields fewer than `N` items, `None` is returned and all already yielded
/// items are dropped.
@ -473,43 +553,49 @@ where
///
/// If `iter.next()` panicks, all items already yielded by the iterator are
/// dropped.
fn collect_into_array<I, const N: usize>(iter: &mut I) -> Option<[I::Item; N]>
fn collect_into_array<E, I, T, const N: usize>(iter: &mut I) -> Option<Result<[T; N], E>>
where
I: Iterator,
I: Iterator<Item = Result<T, E>>,
{
if N == 0 {
// SAFETY: An empty array is always inhabited and has no validity invariants.
return unsafe { Some(mem::zeroed()) };
return unsafe { Some(Ok(mem::zeroed())) };
}
struct Guard<T, const N: usize> {
ptr: *mut T,
struct Guard<'a, T, const N: usize> {
array_mut: &'a mut [MaybeUninit<T>; N],
initialized: usize,
}
impl<T, const N: usize> Drop for Guard<T, N> {
impl<T, const N: usize> Drop for Guard<'_, T, N> {
fn drop(&mut self) {
debug_assert!(self.initialized <= N);
let initialized_part = crate::ptr::slice_from_raw_parts_mut(self.ptr, self.initialized);
// SAFETY: this raw slice will contain only initialized objects.
// SAFETY: this slice will contain only initialized objects.
unsafe {
crate::ptr::drop_in_place(initialized_part);
crate::ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(
&mut self.array_mut.get_unchecked_mut(..self.initialized),
));
}
}
}
let mut array = MaybeUninit::uninit_array::<N>();
let mut guard: Guard<_, N> =
Guard { ptr: MaybeUninit::slice_as_mut_ptr(&mut array), initialized: 0 };
let mut guard = Guard { array_mut: &mut array, initialized: 0 };
while let Some(item_rslt) = iter.next() {
let item = match item_rslt {
Err(err) => {
return Some(Err(err));
}
Ok(elem) => elem,
};
while let Some(item) = iter.next() {
// SAFETY: `guard.initialized` starts at 0, is increased by one in the
// loop and the loop is aborted once it reaches N (which is
// `array.len()`).
unsafe {
array.get_unchecked_mut(guard.initialized).write(item);
guard.array_mut.get_unchecked_mut(guard.initialized).write(item);
}
guard.initialized += 1;
@ -520,7 +606,7 @@ where
// SAFETY: the condition above asserts that all elements are
// initialized.
let out = unsafe { MaybeUninit::array_assume_init(array) };
return Some(out);
return Some(Ok(out));
}
}

View file

@ -44,10 +44,10 @@ pub(crate) fn is_printable(x: char) -> bool {
} else if x < 0x20000 {
check(lower, SINGLETONS1U, SINGLETONS1L, NORMAL1)
} else {
if 0x2a6de <= x && x < 0x2a700 {
if 0x2a6e0 <= x && x < 0x2a700 {
return false;
}
if 0x2b735 <= x && x < 0x2b740 {
if 0x2b739 <= x && x < 0x2b740 {
return false;
}
if 0x2b81e <= x && x < 0x2b820 {
@ -77,13 +77,13 @@ const SINGLETONS0U: &[(u8, u8)] = &[
(0x00, 1),
(0x03, 5),
(0x05, 6),
(0x06, 3),
(0x06, 2),
(0x07, 6),
(0x08, 8),
(0x08, 7),
(0x09, 17),
(0x0a, 28),
(0x0b, 25),
(0x0c, 20),
(0x0c, 26),
(0x0d, 16),
(0x0e, 13),
(0x0f, 4),
@ -91,16 +91,15 @@ const SINGLETONS0U: &[(u8, u8)] = &[
(0x12, 18),
(0x13, 9),
(0x16, 1),
(0x17, 5),
(0x18, 2),
(0x17, 4),
(0x18, 1),
(0x19, 3),
(0x1a, 7),
(0x1b, 1),
(0x1c, 2),
(0x1d, 1),
(0x1f, 22),
(0x20, 3),
(0x2b, 3),
(0x2c, 2),
(0x2d, 11),
(0x2e, 1),
(0x30, 3),
@ -112,49 +111,48 @@ const SINGLETONS0U: &[(u8, u8)] = &[
(0xab, 8),
(0xfa, 2),
(0xfb, 5),
(0xfd, 4),
(0xfd, 2),
(0xfe, 3),
(0xff, 9),
];
#[rustfmt::skip]
const SINGLETONS0L: &[u8] = &[
0xad, 0x78, 0x79, 0x8b, 0x8d, 0xa2, 0x30, 0x57,
0x58, 0x8b, 0x8c, 0x90, 0x1c, 0x1d, 0xdd, 0x0e,
0x0f, 0x4b, 0x4c, 0xfb, 0xfc, 0x2e, 0x2f, 0x3f,
0x5c, 0x5d, 0x5f, 0xb5, 0xe2, 0x84, 0x8d, 0x8e,
0x91, 0x92, 0xa9, 0xb1, 0xba, 0xbb, 0xc5, 0xc6,
0xc9, 0xca, 0xde, 0xe4, 0xe5, 0xff, 0x00, 0x04,
0x11, 0x12, 0x29, 0x31, 0x34, 0x37, 0x3a, 0x3b,
0x3d, 0x49, 0x4a, 0x5d, 0x84, 0x8e, 0x92, 0xa9,
0xb1, 0xb4, 0xba, 0xbb, 0xc6, 0xca, 0xce, 0xcf,
0xe4, 0xe5, 0x00, 0x04, 0x0d, 0x0e, 0x11, 0x12,
0x29, 0x31, 0x34, 0x3a, 0x3b, 0x45, 0x46, 0x49,
0x4a, 0x5e, 0x64, 0x65, 0x84, 0x91, 0x9b, 0x9d,
0xc9, 0xce, 0xcf, 0x0d, 0x11, 0x29, 0x45, 0x49,
0x57, 0x64, 0x65, 0x8d, 0x91, 0xa9, 0xb4, 0xba,
0xbb, 0xc5, 0xc9, 0xdf, 0xe4, 0xe5, 0xf0, 0x0d,
0x11, 0x45, 0x49, 0x64, 0x65, 0x80, 0x84, 0xb2,
0xbc, 0xbe, 0xbf, 0xd5, 0xd7, 0xf0, 0xf1, 0x83,
0x85, 0x8b, 0xa4, 0xa6, 0xbe, 0xbf, 0xc5, 0xc7,
0xce, 0xcf, 0xda, 0xdb, 0x48, 0x98, 0xbd, 0xcd,
0xc6, 0xce, 0xcf, 0x49, 0x4e, 0x4f, 0x57, 0x59,
0x5e, 0x5f, 0x89, 0x8e, 0x8f, 0xb1, 0xb6, 0xb7,
0xbf, 0xc1, 0xc6, 0xc7, 0xd7, 0x11, 0x16, 0x17,
0x5b, 0x5c, 0xf6, 0xf7, 0xfe, 0xff, 0x80, 0x0d,
0x6d, 0x71, 0xde, 0xdf, 0x0e, 0x0f, 0x1f, 0x6e,
0x6f, 0x1c, 0x1d, 0x5f, 0x7d, 0x7e, 0xae, 0xaf,
0xbb, 0xbc, 0xfa, 0x16, 0x17, 0x1e, 0x1f, 0x46,
0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5c, 0x5e, 0x7e,
0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc, 0xf0, 0xf1,
0xf5, 0x72, 0x73, 0x8f, 0x74, 0x75, 0x96, 0x2f,
0x5f, 0x26, 0x2e, 0x2f, 0xa7, 0xaf, 0xb7, 0xbf,
0x58, 0x8b, 0x8c, 0x90, 0x1c, 0xdd, 0x0e, 0x0f,
0x4b, 0x4c, 0xfb, 0xfc, 0x2e, 0x2f, 0x3f, 0x5c,
0x5d, 0x5f, 0xe2, 0x84, 0x8d, 0x8e, 0x91, 0x92,
0xa9, 0xb1, 0xba, 0xbb, 0xc5, 0xc6, 0xc9, 0xca,
0xde, 0xe4, 0xe5, 0xff, 0x00, 0x04, 0x11, 0x12,
0x29, 0x31, 0x34, 0x37, 0x3a, 0x3b, 0x3d, 0x49,
0x4a, 0x5d, 0x84, 0x8e, 0x92, 0xa9, 0xb1, 0xb4,
0xba, 0xbb, 0xc6, 0xca, 0xce, 0xcf, 0xe4, 0xe5,
0x00, 0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31,
0x34, 0x3a, 0x3b, 0x45, 0x46, 0x49, 0x4a, 0x5e,
0x64, 0x65, 0x84, 0x91, 0x9b, 0x9d, 0xc9, 0xce,
0xcf, 0x0d, 0x11, 0x29, 0x3a, 0x3b, 0x45, 0x49,
0x57, 0x5b, 0x5c, 0x5e, 0x5f, 0x64, 0x65, 0x8d,
0x91, 0xa9, 0xb4, 0xba, 0xbb, 0xc5, 0xc9, 0xdf,
0xe4, 0xe5, 0xf0, 0x0d, 0x11, 0x45, 0x49, 0x64,
0x65, 0x80, 0x84, 0xb2, 0xbc, 0xbe, 0xbf, 0xd5,
0xd7, 0xf0, 0xf1, 0x83, 0x85, 0x8b, 0xa4, 0xa6,
0xbe, 0xbf, 0xc5, 0xc7, 0xce, 0xcf, 0xda, 0xdb,
0x48, 0x98, 0xbd, 0xcd, 0xc6, 0xce, 0xcf, 0x49,
0x4e, 0x4f, 0x57, 0x59, 0x5e, 0x5f, 0x89, 0x8e,
0x8f, 0xb1, 0xb6, 0xb7, 0xbf, 0xc1, 0xc6, 0xc7,
0xd7, 0x11, 0x16, 0x17, 0x5b, 0x5c, 0xf6, 0xf7,
0xfe, 0xff, 0x80, 0x6d, 0x71, 0xde, 0xdf, 0x0e,
0x1f, 0x6e, 0x6f, 0x1c, 0x1d, 0x5f, 0x7d, 0x7e,
0xae, 0xaf, 0x7f, 0xbb, 0xbc, 0x16, 0x17, 0x1e,
0x1f, 0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5c,
0x5e, 0x7e, 0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc,
0xf0, 0xf1, 0xf5, 0x72, 0x73, 0x8f, 0x74, 0x75,
0x96, 0x26, 0x2e, 0x2f, 0xa7, 0xaf, 0xb7, 0xbf,
0xc7, 0xcf, 0xd7, 0xdf, 0x9a, 0x40, 0x97, 0x98,
0x30, 0x8f, 0x1f, 0xc0, 0xc1, 0xce, 0xff, 0x4e,
0x30, 0x8f, 0x1f, 0xd2, 0xd4, 0xce, 0xff, 0x4e,
0x4f, 0x5a, 0x5b, 0x07, 0x08, 0x0f, 0x10, 0x27,
0x2f, 0xee, 0xef, 0x6e, 0x6f, 0x37, 0x3d, 0x3f,
0x42, 0x45, 0x90, 0x91, 0xfe, 0xff, 0x53, 0x67,
0x75, 0xc8, 0xc9, 0xd0, 0xd1, 0xd8, 0xd9, 0xe7,
0xfe, 0xff,
0x42, 0x45, 0x90, 0x91, 0x53, 0x67, 0x75, 0xc8,
0xc9, 0xd0, 0xd1, 0xd8, 0xd9, 0xe7, 0xfe, 0xff,
];
#[rustfmt::skip]
const SINGLETONS1U: &[(u8, u8)] = &[
@ -162,6 +160,8 @@ const SINGLETONS1U: &[(u8, u8)] = &[
(0x01, 1),
(0x03, 1),
(0x04, 2),
(0x05, 7),
(0x07, 2),
(0x08, 8),
(0x09, 2),
(0x0a, 5),
@ -178,9 +178,11 @@ const SINGLETONS1U: &[(u8, u8)] = &[
(0x1c, 5),
(0x1d, 8),
(0x24, 1),
(0x6a, 3),
(0x6a, 4),
(0x6b, 2),
(0xaf, 3),
(0xbc, 2),
(0xcf, 2),
(0xd1, 2),
(0xd4, 12),
(0xd5, 9),
@ -189,38 +191,40 @@ const SINGLETONS1U: &[(u8, u8)] = &[
(0xda, 1),
(0xe0, 5),
(0xe1, 2),
(0xe7, 4),
(0xe8, 2),
(0xee, 32),
(0xf0, 4),
(0xf8, 2),
(0xf9, 2),
(0xfa, 2),
(0xfb, 1),
];
#[rustfmt::skip]
const SINGLETONS1L: &[u8] = &[
0x0c, 0x27, 0x3b, 0x3e, 0x4e, 0x4f, 0x8f, 0x9e,
0x9e, 0x9f, 0x06, 0x07, 0x09, 0x36, 0x3d, 0x3e,
0x56, 0xf3, 0xd0, 0xd1, 0x04, 0x14, 0x18, 0x36,
0x37, 0x56, 0x57, 0x7f, 0xaa, 0xae, 0xaf, 0xbd,
0x35, 0xe0, 0x12, 0x87, 0x89, 0x8e, 0x9e, 0x04,
0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a,
0x45, 0x46, 0x49, 0x4a, 0x4e, 0x4f, 0x64, 0x65,
0x5c, 0xb6, 0xb7, 0x1b, 0x1c, 0x07, 0x08, 0x0a,
0x0b, 0x14, 0x17, 0x36, 0x39, 0x3a, 0xa8, 0xa9,
0xd8, 0xd9, 0x09, 0x37, 0x90, 0x91, 0xa8, 0x07,
0x0a, 0x3b, 0x3e, 0x66, 0x69, 0x8f, 0x92, 0x6f,
0x5f, 0xee, 0xef, 0x5a, 0x62, 0x9a, 0x9b, 0x27,
0x28, 0x55, 0x9d, 0xa0, 0xa1, 0xa3, 0xa4, 0xa7,
0xa8, 0xad, 0xba, 0xbc, 0xc4, 0x06, 0x0b, 0x0c,
0x15, 0x1d, 0x3a, 0x3f, 0x45, 0x51, 0xa6, 0xa7,
0xcc, 0xcd, 0xa0, 0x07, 0x19, 0x1a, 0x22, 0x25,
0x3e, 0x3f, 0xc5, 0xc6, 0x04, 0x20, 0x23, 0x25,
0x26, 0x28, 0x33, 0x38, 0x3a, 0x48, 0x4a, 0x4c,
0x50, 0x53, 0x55, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
0x60, 0x63, 0x65, 0x66, 0x6b, 0x73, 0x78, 0x7d,
0x7f, 0x8a, 0xa4, 0xaa, 0xaf, 0xb0, 0xc0, 0xd0,
0xae, 0xaf, 0x79, 0xcc, 0x6e, 0x6f, 0x93,
0x9e, 0x9f, 0x7b, 0x8b, 0x93, 0x96, 0xa2, 0xb2,
0xba, 0x86, 0xb1, 0x06, 0x07, 0x09, 0x36, 0x3d,
0x3e, 0x56, 0xf3, 0xd0, 0xd1, 0x04, 0x14, 0x18,
0x36, 0x37, 0x56, 0x57, 0x7f, 0xaa, 0xae, 0xaf,
0xbd, 0x35, 0xe0, 0x12, 0x87, 0x89, 0x8e, 0x9e,
0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34,
0x3a, 0x45, 0x46, 0x49, 0x4a, 0x4e, 0x4f, 0x64,
0x65, 0x5c, 0xb6, 0xb7, 0x1b, 0x1c, 0x07, 0x08,
0x0a, 0x0b, 0x14, 0x17, 0x36, 0x39, 0x3a, 0xa8,
0xa9, 0xd8, 0xd9, 0x09, 0x37, 0x90, 0x91, 0xa8,
0x07, 0x0a, 0x3b, 0x3e, 0x66, 0x69, 0x8f, 0x92,
0x6f, 0x5f, 0xbf, 0xee, 0xef, 0x5a, 0x62, 0xf4,
0xfc, 0xff, 0x9a, 0x9b, 0x2e, 0x2f, 0x27, 0x28,
0x55, 0x9d, 0xa0, 0xa1, 0xa3, 0xa4, 0xa7, 0xa8,
0xad, 0xba, 0xbc, 0xc4, 0x06, 0x0b, 0x0c, 0x15,
0x1d, 0x3a, 0x3f, 0x45, 0x51, 0xa6, 0xa7, 0xcc,
0xcd, 0xa0, 0x07, 0x19, 0x1a, 0x22, 0x25, 0x3e,
0x3f, 0xe7, 0xec, 0xef, 0xff, 0xc5, 0xc6, 0x04,
0x20, 0x23, 0x25, 0x26, 0x28, 0x33, 0x38, 0x3a,
0x48, 0x4a, 0x4c, 0x50, 0x53, 0x55, 0x56, 0x58,
0x5a, 0x5c, 0x5e, 0x60, 0x63, 0x65, 0x66, 0x6b,
0x73, 0x78, 0x7d, 0x7f, 0x8a, 0xa4, 0xaa, 0xaf,
0xb0, 0xc0, 0xd0, 0xae, 0xaf, 0x6e, 0x6f, 0x93,
];
#[rustfmt::skip]
const NORMAL0: &[u8] = &[
@ -231,9 +235,9 @@ const NORMAL0: &[u8] = &[
0x1b, 0x04,
0x06, 0x11,
0x81, 0xac, 0x0e,
0x80, 0xab, 0x35,
0x28, 0x0b,
0x80, 0xe0, 0x03,
0x80, 0xab, 0x05,
0x1f, 0x09,
0x81, 0x1b, 0x03,
0x19, 0x08,
0x01, 0x04,
0x2f, 0x04,
@ -257,13 +261,11 @@ const NORMAL0: &[u8] = &[
0x0b, 0x06,
0x01, 0x0e,
0x15, 0x05,
0x3a, 0x03,
0x11, 0x07,
0x06, 0x05,
0x10, 0x07,
0x4e, 0x07,
0x1b, 0x07,
0x57, 0x07,
0x02, 0x07,
0x15, 0x0d,
0x02, 0x06,
0x16, 0x0d,
0x50, 0x04,
0x43, 0x03,
0x2d, 0x03,
@ -280,8 +282,8 @@ const NORMAL0: &[u8] = &[
0x1a, 0x06,
0x82, 0xfd, 0x03,
0x59, 0x07,
0x15, 0x0b,
0x17, 0x09,
0x16, 0x09,
0x18, 0x09,
0x14, 0x0c,
0x14, 0x0c,
0x6a, 0x06,
@ -299,10 +301,9 @@ const NORMAL0: &[u8] = &[
0x0b, 0x03,
0x80, 0xac, 0x06,
0x0a, 0x06,
0x21, 0x3f,
0x4c, 0x04,
0x2d, 0x03,
0x74, 0x08,
0x2f, 0x31,
0x4d, 0x03,
0x80, 0xa4, 0x08,
0x3c, 0x03,
0x0f, 0x03,
0x3c, 0x07,
@ -312,7 +313,7 @@ const NORMAL0: &[u8] = &[
0x18, 0x08,
0x2f, 0x11,
0x2d, 0x03,
0x20, 0x10,
0x21, 0x0f,
0x21, 0x0f,
0x80, 0x8c, 0x04,
0x82, 0x97, 0x19,
@ -322,19 +323,19 @@ const NORMAL0: &[u8] = &[
0x3b, 0x07,
0x02, 0x0e,
0x18, 0x09,
0x80, 0xb3, 0x2d,
0x80, 0xbe, 0x22,
0x74, 0x0c,
0x80, 0xd6, 0x1a,
0x0c, 0x05,
0x80, 0xff, 0x05,
0x80, 0xdf, 0x0c,
0xee, 0x0d, 0x03,
0x84, 0x8d, 0x03,
0xf2, 0x9d, 0x03,
0x37, 0x09,
0x81, 0x5c, 0x14,
0x80, 0xb8, 0x08,
0x80, 0xcb, 0x2a,
0x38, 0x03,
0x80, 0xcb, 0x05,
0x0a, 0x18,
0x3b, 0x03,
0x0a, 0x06,
0x38, 0x08,
0x46, 0x08,
@ -354,9 +355,9 @@ const NORMAL0: &[u8] = &[
0x81, 0xda, 0x26,
0x07, 0x0c,
0x05, 0x05,
0x80, 0xa5, 0x11,
0x81, 0x6d, 0x10,
0x78, 0x28,
0x80, 0xa6, 0x10,
0x81, 0xf5, 0x07,
0x01, 0x20,
0x2a, 0x06,
0x4c, 0x04,
0x80, 0x8d, 0x04,
@ -386,10 +387,11 @@ const NORMAL1: &[u8] = &[
0x24, 0x04,
0x28, 0x08,
0x34, 0x0b,
0x01, 0x80, 0x90,
0x4e, 0x43,
0x81, 0x37, 0x09,
0x16, 0x0a,
0x08, 0x80, 0x98,
0x08, 0x18,
0x3b, 0x45,
0x39, 0x03,
0x63, 0x08,
0x09, 0x30,
@ -417,12 +419,13 @@ const NORMAL1: &[u8] = &[
0x0a, 0x81, 0x26,
0x52, 0x4e,
0x28, 0x08,
0x2a, 0x56,
0x2a, 0x16,
0x1a, 0x26,
0x1c, 0x14,
0x17, 0x09,
0x4e, 0x04,
0x1e, 0x0f,
0x43, 0x0e,
0x24, 0x09,
0x44, 0x0d,
0x19, 0x07,
0x0a, 0x06,
0x48, 0x08,
@ -443,18 +446,18 @@ const NORMAL1: &[u8] = &[
0x45, 0x0b,
0x0a, 0x06,
0x0d, 0x13,
0x39, 0x07,
0x3a, 0x06,
0x0a, 0x36,
0x2c, 0x04,
0x10, 0x80, 0xc0,
0x17, 0x80, 0xb9,
0x3c, 0x64,
0x53, 0x0c,
0x48, 0x09,
0x0a, 0x46,
0x45, 0x1b,
0x48, 0x08,
0x53, 0x1d,
0x39, 0x81, 0x07,
0x53, 0x0d,
0x49, 0x81, 0x07,
0x46, 0x0a,
0x1d, 0x03,
0x47, 0x49,
@ -468,12 +471,13 @@ const NORMAL1: &[u8] = &[
0x32, 0x0d,
0x83, 0x9b, 0x66,
0x75, 0x0b,
0x80, 0xc4, 0x8a, 0xbc,
0x80, 0xc4, 0x8a, 0x4c,
0x63, 0x0d,
0x84, 0x2f, 0x8f, 0xd1,
0x82, 0x47, 0xa1, 0xb9,
0x82, 0x39, 0x07,
0x2a, 0x04,
0x02, 0x60,
0x5c, 0x06,
0x26, 0x0a,
0x46, 0x0a,
0x28, 0x05,
@ -486,32 +490,36 @@ const NORMAL1: &[u8] = &[
0x02, 0x0e,
0x97, 0xf8, 0x08,
0x84, 0xd6, 0x2a,
0x09, 0xa2, 0xf7,
0x81, 0x1f, 0x31,
0x09, 0xa2, 0xe7,
0x81, 0x33, 0x2d,
0x03, 0x11,
0x04, 0x08,
0x81, 0x8c, 0x89, 0x04,
0x6b, 0x05,
0x0d, 0x03,
0x09, 0x07,
0x10, 0x93, 0x60,
0x10, 0x92, 0x60,
0x47, 0x09,
0x74, 0x3c,
0x80, 0xf6, 0x0a,
0x73, 0x08,
0x6e, 0x17,
0x70, 0x15,
0x46, 0x80, 0x9a,
0x14, 0x0c,
0x57, 0x09,
0x19, 0x80, 0x87,
0x81, 0x47, 0x03,
0x85, 0x42, 0x0f,
0x15, 0x85, 0x50,
0x15, 0x84, 0x50,
0x1f, 0x80, 0xe1,
0x2b, 0x80, 0xd5,
0x2d, 0x03,
0x1a, 0x04,
0x02, 0x81, 0x70,
0x02, 0x81, 0x40,
0x1f, 0x11,
0x3a, 0x05,
0x01, 0x85, 0x00,
0x80, 0xd7, 0x29,
0x01, 0x84, 0xe0,
0x80, 0xf7, 0x29,
0x4c, 0x04,
0x0a, 0x04,
0x02, 0x83, 0x11,
@ -531,12 +539,13 @@ const NORMAL1: &[u8] = &[
0x09, 0x07,
0x02, 0x0e,
0x06, 0x80, 0x9a,
0x83, 0xd8, 0x08,
0x0d, 0x03,
0x83, 0xd8, 0x05,
0x10, 0x03,
0x0d, 0x03,
0x74, 0x0c,
0x59, 0x07,
0x0c, 0x14,
0x0c, 0x04,
0x01, 0x0f,
0x0c, 0x04,
0x38, 0x08,
0x0a, 0x06,
@ -544,12 +553,14 @@ const NORMAL1: &[u8] = &[
0x22, 0x4e,
0x81, 0x54, 0x0c,
0x15, 0x03,
0x03, 0x05,
0x05, 0x03,
0x07, 0x09,
0x19, 0x07,
0x1d, 0x03,
0x0b, 0x05,
0x06, 0x0a,
0x0a, 0x06,
0x08, 0x08,
0x07, 0x09,
0x03, 0x0d,
0x07, 0x29,
0x80, 0xcb, 0x25,
0x0a, 0x84, 0x06,
];

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,6 @@
use core::array;
use core::convert::TryFrom;
use core::sync::atomic::{AtomicUsize, Ordering};
#[test]
fn array_from_ref() {
@ -303,8 +304,6 @@ fn array_map() {
#[test]
#[should_panic(expected = "test succeeded")]
fn array_map_drop_safety() {
use core::sync::atomic::AtomicUsize;
use core::sync::atomic::Ordering;
static DROPPED: AtomicUsize = AtomicUsize::new(0);
struct DropCounter;
impl Drop for DropCounter {
@ -356,3 +355,84 @@ fn cell_allows_array_cycle() {
b3.a[0].set(Some(&b1));
b3.a[1].set(Some(&b2));
}
#[test]
fn array_from_fn() {
let array = core::array::from_fn(|idx| idx);
assert_eq!(array, [0, 1, 2, 3, 4]);
}
#[test]
fn array_try_from_fn() {
#[derive(Debug, PartialEq)]
enum SomeError {
Foo,
}
let array = core::array::try_from_fn(|i| Ok::<_, SomeError>(i));
assert_eq!(array, Ok([0, 1, 2, 3, 4]));
let another_array = core::array::try_from_fn::<SomeError, _, (), 2>(|_| Err(SomeError::Foo));
assert_eq!(another_array, Err(SomeError::Foo));
}
#[cfg(not(panic = "abort"))]
#[test]
fn array_try_from_fn_drops_inserted_elements_on_err() {
static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
struct CountDrop;
impl Drop for CountDrop {
fn drop(&mut self) {
DROP_COUNTER.fetch_add(1, Ordering::SeqCst);
}
}
let _ = catch_unwind_silent(move || {
let _: Result<[CountDrop; 4], ()> = core::array::try_from_fn(|idx| {
if idx == 2 {
return Err(());
}
Ok(CountDrop)
});
});
assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 2);
}
#[cfg(not(panic = "abort"))]
#[test]
fn array_try_from_fn_drops_inserted_elements_on_panic() {
static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
struct CountDrop;
impl Drop for CountDrop {
fn drop(&mut self) {
DROP_COUNTER.fetch_add(1, Ordering::SeqCst);
}
}
let _ = catch_unwind_silent(move || {
let _: Result<[CountDrop; 4], ()> = core::array::try_from_fn(|idx| {
if idx == 2 {
panic!("peek a boo");
}
Ok(CountDrop)
});
});
assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 2);
}
#[cfg(not(panic = "abort"))]
// https://stackoverflow.com/a/59211505
fn catch_unwind_silent<F, R>(f: F) -> std::thread::Result<R>
where
F: FnOnce() -> R + core::panic::UnwindSafe,
{
let prev_hook = std::panic::take_hook();
std::panic::set_hook(Box::new(|_| {}));
let result = std::panic::catch_unwind(f);
std::panic::set_hook(prev_hook);
result
}

View file

@ -26,6 +26,7 @@
#![feature(extern_types)]
#![feature(flt2dec)]
#![feature(fmt_internals)]
#![feature(array_from_fn)]
#![feature(hashmap_internals)]
#![feature(try_find)]
#![feature(is_sorted)]

View file

@ -115,7 +115,7 @@ use crate::path::Path;
use crate::str;
use crate::sys::pipe::{read2, AnonPipe};
use crate::sys::process as imp;
#[unstable(feature = "command_access", issue = "44434")]
#[stable(feature = "command_access", since = "1.57.0")]
pub use crate::sys_common::process::CommandEnvs;
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
@ -943,13 +943,12 @@ impl Command {
/// # Examples
///
/// ```
/// # #![feature(command_access)]
/// use std::process::Command;
///
/// let cmd = Command::new("echo");
/// assert_eq!(cmd.get_program(), "echo");
/// ```
#[unstable(feature = "command_access", issue = "44434")]
#[stable(feature = "command_access", since = "1.57.0")]
pub fn get_program(&self) -> &OsStr {
self.inner.get_program()
}
@ -963,7 +962,6 @@ impl Command {
/// # Examples
///
/// ```
/// # #![feature(command_access)]
/// use std::ffi::OsStr;
/// use std::process::Command;
///
@ -972,7 +970,7 @@ impl Command {
/// let args: Vec<&OsStr> = cmd.get_args().collect();
/// assert_eq!(args, &["first", "second"]);
/// ```
#[unstable(feature = "command_access", issue = "44434")]
#[stable(feature = "command_access", since = "1.57.0")]
pub fn get_args(&self) -> CommandArgs<'_> {
CommandArgs { inner: self.inner.get_args() }
}
@ -992,7 +990,6 @@ impl Command {
/// # Examples
///
/// ```
/// # #![feature(command_access)]
/// use std::ffi::OsStr;
/// use std::process::Command;
///
@ -1004,7 +1001,7 @@ impl Command {
/// (OsStr::new("TZ"), None)
/// ]);
/// ```
#[unstable(feature = "command_access", issue = "44434")]
#[stable(feature = "command_access", since = "1.57.0")]
pub fn get_envs(&self) -> CommandEnvs<'_> {
self.inner.get_envs()
}
@ -1016,7 +1013,6 @@ impl Command {
/// # Examples
///
/// ```
/// # #![feature(command_access)]
/// use std::path::Path;
/// use std::process::Command;
///
@ -1025,7 +1021,7 @@ impl Command {
/// cmd.current_dir("/bin");
/// assert_eq!(cmd.get_current_dir(), Some(Path::new("/bin")));
/// ```
#[unstable(feature = "command_access", issue = "44434")]
#[stable(feature = "command_access", since = "1.57.0")]
pub fn get_current_dir(&self) -> Option<&Path> {
self.inner.get_current_dir()
}
@ -1057,13 +1053,13 @@ impl AsInnerMut<imp::Command> for Command {
///
/// This struct is created by [`Command::get_args`]. See its documentation for
/// more.
#[unstable(feature = "command_access", issue = "44434")]
#[stable(feature = "command_access", since = "1.57.0")]
#[derive(Debug)]
pub struct CommandArgs<'a> {
inner: imp::CommandArgs<'a>,
}
#[unstable(feature = "command_access", issue = "44434")]
#[stable(feature = "command_access", since = "1.57.0")]
impl<'a> Iterator for CommandArgs<'a> {
type Item = &'a OsStr;
fn next(&mut self) -> Option<&'a OsStr> {
@ -1074,7 +1070,7 @@ impl<'a> Iterator for CommandArgs<'a> {
}
}
#[unstable(feature = "command_access", issue = "44434")]
#[stable(feature = "command_access", since = "1.57.0")]
impl<'a> ExactSizeIterator for CommandArgs<'a> {
fn len(&self) -> usize {
self.inner.len()

View file

@ -143,14 +143,15 @@ mod imp {
}
unsafe fn get_stackp() -> *mut libc::c_void {
let stackp = mmap(
ptr::null_mut(),
SIGSTKSZ + page_size(),
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON,
-1,
0,
);
// OpenBSD requires this flag for stack mapping
// otherwise the said mapping will fail as a no-op on most systems
// and has a different meaning on FreeBSD
#[cfg(any(target_os = "openbsd", target_os = "netbsd", target_os = "linux",))]
let flags = MAP_PRIVATE | MAP_ANON | libc::MAP_STACK;
#[cfg(not(any(target_os = "openbsd", target_os = "netbsd", target_os = "linux",)))]
let flags = MAP_PRIVATE | MAP_ANON;
let stackp =
mmap(ptr::null_mut(), SIGSTKSZ + page_size(), PROT_READ | PROT_WRITE, flags, -1, 0);
if stackp == MAP_FAILED {
panic!("failed to allocate an alternative stack: {}", io::Error::last_os_error());
}

View file

@ -106,13 +106,13 @@ impl CommandEnv {
/// This struct is created by
/// [`Command::get_envs`][crate::process::Command::get_envs]. See its
/// documentation for more.
#[unstable(feature = "command_access", issue = "44434")]
#[stable(feature = "command_access", since = "1.57.0")]
#[derive(Debug)]
pub struct CommandEnvs<'a> {
iter: crate::collections::btree_map::Iter<'a, EnvKey, Option<OsString>>,
}
#[unstable(feature = "command_access", issue = "44434")]
#[stable(feature = "command_access", since = "1.57.0")]
impl<'a> Iterator for CommandEnvs<'a> {
type Item = (&'a OsStr, Option<&'a OsStr>);
fn next(&mut self) -> Option<Self::Item> {
@ -123,7 +123,7 @@ impl<'a> Iterator for CommandEnvs<'a> {
}
}
#[unstable(feature = "command_access", issue = "44434")]
#[stable(feature = "command_access", since = "1.57.0")]
impl<'a> ExactSizeIterator for CommandEnvs<'a> {
fn len(&self) -> usize {
self.iter.len()

View file

@ -270,7 +270,7 @@ crate fn print_where_clause<'a, 'tcx: 'a>(
0 => String::new(),
_ if f.alternate() => {
format!(
"for<{:#}> ",
"for&lt;{:#}&gt; ",
comma_sep(bound_params.iter().map(|lt| lt.print()))
)
}
@ -1059,7 +1059,11 @@ impl clean::BareFunctionDecl {
) -> impl fmt::Display + 'a + Captures<'tcx> {
display_fn(move |f| {
if !self.generic_params.is_empty() {
write!(f, "for<{}> ", comma_sep(self.generic_params.iter().map(|g| g.print(cx))))
write!(
f,
"for&lt;{}&gt; ",
comma_sep(self.generic_params.iter().map(|g| g.print(cx)))
)
} else {
Ok(())
}

View file

@ -41,18 +41,26 @@ impl fmt::Debug for CharEscape {
}
}
static HEADER: &str = "
static HEADER: &str = r"
pub fn to_lower(c: char) -> [char; 3] {
match bsearch_case_table(c, LOWERCASE_TABLE) {
None => [c, '\\0', '\\0'],
Some(index) => LOWERCASE_TABLE[index].1,
if c.is_ascii() {
[(c as u8).to_ascii_lowercase() as char, '\0', '\0']
} else {
match bsearch_case_table(c, LOWERCASE_TABLE) {
None => [c, '\0', '\0'],
Some(index) => LOWERCASE_TABLE[index].1,
}
}
}
pub fn to_upper(c: char) -> [char; 3] {
match bsearch_case_table(c, UPPERCASE_TABLE) {
None => [c, '\\0', '\\0'],
Some(index) => UPPERCASE_TABLE[index].1,
if c.is_ascii() {
[(c as u8).to_ascii_uppercase() as char, '\0', '\0']
} else {
match bsearch_case_table(c, UPPERCASE_TABLE) {
None => [c, '\0', '\0'],
Some(index) => UPPERCASE_TABLE[index].1,
}
}
}

View file

@ -23,7 +23,7 @@ impl RawEmitter {
writeln!(&mut self.file).unwrap();
}
fn emit_bitset(&mut self, ranges: &[Range<u32>]) {
fn emit_bitset(&mut self, ranges: &[Range<u32>]) -> Result<(), String> {
let last_code_point = ranges.last().unwrap().end;
// bitset for every bit in the codepoint range
//
@ -44,7 +44,7 @@ impl RawEmitter {
let unique_words =
words.iter().cloned().collect::<BTreeSet<_>>().into_iter().collect::<Vec<_>>();
if unique_words.len() > u8::MAX as usize {
panic!("cannot pack {} into 8 bits", unique_words.len());
return Err(format!("cannot pack {} into 8 bits", unique_words.len()));
}
// needed for the chunk mapping to work
assert_eq!(unique_words[0], 0, "has a zero word");
@ -105,6 +105,8 @@ impl RawEmitter {
writeln!(&mut self.file, " &BITSET_MAPPING,").unwrap();
writeln!(&mut self.file, " )").unwrap();
writeln!(&mut self.file, "}}").unwrap();
Ok(())
}
fn emit_chunk_map(&mut self, zero_at: u8, compressed_words: &[u8], chunk_length: usize) {
@ -154,12 +156,12 @@ pub fn emit_codepoints(emitter: &mut RawEmitter, ranges: &[Range<u32>]) {
emitter.blank_line();
let mut bitset = emitter.clone();
bitset.emit_bitset(&ranges);
let bitset_ok = bitset.emit_bitset(&ranges).is_ok();
let mut skiplist = emitter.clone();
skiplist.emit_skiplist(&ranges);
if bitset.bytes_used <= skiplist.bytes_used {
if bitset_ok && bitset.bytes_used <= skiplist.bytes_used {
*emitter = bitset;
emitter.desc = String::from("bitset");
} else {