Skip to content

Commit b9a37ad

Browse files
committed
Auto merge of #91776 - matthiaskrgr:rollup-tlb4bw1, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #91127 (Add `<*{const|mut} T>::{to|from}_bits`) - #91310 (Add --out-dir flag for rustdoc) - #91373 (Add needs-unwind to tests that depend on panicking) - #91426 (Make IdFunctor::try_map_id panic-safe) - #91515 (Add rsplit_array variants to slices and arrays) - #91553 (socket ancillary data implementation for dragonflybsd.) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 4a66a70 + 5da7331 commit b9a37ad

File tree

84 files changed

+561
-39
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+561
-39
lines changed

compiler/rustc_data_structures/src/functor.rs

+29-24
Original file line numberDiff line numberDiff line change
@@ -34,38 +34,43 @@ impl<T> IdFunctor for Vec<T> {
3434
type Inner = T;
3535

3636
#[inline]
37-
fn try_map_id<F, E>(mut self, mut f: F) -> Result<Self, E>
37+
fn try_map_id<F, E>(self, mut f: F) -> Result<Self, E>
3838
where
3939
F: FnMut(Self::Inner) -> Result<Self::Inner, E>,
4040
{
41-
// FIXME: We don't really care about panics here and leak
42-
// far more than we should, but that should be fine for now.
43-
let len = self.len();
44-
unsafe {
45-
self.set_len(0);
46-
let start = self.as_mut_ptr();
47-
for i in 0..len {
48-
let p = start.add(i);
49-
match f(p.read()) {
50-
Ok(val) => p.write(val),
51-
Err(err) => {
52-
// drop all other elements in self
53-
// (current element was "moved" into the call to f)
54-
for j in (0..i).chain(i + 1..len) {
55-
start.add(j).drop_in_place();
56-
}
41+
struct HoleVec<T> {
42+
vec: Vec<mem::ManuallyDrop<T>>,
43+
hole: Option<usize>,
44+
}
5745

58-
// returning will drop self, releasing the allocation
59-
// (len is 0 so elements will not be re-dropped)
60-
return Err(err);
46+
impl<T> Drop for HoleVec<T> {
47+
fn drop(&mut self) {
48+
unsafe {
49+
for (index, slot) in self.vec.iter_mut().enumerate() {
50+
if self.hole != Some(index) {
51+
mem::ManuallyDrop::drop(slot);
52+
}
6153
}
6254
}
6355
}
64-
// Even if we encountered an error, set the len back
65-
// so we don't leak memory.
66-
self.set_len(len);
6756
}
68-
Ok(self)
57+
58+
unsafe {
59+
let (ptr, length, capacity) = self.into_raw_parts();
60+
let vec = Vec::from_raw_parts(ptr.cast(), length, capacity);
61+
let mut hole_vec = HoleVec { vec, hole: None };
62+
63+
for (index, slot) in hole_vec.vec.iter_mut().enumerate() {
64+
hole_vec.hole = Some(index);
65+
let original = mem::ManuallyDrop::take(slot);
66+
let mapped = f(original)?;
67+
*slot = mem::ManuallyDrop::new(mapped);
68+
hole_vec.hole = None;
69+
}
70+
71+
mem::forget(hole_vec);
72+
Ok(Vec::from_raw_parts(ptr, length, capacity))
73+
}
6974
}
7075
}
7176

compiler/rustc_data_structures/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#![feature(once_cell)]
2424
#![feature(test)]
2525
#![feature(thread_id_value)]
26+
#![feature(vec_into_raw_parts)]
2627
#![allow(rustc::default_hash_types)]
2728
#![deny(unaligned_references)]
2829

library/core/src/array/mod.rs

+78
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,84 @@ impl<T, const N: usize> [T; N] {
645645
pub fn split_array_mut<const M: usize>(&mut self) -> (&mut [T; M], &mut [T]) {
646646
(&mut self[..]).split_array_mut::<M>()
647647
}
648+
649+
/// Divides one array reference into two at an index from the end.
650+
///
651+
/// The first will contain all indices from `[0, N - M)` (excluding
652+
/// the index `N - M` itself) and the second will contain all
653+
/// indices from `[N - M, N)` (excluding the index `N` itself).
654+
///
655+
/// # Panics
656+
///
657+
/// Panics if `M > N`.
658+
///
659+
/// # Examples
660+
///
661+
/// ```
662+
/// #![feature(split_array)]
663+
///
664+
/// let v = [1, 2, 3, 4, 5, 6];
665+
///
666+
/// {
667+
/// let (left, right) = v.rsplit_array_ref::<0>();
668+
/// assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
669+
/// assert_eq!(right, &[]);
670+
/// }
671+
///
672+
/// {
673+
/// let (left, right) = v.rsplit_array_ref::<2>();
674+
/// assert_eq!(left, &[1, 2, 3, 4]);
675+
/// assert_eq!(right, &[5, 6]);
676+
/// }
677+
///
678+
/// {
679+
/// let (left, right) = v.rsplit_array_ref::<6>();
680+
/// assert_eq!(left, &[]);
681+
/// assert_eq!(right, &[1, 2, 3, 4, 5, 6]);
682+
/// }
683+
/// ```
684+
#[unstable(
685+
feature = "split_array",
686+
reason = "return type should have array as 2nd element",
687+
issue = "90091"
688+
)]
689+
#[inline]
690+
pub fn rsplit_array_ref<const M: usize>(&self) -> (&[T], &[T; M]) {
691+
(&self[..]).rsplit_array_ref::<M>()
692+
}
693+
694+
/// Divides one mutable array reference into two at an index from the end.
695+
///
696+
/// The first will contain all indices from `[0, N - M)` (excluding
697+
/// the index `N - M` itself) and the second will contain all
698+
/// indices from `[N - M, N)` (excluding the index `N` itself).
699+
///
700+
/// # Panics
701+
///
702+
/// Panics if `M > N`.
703+
///
704+
/// # Examples
705+
///
706+
/// ```
707+
/// #![feature(split_array)]
708+
///
709+
/// let mut v = [1, 0, 3, 0, 5, 6];
710+
/// let (left, right) = v.rsplit_array_mut::<4>();
711+
/// assert_eq!(left, &mut [1, 0]);
712+
/// assert_eq!(right, &mut [3, 0, 5, 6][..]);
713+
/// left[1] = 2;
714+
/// right[1] = 4;
715+
/// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
716+
/// ```
717+
#[unstable(
718+
feature = "split_array",
719+
reason = "return type should have array as 2nd element",
720+
issue = "90091"
721+
)]
722+
#[inline]
723+
pub fn rsplit_array_mut<const M: usize>(&mut self) -> (&mut [T], &mut [T; M]) {
724+
(&mut self[..]).rsplit_array_mut::<M>()
725+
}
648726
}
649727

650728
/// Pulls `N` items from `iter` and returns them as an array. If the iterator

library/core/src/ptr/const_ptr.rs

+48
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,54 @@ impl<T: ?Sized> *const T {
4848
self as _
4949
}
5050

51+
/// Casts a pointer to its raw bits.
52+
///
53+
/// This is equivalent to `as usize`, but is more specific to enhance readability.
54+
/// The inverse method is [`from_bits`](#method.from_bits).
55+
///
56+
/// In particular, `*p as usize` and `p as usize` will both compile for
57+
/// pointers to numeric types but do very different things, so using this
58+
/// helps emphasize that reading the bits was intentional.
59+
///
60+
/// # Examples
61+
///
62+
/// ```
63+
/// #![feature(ptr_to_from_bits)]
64+
/// let array = [13, 42];
65+
/// let p0: *const i32 = &array[0];
66+
/// assert_eq!(<*const _>::from_bits(p0.to_bits()), p0);
67+
/// let p1: *const i32 = &array[1];
68+
/// assert_eq!(p1.to_bits() - p0.to_bits(), 4);
69+
/// ```
70+
#[unstable(feature = "ptr_to_from_bits", issue = "91126")]
71+
pub fn to_bits(self) -> usize
72+
where
73+
T: Sized,
74+
{
75+
self as usize
76+
}
77+
78+
/// Creates a pointer from its raw bits.
79+
///
80+
/// This is equivalent to `as *const T`, but is more specific to enhance readability.
81+
/// The inverse method is [`to_bits`](#method.to_bits).
82+
///
83+
/// # Examples
84+
///
85+
/// ```
86+
/// #![feature(ptr_to_from_bits)]
87+
/// use std::ptr::NonNull;
88+
/// let dangling: *const u8 = NonNull::dangling().as_ptr();
89+
/// assert_eq!(<*const u8>::from_bits(1), dangling);
90+
/// ```
91+
#[unstable(feature = "ptr_to_from_bits", issue = "91126")]
92+
pub fn from_bits(bits: usize) -> Self
93+
where
94+
T: Sized,
95+
{
96+
bits as Self
97+
}
98+
5199
/// Decompose a (possibly wide) pointer into its address and metadata components.
52100
///
53101
/// The pointer can be later reconstructed with [`from_raw_parts`].

library/core/src/ptr/mut_ptr.rs

+49
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,55 @@ impl<T: ?Sized> *mut T {
4747
self as _
4848
}
4949

50+
/// Casts a pointer to its raw bits.
51+
///
52+
/// This is equivalent to `as usize`, but is more specific to enhance readability.
53+
/// The inverse method is [`from_bits`](#method.from_bits-1).
54+
///
55+
/// In particular, `*p as usize` and `p as usize` will both compile for
56+
/// pointers to numeric types but do very different things, so using this
57+
/// helps emphasize that reading the bits was intentional.
58+
///
59+
/// # Examples
60+
///
61+
/// ```
62+
/// #![feature(ptr_to_from_bits)]
63+
/// let mut array = [13, 42];
64+
/// let mut it = array.iter_mut();
65+
/// let p0: *mut i32 = it.next().unwrap();
66+
/// assert_eq!(<*mut _>::from_bits(p0.to_bits()), p0);
67+
/// let p1: *mut i32 = it.next().unwrap();
68+
/// assert_eq!(p1.to_bits() - p0.to_bits(), 4);
69+
/// ```
70+
#[unstable(feature = "ptr_to_from_bits", issue = "91126")]
71+
pub fn to_bits(self) -> usize
72+
where
73+
T: Sized,
74+
{
75+
self as usize
76+
}
77+
78+
/// Creates a pointer from its raw bits.
79+
///
80+
/// This is equivalent to `as *mut T`, but is more specific to enhance readability.
81+
/// The inverse method is [`to_bits`](#method.to_bits-1).
82+
///
83+
/// # Examples
84+
///
85+
/// ```
86+
/// #![feature(ptr_to_from_bits)]
87+
/// use std::ptr::NonNull;
88+
/// let dangling: *mut u8 = NonNull::dangling().as_ptr();
89+
/// assert_eq!(<*mut u8>::from_bits(1), dangling);
90+
/// ```
91+
#[unstable(feature = "ptr_to_from_bits", issue = "91126")]
92+
pub fn from_bits(bits: usize) -> Self
93+
where
94+
T: Sized,
95+
{
96+
bits as Self
97+
}
98+
5099
/// Decompose a (possibly wide) pointer into its address and metadata components.
51100
///
52101
/// The pointer can be later reconstructed with [`from_raw_parts_mut`].

library/core/src/slice/mod.rs

+78
Original file line numberDiff line numberDiff line change
@@ -1705,6 +1705,84 @@ impl<T> [T] {
17051705
unsafe { (&mut *(a.as_mut_ptr() as *mut [T; N]), b) }
17061706
}
17071707

1708+
/// Divides one slice into an array and a remainder slice at an index from
1709+
/// the end.
1710+
///
1711+
/// The slice will contain all indices from `[0, len - N)` (excluding
1712+
/// the index `len - N` itself) and the array will contain all
1713+
/// indices from `[len - N, len)` (excluding the index `len` itself).
1714+
///
1715+
/// # Panics
1716+
///
1717+
/// Panics if `N > len`.
1718+
///
1719+
/// # Examples
1720+
///
1721+
/// ```
1722+
/// #![feature(split_array)]
1723+
///
1724+
/// let v = &[1, 2, 3, 4, 5, 6][..];
1725+
///
1726+
/// {
1727+
/// let (left, right) = v.rsplit_array_ref::<0>();
1728+
/// assert_eq!(left, [1, 2, 3, 4, 5, 6]);
1729+
/// assert_eq!(right, &[]);
1730+
/// }
1731+
///
1732+
/// {
1733+
/// let (left, right) = v.rsplit_array_ref::<2>();
1734+
/// assert_eq!(left, [1, 2, 3, 4]);
1735+
/// assert_eq!(right, &[5, 6]);
1736+
/// }
1737+
///
1738+
/// {
1739+
/// let (left, right) = v.rsplit_array_ref::<6>();
1740+
/// assert_eq!(left, []);
1741+
/// assert_eq!(right, &[1, 2, 3, 4, 5, 6]);
1742+
/// }
1743+
/// ```
1744+
#[unstable(feature = "split_array", reason = "new API", issue = "90091")]
1745+
#[inline]
1746+
pub fn rsplit_array_ref<const N: usize>(&self) -> (&[T], &[T; N]) {
1747+
assert!(N <= self.len());
1748+
let (a, b) = self.split_at(self.len() - N);
1749+
// SAFETY: b points to [T; N]? Yes it's [T] of length N (checked by split_at)
1750+
unsafe { (a, &*(b.as_ptr() as *const [T; N])) }
1751+
}
1752+
1753+
/// Divides one mutable slice into an array and a remainder slice at an
1754+
/// index from the end.
1755+
///
1756+
/// The slice will contain all indices from `[0, len - N)` (excluding
1757+
/// the index `N` itself) and the array will contain all
1758+
/// indices from `[len - N, len)` (excluding the index `len` itself).
1759+
///
1760+
/// # Panics
1761+
///
1762+
/// Panics if `N > len`.
1763+
///
1764+
/// # Examples
1765+
///
1766+
/// ```
1767+
/// #![feature(split_array)]
1768+
///
1769+
/// let mut v = &mut [1, 0, 3, 0, 5, 6][..];
1770+
/// let (left, right) = v.rsplit_array_mut::<4>();
1771+
/// assert_eq!(left, [1, 0]);
1772+
/// assert_eq!(right, &mut [3, 0, 5, 6]);
1773+
/// left[1] = 2;
1774+
/// right[1] = 4;
1775+
/// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
1776+
/// ```
1777+
#[unstable(feature = "split_array", reason = "new API", issue = "90091")]
1778+
#[inline]
1779+
pub fn rsplit_array_mut<const N: usize>(&mut self) -> (&mut [T], &mut [T; N]) {
1780+
assert!(N <= self.len());
1781+
let (a, b) = self.split_at_mut(self.len() - N);
1782+
// SAFETY: b points to [T; N]? Yes it's [T] of length N (checked by split_at_mut)
1783+
unsafe { (a, &mut *(b.as_mut_ptr() as *mut [T; N])) }
1784+
}
1785+
17081786
/// Returns an iterator over subslices separated by elements that match
17091787
/// `pred`. The matched element is not contained in the subslices.
17101788
///

0 commit comments

Comments
 (0)