Skip to content

Commit 57220a5

Browse files
committed
Auto merge of rust-lang#149397 - matthiaskrgr:rollup-go79y6a, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#147071 (constify from_fn, try_from_fn, try_map, map) - rust-lang#148930 (tweak editor configs) - rust-lang#149320 (-Znext-solver: normalize expected function input types when fudging) - rust-lang#149363 (Port the `#![windows_subsystem]` attribute to the new attribute system) - rust-lang#149378 (make run-make tests use 2024 edition by default) - rust-lang#149381 (Add `impl TrustedLen` on `BTree{Map,Set}` iterators) - rust-lang#149388 (remove session+blob decoder construction) - rust-lang#149390 (`rust-analyzer` subtree update) r? `@ghost` `@rustbot` modify labels: rollup
2 parents f3f1687 + 0391420 commit 57220a5

7 files changed

Lines changed: 215 additions & 96 deletions

File tree

alloc/src/collections/btree/map.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use core::cmp::Ordering;
33
use core::error::Error;
44
use core::fmt::{self, Debug};
55
use core::hash::{Hash, Hasher};
6-
use core::iter::FusedIterator;
6+
use core::iter::{FusedIterator, TrustedLen};
77
use core::marker::PhantomData;
88
use core::mem::{self, ManuallyDrop};
99
use core::ops::{Bound, Index, RangeBounds};
@@ -1624,6 +1624,9 @@ impl<K, V> ExactSizeIterator for Iter<'_, K, V> {
16241624
}
16251625
}
16261626

1627+
#[unstable(feature = "trusted_len", issue = "37572")]
1628+
unsafe impl<K, V> TrustedLen for Iter<'_, K, V> {}
1629+
16271630
#[stable(feature = "rust1", since = "1.0.0")]
16281631
impl<K, V> Clone for Iter<'_, K, V> {
16291632
fn clone(&self) -> Self {
@@ -1696,6 +1699,9 @@ impl<K, V> ExactSizeIterator for IterMut<'_, K, V> {
16961699
}
16971700
}
16981701

1702+
#[unstable(feature = "trusted_len", issue = "37572")]
1703+
unsafe impl<K, V> TrustedLen for IterMut<'_, K, V> {}
1704+
16991705
#[stable(feature = "fused", since = "1.26.0")]
17001706
impl<K, V> FusedIterator for IterMut<'_, K, V> {}
17011707

@@ -1817,6 +1823,9 @@ impl<K, V, A: Allocator + Clone> ExactSizeIterator for IntoIter<K, V, A> {
18171823
}
18181824
}
18191825

1826+
#[unstable(feature = "trusted_len", issue = "37572")]
1827+
unsafe impl<K, V, A: Allocator + Clone> TrustedLen for IntoIter<K, V, A> {}
1828+
18201829
#[stable(feature = "fused", since = "1.26.0")]
18211830
impl<K, V, A: Allocator + Clone> FusedIterator for IntoIter<K, V, A> {}
18221831

@@ -1865,6 +1874,9 @@ impl<K, V> ExactSizeIterator for Keys<'_, K, V> {
18651874
}
18661875
}
18671876

1877+
#[unstable(feature = "trusted_len", issue = "37572")]
1878+
unsafe impl<K, V> TrustedLen for Keys<'_, K, V> {}
1879+
18681880
#[stable(feature = "fused", since = "1.26.0")]
18691881
impl<K, V> FusedIterator for Keys<'_, K, V> {}
18701882

@@ -1920,6 +1932,9 @@ impl<K, V> ExactSizeIterator for Values<'_, K, V> {
19201932
}
19211933
}
19221934

1935+
#[unstable(feature = "trusted_len", issue = "37572")]
1936+
unsafe impl<K, V> TrustedLen for Values<'_, K, V> {}
1937+
19231938
#[stable(feature = "fused", since = "1.26.0")]
19241939
impl<K, V> FusedIterator for Values<'_, K, V> {}
19251940

@@ -2160,6 +2175,9 @@ impl<K, V> ExactSizeIterator for ValuesMut<'_, K, V> {
21602175
}
21612176
}
21622177

2178+
#[unstable(feature = "trusted_len", issue = "37572")]
2179+
unsafe impl<K, V> TrustedLen for ValuesMut<'_, K, V> {}
2180+
21632181
#[stable(feature = "fused", since = "1.26.0")]
21642182
impl<K, V> FusedIterator for ValuesMut<'_, K, V> {}
21652183

@@ -2222,6 +2240,9 @@ impl<K, V, A: Allocator + Clone> ExactSizeIterator for IntoKeys<K, V, A> {
22222240
}
22232241
}
22242242

2243+
#[unstable(feature = "trusted_len", issue = "37572")]
2244+
unsafe impl<K, V, A: Allocator + Clone> TrustedLen for IntoKeys<K, V, A> {}
2245+
22252246
#[stable(feature = "map_into_keys_values", since = "1.54.0")]
22262247
impl<K, V, A: Allocator + Clone> FusedIterator for IntoKeys<K, V, A> {}
22272248

@@ -2273,6 +2294,9 @@ impl<K, V, A: Allocator + Clone> ExactSizeIterator for IntoValues<K, V, A> {
22732294
}
22742295
}
22752296

2297+
#[unstable(feature = "trusted_len", issue = "37572")]
2298+
unsafe impl<K, V, A: Allocator + Clone> TrustedLen for IntoValues<K, V, A> {}
2299+
22762300
#[stable(feature = "map_into_keys_values", since = "1.54.0")]
22772301
impl<K, V, A: Allocator + Clone> FusedIterator for IntoValues<K, V, A> {}
22782302

alloc/src/collections/btree/set.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use core::cmp::Ordering::{self, Equal, Greater, Less};
33
use core::cmp::{max, min};
44
use core::fmt::{self, Debug};
55
use core::hash::{Hash, Hasher};
6-
use core::iter::{FusedIterator, Peekable};
6+
use core::iter::{FusedIterator, Peekable, TrustedLen};
77
use core::mem::ManuallyDrop;
88
use core::ops::{BitAnd, BitOr, BitXor, Bound, RangeBounds, Sub};
99

@@ -1753,6 +1753,7 @@ impl<T> Clone for Iter<'_, T> {
17531753
Iter { iter: self.iter.clone() }
17541754
}
17551755
}
1756+
17561757
#[stable(feature = "rust1", since = "1.0.0")]
17571758
impl<'a, T> Iterator for Iter<'a, T> {
17581759
type Item = &'a T;
@@ -1783,19 +1784,24 @@ impl<'a, T> Iterator for Iter<'a, T> {
17831784
self.next_back()
17841785
}
17851786
}
1787+
17861788
#[stable(feature = "rust1", since = "1.0.0")]
17871789
impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
17881790
fn next_back(&mut self) -> Option<&'a T> {
17891791
self.iter.next_back()
17901792
}
17911793
}
1794+
17921795
#[stable(feature = "rust1", since = "1.0.0")]
17931796
impl<T> ExactSizeIterator for Iter<'_, T> {
17941797
fn len(&self) -> usize {
17951798
self.iter.len()
17961799
}
17971800
}
17981801

1802+
#[unstable(feature = "trusted_len", issue = "37572")]
1803+
unsafe impl<T> TrustedLen for Iter<'_, T> {}
1804+
17991805
#[stable(feature = "fused", since = "1.26.0")]
18001806
impl<T> FusedIterator for Iter<'_, T> {}
18011807

@@ -1832,13 +1838,17 @@ impl<T, A: Allocator + Clone> DoubleEndedIterator for IntoIter<T, A> {
18321838
self.iter.next_back().map(|(k, _)| k)
18331839
}
18341840
}
1841+
18351842
#[stable(feature = "rust1", since = "1.0.0")]
18361843
impl<T, A: Allocator + Clone> ExactSizeIterator for IntoIter<T, A> {
18371844
fn len(&self) -> usize {
18381845
self.iter.len()
18391846
}
18401847
}
18411848

1849+
#[unstable(feature = "trusted_len", issue = "37572")]
1850+
unsafe impl<T, A: Allocator + Clone> TrustedLen for IntoIter<T, A> {}
1851+
18421852
#[stable(feature = "fused", since = "1.26.0")]
18431853
impl<T, A: Allocator + Clone> FusedIterator for IntoIter<T, A> {}
18441854

core/src/array/drain.rs

Lines changed: 94 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,108 @@
1-
use crate::iter::{TrustedLen, UncheckedIterator};
2-
use crate::mem::ManuallyDrop;
3-
use crate::ptr::drop_in_place;
4-
use crate::slice;
1+
use crate::marker::{Destruct, PhantomData};
2+
use crate::mem::{ManuallyDrop, SizedTypeProperties, conjure_zst};
3+
use crate::ptr::{NonNull, drop_in_place, from_raw_parts_mut, null_mut};
54

6-
/// A situationally-optimized version of `array.into_iter().for_each(func)`.
7-
///
8-
/// [`crate::array::IntoIter`]s are great when you need an owned iterator, but
9-
/// storing the entire array *inside* the iterator like that can sometimes
10-
/// pessimize code. Notable, it can be more bytes than you really want to move
11-
/// around, and because the array accesses index into it SRoA has a harder time
12-
/// optimizing away the type than it does iterators that just hold a couple pointers.
13-
///
14-
/// Thus this function exists, which gives a way to get *moved* access to the
15-
/// elements of an array using a small iterator -- no bigger than a slice iterator.
16-
///
17-
/// The function-taking-a-closure structure makes it safe, as it keeps callers
18-
/// from looking at already-dropped elements.
19-
pub(crate) fn drain_array_with<T, R, const N: usize>(
20-
array: [T; N],
21-
func: impl for<'a> FnOnce(Drain<'a, T>) -> R,
22-
) -> R {
23-
let mut array = ManuallyDrop::new(array);
24-
// SAFETY: Now that the local won't drop it, it's ok to construct the `Drain` which will.
25-
let drain = Drain(array.iter_mut());
26-
func(drain)
5+
impl<'l, 'f, T, U, const N: usize, F: FnMut(T) -> U> Drain<'l, 'f, T, N, F> {
6+
/// This function returns a function that lets you index the given array in const.
7+
/// As implemented it can optimize better than iterators, and can be constified.
8+
/// It acts like a sort of guard (owns the array) and iterator combined, which can be implemented
9+
/// as it is a struct that implements const fn;
10+
/// in that regard it is somewhat similar to an array::Iter implementing `UncheckedIterator`.
11+
/// The only method you're really allowed to call is `next()`,
12+
/// anything else is more or less UB, hence this function being unsafe.
13+
/// Moved elements will not be dropped.
14+
/// This will also not actually store the array.
15+
///
16+
/// SAFETY: must only be called `N` times. Thou shalt not drop the array either.
17+
// FIXME(const-hack): this is a hack for `let guard = Guard(array); |i| f(guard[i])`.
18+
#[rustc_const_unstable(feature = "array_try_map", issue = "79711")]
19+
pub(super) const unsafe fn new(array: &'l mut ManuallyDrop<[T; N]>, f: &'f mut F) -> Self {
20+
// dont drop the array, transfers "ownership" to Self
21+
let ptr: NonNull<T> = NonNull::from_mut(array).cast();
22+
// SAFETY:
23+
// Adding `slice.len()` to the starting pointer gives a pointer
24+
// at the end of `slice`. `end` will never be dereferenced, only checked
25+
// for direct pointer equality with `ptr` to check if the drainer is done.
26+
unsafe {
27+
let end = if T::IS_ZST { null_mut() } else { ptr.as_ptr().add(N) };
28+
Self { ptr, end, f, l: PhantomData }
29+
}
30+
}
2731
}
2832

29-
/// See [`drain_array_with`] -- this is `pub(crate)` only so it's allowed to be
30-
/// mentioned in the signature of that method. (Otherwise it hits `E0446`.)
31-
// INVARIANT: It's ok to drop the remainder of the inner iterator.
32-
pub(crate) struct Drain<'a, T>(slice::IterMut<'a, T>);
33+
/// See [`Drain::new`]; this is our fake iterator.
34+
#[rustc_const_unstable(feature = "array_try_map", issue = "79711")]
35+
#[unstable(feature = "array_try_map", issue = "79711")]
36+
pub(super) struct Drain<'l, 'f, T, const N: usize, F> {
37+
// FIXME(const-hack): This is essentially a slice::IterMut<'static>, replace when possible.
38+
/// The pointer to the next element to return, or the past-the-end location
39+
/// if the drainer is empty.
40+
///
41+
/// This address will be used for all ZST elements, never changed.
42+
/// As we "own" this array, we dont need to store any lifetime.
43+
ptr: NonNull<T>,
44+
/// For non-ZSTs, the non-null pointer to the past-the-end element.
45+
/// For ZSTs, this is null.
46+
end: *mut T,
3347

34-
impl<T> Drop for Drain<'_, T> {
35-
fn drop(&mut self) {
36-
// SAFETY: By the type invariant, we're allowed to drop all these.
37-
unsafe { drop_in_place(self.0.as_mut_slice()) }
38-
}
48+
f: &'f mut F,
49+
l: PhantomData<&'l mut [T; N]>,
3950
}
4051

41-
impl<T> Iterator for Drain<'_, T> {
42-
type Item = T;
43-
44-
#[inline]
45-
fn next(&mut self) -> Option<T> {
46-
let p: *const T = self.0.next()?;
47-
// SAFETY: The iterator was already advanced, so we won't drop this later.
48-
Some(unsafe { p.read() })
49-
}
52+
#[rustc_const_unstable(feature = "array_try_map", issue = "79711")]
53+
#[unstable(feature = "array_try_map", issue = "79711")]
54+
impl<T, U, const N: usize, F> const FnOnce<(usize,)> for &mut Drain<'_, '_, T, N, F>
55+
where
56+
F: [const] FnMut(T) -> U,
57+
{
58+
type Output = U;
5059

51-
#[inline]
52-
fn size_hint(&self) -> (usize, Option<usize>) {
53-
let n = self.len();
54-
(n, Some(n))
60+
/// This implementation is useless.
61+
extern "rust-call" fn call_once(mut self, args: (usize,)) -> Self::Output {
62+
self.call_mut(args)
5563
}
5664
}
57-
58-
impl<T> ExactSizeIterator for Drain<'_, T> {
59-
#[inline]
60-
fn len(&self) -> usize {
61-
self.0.len()
65+
#[rustc_const_unstable(feature = "array_try_map", issue = "79711")]
66+
#[unstable(feature = "array_try_map", issue = "79711")]
67+
impl<T, U, const N: usize, F> const FnMut<(usize,)> for &mut Drain<'_, '_, T, N, F>
68+
where
69+
F: [const] FnMut(T) -> U,
70+
{
71+
// FIXME(const-hack): ideally this would be an unsafe fn `next()`, and to use it you would instead `|_| unsafe { drain.next() }`.
72+
extern "rust-call" fn call_mut(
73+
&mut self,
74+
(_ /* ignore argument */,): (usize,),
75+
) -> Self::Output {
76+
if T::IS_ZST {
77+
// its UB to call this more than N times, so returning more ZSTs is valid.
78+
// SAFETY: its a ZST? we conjur.
79+
(self.f)(unsafe { conjure_zst::<T>() })
80+
} else {
81+
// increment before moving; if `f` panics, we drop the rest.
82+
let p = self.ptr;
83+
// SAFETY: caller guarantees never called more than N times (see `Drain::new`)
84+
self.ptr = unsafe { self.ptr.add(1) };
85+
// SAFETY: we are allowed to move this.
86+
(self.f)(unsafe { p.read() })
87+
}
6288
}
6389
}
90+
#[rustc_const_unstable(feature = "array_try_map", issue = "79711")]
91+
#[unstable(feature = "array_try_map", issue = "79711")]
92+
impl<T: [const] Destruct, const N: usize, F> const Drop for Drain<'_, '_, T, N, F> {
93+
fn drop(&mut self) {
94+
if !T::IS_ZST {
95+
// SAFETY: we cant read more than N elements
96+
let slice = unsafe {
97+
from_raw_parts_mut::<[T]>(
98+
self.ptr.as_ptr(),
99+
// SAFETY: `start <= end`
100+
self.end.offset_from_unsigned(self.ptr.as_ptr()),
101+
)
102+
};
64103

65-
// SAFETY: This is a 1:1 wrapper for a slice iterator, which is also `TrustedLen`.
66-
unsafe impl<T> TrustedLen for Drain<'_, T> {}
67-
68-
impl<T> UncheckedIterator for Drain<'_, T> {
69-
unsafe fn next_unchecked(&mut self) -> T {
70-
// SAFETY: `Drain` is 1:1 with the inner iterator, so if the caller promised
71-
// that there's an element left, the inner iterator has one too.
72-
let p: *const T = unsafe { self.0.next_unchecked() };
73-
// SAFETY: The iterator was already advanced, so we won't drop this later.
74-
unsafe { p.read() }
104+
// SAFETY: By the type invariant, we're allowed to drop all these. (we own it, after all)
105+
unsafe { drop_in_place(slice) }
106+
}
75107
}
76108
}

0 commit comments

Comments
 (0)