Skip to content

Commit 9e7656c

Browse files
committed
Allow const iterator implementations
1 parent 9cdfe03 commit 9e7656c

Some content is hidden

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

43 files changed

+705
-406
lines changed

library/core/src/array/mod.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::error::Error;
1111
use crate::fmt;
1212
use crate::hash::{self, Hash};
1313
use crate::iter::TrustedLen;
14+
use crate::marker::Destruct;
1415
use crate::mem::{self, MaybeUninit};
1516
use crate::ops::{
1617
ChangeOutputType, ControlFlow, FromResidual, Index, IndexMut, NeverShortCircuit, Residual, Try,
@@ -852,23 +853,26 @@ where
852853
/// If `iter.next()` panicks, all items already yielded by the iterator are
853854
/// dropped.
854855
#[inline]
855-
fn try_collect_into_array<I, T, R, const N: usize>(
856+
const fn try_collect_into_array<I, T, R, const N: usize>(
856857
iter: &mut I,
857858
) -> Result<R::TryType, IntoIter<T, N>>
858859
where
859-
I: Iterator,
860-
I::Item: Try<Output = T, Residual = R>,
861-
R: Residual<[T; N]>,
860+
I: ~const Iterator,
861+
I::Item: ~const Try<Output = T, Residual = R>,
862+
R: ~const Residual<[T; N]>,
863+
T: ~const Destruct,
862864
{
863865
if N == 0 {
864866
// SAFETY: An empty array is always inhabited and has no validity invariants.
865-
return Ok(Try::from_output(unsafe { mem::zeroed() }));
867+
return Ok(Try::from_output(unsafe { MaybeUninit::zeroed().assume_init() }));
866868
}
867869

868870
let mut array = MaybeUninit::uninit_array::<N>();
869871
let mut guard = Guard { array_mut: &mut array, initialized: 0 };
870872

871-
for _ in 0..N {
873+
let mut i = 0;
874+
// FIXME(const_trait_impl): replace with `for` loop
875+
while i < N {
872876
match iter.next() {
873877
Some(item_rslt) => {
874878
let item = match item_rslt.branch() {
@@ -892,6 +896,7 @@ where
892896
return Err(unsafe { IntoIter::new_unchecked(array, alive) });
893897
}
894898
}
899+
i += 1;
895900
}
896901

897902
mem::forget(guard);
@@ -952,12 +957,17 @@ impl<T, const N: usize> Drop for Guard<'_, T, N> {
952957
/// Returns the next chunk of `N` items from the iterator or errors with an
953958
/// iterator over the remainder. Used for `Iterator::next_chunk`.
954959
#[inline]
955-
pub(crate) fn iter_next_chunk<I, const N: usize>(
960+
pub(crate) const fn iter_next_chunk<I, const N: usize>(
956961
iter: &mut I,
957962
) -> Result<[I::Item; N], IntoIter<I::Item, N>>
958963
where
959-
I: Iterator,
964+
I: ~const Iterator,
965+
I::Item: ~const Destruct,
960966
{
961967
let mut map = iter.map(NeverShortCircuit);
962-
try_collect_into_array(&mut map).map(|NeverShortCircuit(arr)| arr)
968+
969+
match try_collect_into_array(&mut map) {
970+
Ok(NeverShortCircuit(x)) => Ok(x),
971+
Err(e) => Err(e),
972+
}
963973
}

library/core/src/cmp.rs

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,8 @@ pub macro PartialEq($item:item) {
281281
#[doc(alias = "!=")]
282282
#[stable(feature = "rust1", since = "1.0.0")]
283283
#[rustc_diagnostic_item = "Eq"]
284-
pub trait Eq: PartialEq<Self> {
284+
#[const_trait]
285+
pub trait Eq: ~const PartialEq<Self> {
285286
// this method is used solely by #[deriving] to assert
286287
// that every component of a type implements #[deriving]
287288
// itself, the current deriving infrastructure means doing this
@@ -331,8 +332,9 @@ pub struct AssertParamIsEq<T: Eq + ?Sized> {
331332
/// let result = 2.cmp(&1);
332333
/// assert_eq!(Ordering::Greater, result);
333334
/// ```
334-
#[derive(Clone, Copy, Eq, Debug, Hash)]
335-
#[cfg_attr(not(bootstrap), derive_const(PartialOrd, Ord, PartialEq))]
335+
#[derive(Clone, Copy, Debug, Hash)]
336+
#[cfg_attr(bootstrap, derive(Ord, Eq))]
337+
#[cfg_attr(not(bootstrap), derive_const(PartialOrd, Ord, PartialEq, Eq))]
336338
#[stable(feature = "rust1", since = "1.0.0")]
337339
#[repr(i8)]
338340
pub enum Ordering {
@@ -762,7 +764,7 @@ impl<T: Clone> Clone for Reverse<T> {
762764
#[stable(feature = "rust1", since = "1.0.0")]
763765
#[rustc_diagnostic_item = "Ord"]
764766
#[const_trait]
765-
pub trait Ord: Eq + PartialOrd<Self> {
767+
pub trait Ord: ~const Eq + ~const PartialOrd<Self> {
766768
/// This method returns an [`Ordering`] between `self` and `other`.
767769
///
768770
/// By convention, `self.cmp(&other)` returns the ordering matching the expression
@@ -892,16 +894,6 @@ impl const PartialEq for Ordering {
892894
}
893895
}
894896

895-
#[stable(feature = "rust1", since = "1.0.0")]
896-
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
897-
#[cfg(bootstrap)]
898-
impl const Ord for Ordering {
899-
#[inline]
900-
fn cmp(&self, other: &Ordering) -> Ordering {
901-
(*self as i32).cmp(&(*other as i32))
902-
}
903-
}
904-
905897
#[stable(feature = "rust1", since = "1.0.0")]
906898
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
907899
#[cfg(bootstrap)]
@@ -1231,9 +1223,8 @@ pub const fn min<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T {
12311223
#[stable(feature = "cmp_min_max_by", since = "1.53.0")]
12321224
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
12331225
pub const fn min_by<T, F: ~const FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T
1234-
where
1226+
where
12351227
T: ~const Destruct,
1236-
F: ~const Destruct,
12371228
{
12381229
match compare(&v1, &v2) {
12391230
Ordering::Less | Ordering::Equal => v1,
@@ -1318,8 +1309,6 @@ pub const fn max<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T {
13181309
pub const fn max_by<T, F: ~const FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T
13191310
where
13201311
T: ~const Destruct,
1321-
F: ~const Destruct,
1322-
{
13231312
match compare(&v1, &v2) {
13241313
Ordering::Less | Ordering::Equal => v2,
13251314
Ordering::Greater => v1,
@@ -1399,7 +1388,8 @@ mod impls {
13991388
macro_rules! eq_impl {
14001389
($($t:ty)*) => ($(
14011390
#[stable(feature = "rust1", since = "1.0.0")]
1402-
impl Eq for $t {}
1391+
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1392+
impl const Eq for $t {}
14031393
)*)
14041394
}
14051395

@@ -1523,7 +1513,8 @@ mod impls {
15231513
}
15241514

15251515
#[unstable(feature = "never_type", issue = "35121")]
1526-
impl Eq for ! {}
1516+
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1517+
impl const Eq for ! {}
15271518

15281519
#[unstable(feature = "never_type", issue = "35121")]
15291520
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]

library/core/src/iter/adapters/array_chunks.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ where
2424
I: Iterator,
2525
{
2626
#[track_caller]
27-
pub(in crate::iter) fn new(iter: I) -> Self {
27+
pub(in crate::iter) const fn new(iter: I) -> Self {
2828
assert!(N != 0, "chunk size must be non-zero");
2929
Self { iter, remainder: None }
3030
}

library/core/src/iter/adapters/by_ref_sized.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
use crate::{
2-
const_closure::ConstFnMutClosure,
3-
ops::{NeverShortCircuit, Try},
4-
};
1+
use crate::const_closure::ConstFnMutClosure;
2+
use crate::marker::Destruct;
3+
use crate::ops::{NeverShortCircuit, Try};
54

65
/// Like `Iterator::by_ref`, but requiring `Sized` so it can forward generics.
76
///
@@ -15,7 +14,7 @@ pub struct ByRefSized<'a, I>(pub &'a mut I);
1514
// to avoid accidentally calling the `&mut Iterator` implementations.
1615

1716
#[unstable(feature = "std_internals", issue = "none")]
18-
impl<I: Iterator> Iterator for ByRefSized<'_, I> {
17+
impl<I: ~const Iterator> const Iterator for ByRefSized<'_, I> {
1918
type Item = I::Item;
2019

2120
#[inline]
@@ -29,19 +28,25 @@ impl<I: Iterator> Iterator for ByRefSized<'_, I> {
2928
}
3029

3130
#[inline]
32-
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
31+
fn advance_by(&mut self, n: usize) -> Result<(), usize>
32+
where
33+
I::Item: ~const Destruct,
34+
{
3335
I::advance_by(self.0, n)
3436
}
3537

3638
#[inline]
37-
fn nth(&mut self, n: usize) -> Option<Self::Item> {
39+
fn nth(&mut self, n: usize) -> Option<Self::Item>
40+
where
41+
I::Item: ~const Destruct,
42+
{
3843
I::nth(self.0, n)
3944
}
4045

4146
#[inline]
4247
fn fold<B, F>(self, init: B, mut f: F) -> B
4348
where
44-
F: FnMut(B, Self::Item) -> B,
49+
F: ~const FnMut(B, Self::Item) -> B + ~const Destruct,
4550
{
4651
// `fold` needs ownership, so this can't forward directly.
4752
I::try_fold(self.0, init, ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp))
@@ -51,8 +56,8 @@ impl<I: Iterator> Iterator for ByRefSized<'_, I> {
5156
#[inline]
5257
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
5358
where
54-
F: FnMut(B, Self::Item) -> R,
55-
R: Try<Output = B>,
59+
F: ~const FnMut(B, Self::Item) -> R + ~const Destruct,
60+
R: ~const Try<Output = B>,
5661
{
5762
I::try_fold(self.0, init, f)
5863
}

library/core/src/iter/adapters/chain.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub struct Chain<A, B> {
3232
b: Option<B>,
3333
}
3434
impl<A, B> Chain<A, B> {
35-
pub(in super::super) fn new(a: A, b: B) -> Chain<A, B> {
35+
pub(in super::super) const fn new(a: A, b: B) -> Chain<A, B> {
3636
Chain { a: Some(a), b: Some(b) }
3737
}
3838
}

library/core/src/iter/adapters/cloned.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub struct Cloned<I> {
1919
}
2020

2121
impl<I> Cloned<I> {
22-
pub(in crate::iter) fn new(it: I) -> Cloned<I> {
22+
pub(in crate::iter) const fn new(it: I) -> Cloned<I> {
2323
Cloned { it }
2424
}
2525
}

library/core/src/iter/adapters/copied.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub struct Copied<I> {
2222
}
2323

2424
impl<I> Copied<I> {
25-
pub(in crate::iter) fn new(it: I) -> Copied<I> {
25+
pub(in crate::iter) const fn new(it: I) -> Copied<I> {
2626
Copied { it }
2727
}
2828
}

library/core/src/iter/adapters/cycle.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ pub struct Cycle<I> {
1616
}
1717

1818
impl<I: Clone> Cycle<I> {
19-
pub(in crate::iter) fn new(iter: I) -> Cycle<I> {
19+
pub(in crate::iter) const fn new(iter: I) -> Cycle<I>
20+
where
21+
I: ~const Clone,
22+
{
2023
Cycle { orig: iter.clone(), iter }
2124
}
2225
}

library/core/src/iter/adapters/enumerate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub struct Enumerate<I> {
1919
count: usize,
2020
}
2121
impl<I> Enumerate<I> {
22-
pub(in crate::iter) fn new(iter: I) -> Enumerate<I> {
22+
pub(in crate::iter) const fn new(iter: I) -> Enumerate<I> {
2323
Enumerate { iter, count: 0 }
2424
}
2525
}

library/core/src/iter/adapters/filter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub struct Filter<I, P> {
1818
predicate: P,
1919
}
2020
impl<I, P> Filter<I, P> {
21-
pub(in crate::iter) fn new(iter: I, predicate: P) -> Filter<I, P> {
21+
pub(in crate::iter) const fn new(iter: I, predicate: P) -> Filter<I, P> {
2222
Filter { iter, predicate }
2323
}
2424
}

library/core/src/iter/adapters/filter_map.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub struct FilterMap<I, F> {
1717
f: F,
1818
}
1919
impl<I, F> FilterMap<I, F> {
20-
pub(in crate::iter) fn new(iter: I, f: F) -> FilterMap<I, F> {
20+
pub(in crate::iter) const fn new(iter: I, f: F) -> FilterMap<I, F> {
2121
FilterMap { iter, f }
2222
}
2323
}

library/core/src/iter/adapters/flatten.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::fmt;
22
use crate::iter::{DoubleEndedIterator, Fuse, FusedIterator, Iterator, Map, TrustedLen};
3+
use crate::marker::Destruct;
34
use crate::ops::{ControlFlow, Try};
45

56
/// An iterator that maps each element to an iterator, and yields the elements
@@ -13,8 +14,12 @@ pub struct FlatMap<I, U: IntoIterator, F> {
1314
inner: FlattenCompat<Map<I, F>, <U as IntoIterator>::IntoIter>,
1415
}
1516

16-
impl<I: Iterator, U: IntoIterator, F: FnMut(I::Item) -> U> FlatMap<I, U, F> {
17-
pub(in crate::iter) fn new(iter: I, f: F) -> FlatMap<I, U, F> {
17+
impl<I, U: IntoIterator, F> FlatMap<I, U, F> {
18+
pub(in crate::iter) const fn new(iter: I, f: F) -> FlatMap<I, U, F>
19+
where
20+
I: ~const Iterator + ~const Destruct,
21+
F: ~const FnMut(I::Item) -> U + ~const Destruct,
22+
{
1823
FlatMap { inner: FlattenCompat::new(iter.map(f)) }
1924
}
2025
}
@@ -172,7 +177,10 @@ pub struct Flatten<I: Iterator<Item: IntoIterator>> {
172177
}
173178

174179
impl<I: Iterator<Item: IntoIterator>> Flatten<I> {
175-
pub(in super::super) fn new(iter: I) -> Flatten<I> {
180+
pub(in super::super) const fn new(iter: I) -> Flatten<I>
181+
where
182+
I: ~const Iterator,
183+
{
176184
Flatten { inner: FlattenCompat::new(iter) }
177185
}
178186
}
@@ -310,12 +318,12 @@ struct FlattenCompat<I, U> {
310318
frontiter: Option<U>,
311319
backiter: Option<U>,
312320
}
313-
impl<I, U> FlattenCompat<I, U>
314-
where
315-
I: Iterator,
316-
{
321+
impl<I, U> FlattenCompat<I, U> {
317322
/// Adapts an iterator by flattening it, for use in `flatten()` and `flat_map()`.
318-
fn new(iter: I) -> FlattenCompat<I, U> {
323+
const fn new(iter: I) -> FlattenCompat<I, U>
324+
where
325+
I: ~const Iterator,
326+
{
319327
FlattenCompat { iter: iter.fuse(), frontiter: None, backiter: None }
320328
}
321329
}

library/core/src/iter/adapters/fuse.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub struct Fuse<I> {
2121
iter: Option<I>,
2222
}
2323
impl<I> Fuse<I> {
24-
pub(in crate::iter) fn new(iter: I) -> Fuse<I> {
24+
pub(in crate::iter) const fn new(iter: I) -> Fuse<I> {
2525
Fuse { iter: Some(iter) }
2626
}
2727
}

library/core/src/iter/adapters/inspect.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub struct Inspect<I, F> {
1818
f: F,
1919
}
2020
impl<I, F> Inspect<I, F> {
21-
pub(in crate::iter) fn new(iter: I, f: F) -> Inspect<I, F> {
21+
pub(in crate::iter) const fn new(iter: I, f: F) -> Inspect<I, F> {
2222
Inspect { iter, f }
2323
}
2424
}

library/core/src/iter/adapters/intersperse.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ impl<I: Iterator> Intersperse<I>
1919
where
2020
I::Item: Clone,
2121
{
22-
pub(in crate::iter) fn new(iter: I, separator: I::Item) -> Self {
22+
pub(in crate::iter) const fn new(iter: I, separator: I::Item) -> Self
23+
where
24+
I: ~const Iterator,
25+
{
2326
Self { iter: iter.peekable(), separator, needs_sep: false }
2427
}
2528
}
@@ -103,12 +106,14 @@ where
103106
}
104107
}
105108

106-
impl<I, G> IntersperseWith<I, G>
109+
impl<I: Iterator, G> IntersperseWith<I, G>
107110
where
108-
I: Iterator,
109111
G: FnMut() -> I::Item,
110112
{
111-
pub(in crate::iter) fn new(iter: I, separator: G) -> Self {
113+
pub(in crate::iter) const fn new(iter: I, separator: G) -> Self
114+
where
115+
I: ~const Iterator,
116+
{
112117
Self { iter: iter.peekable(), separator, needs_sep: false }
113118
}
114119
}

0 commit comments

Comments
 (0)