Skip to content

Commit cc4c7b7

Browse files
committed
Make it possible to have const impls for Iterator
1 parent a34c079 commit cc4c7b7

38 files changed

+883
-344
lines changed

library/core/src/cmp.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,7 +1192,13 @@ pub fn min<T: Ord>(v1: T, v2: T) -> T {
11921192
#[inline]
11931193
#[must_use]
11941194
#[stable(feature = "cmp_min_max_by", since = "1.53.0")]
1195-
pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
1195+
#[rustc_const_unstable(feature = "const_cmp", issue = "none")]
1196+
pub const fn min_by<T, F>(v1: T, v2: T, compare: F) -> T
1197+
where
1198+
F: ~const FnOnce(&T, &T) -> Ordering,
1199+
F: ~const Drop,
1200+
T: ~const Drop,
1201+
{
11961202
match compare(&v1, &v2) {
11971203
Ordering::Less | Ordering::Equal => v1,
11981204
Ordering::Greater => v2,
@@ -1255,7 +1261,13 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
12551261
#[inline]
12561262
#[must_use]
12571263
#[stable(feature = "cmp_min_max_by", since = "1.53.0")]
1258-
pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
1264+
#[rustc_const_unstable(feature = "const_cmp", issue = "none")]
1265+
pub const fn max_by<T, F>(v1: T, v2: T, compare: F) -> T
1266+
where
1267+
F: ~const FnOnce(&T, &T) -> Ordering,
1268+
F: ~const Drop,
1269+
T: ~const Drop,
1270+
{
12591271
match compare(&v1, &v2) {
12601272
Ordering::Less | Ordering::Equal => v2,
12611273
Ordering::Greater => v1,

library/core/src/internal_macros.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,3 +187,52 @@ macro_rules! impl_fn_for_zst {
187187
)+
188188
}
189189
}
190+
191+
macro_rules! impl_const_closure {
192+
(
193+
impl$(<$( $tt : tt ),*>)?
194+
const FnOnce for $Name: path $(where $($WhereTy:ty : $(~ $const:ident)? $Trait:path),+ $(,)?)? =
195+
$(#[$meta:meta])*
196+
|$mutorself:ident $($self:ident)?, $( $arg: tt: $ArgTy: ty ),*| $(-> $ReturnTy: ty)?
197+
$body: block;
198+
) => {
199+
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
200+
impl $( < $( $tt ),* > )? const FnOnce<($( $ArgTy, )*)> for $Name
201+
$(where $($WhereTy: $(~$const)? $Trait),+)?
202+
{
203+
#[allow(unused_parens)]
204+
type Output = ( $( $ReturnTy )? );
205+
206+
#[allow(unused_mut)]
207+
$(#[$meta])*
208+
extern "rust-call" fn call_once($mutorself $($self)?, ($( $arg, )*): ($( $ArgTy, )*)) -> Self::Output {
209+
$body
210+
}
211+
}
212+
};
213+
(
214+
impl$(< $( $tt: tt ),* >)?
215+
const FnMut for $Name: path $(where $($WhereTy:ty : $(~ $const:ident)? $Trait:path),+ $(,)?)? =
216+
$(#[$meta:meta])*
217+
|&mut $self:ident, $( $arg: tt: $ArgTy: ty ),*| $(-> $ReturnTy: ty)?
218+
$body: block;
219+
) => {
220+
impl_const_closure! {
221+
impl$(< $( $tt ),* >)?
222+
const FnOnce for $Name $(where $($WhereTy: $(~$const)? $Trait),+)? =
223+
$(#[$meta])*
224+
|mut $self, $( $arg: $ArgTy),*| $(-> $ReturnTy)?
225+
$body;
226+
}
227+
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
228+
impl $( < $( $tt ),* > )? const FnMut<($( $ArgTy, )*)> for $Name
229+
$(where $($WhereTy: $(~$const)? $Trait),+)?
230+
{
231+
$(#[$meta])*
232+
#[allow(unused_parens)]
233+
extern "rust-call" fn call_mut(&mut $self, ($( $arg, )*): ($( $ArgTy, )*)) -> ( $($ReturnTy)? ) {
234+
$body
235+
}
236+
}
237+
}
238+
}

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
@@ -19,7 +19,7 @@ pub struct Copied<I> {
1919
}
2020

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

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,12 @@ pub struct Cycle<I> {
1515
iter: I,
1616
}
1717

18-
impl<I: Clone> Cycle<I> {
19-
pub(in crate::iter) fn new(iter: I) -> Cycle<I> {
18+
impl<I> Cycle<I> {
19+
#[rustc_const_unstable(feature = "iter_internals", issue = "none")]
20+
pub(in crate::iter) const fn new(iter: I) -> Cycle<I>
21+
where
22+
I: ~const Clone,
23+
{
2024
Cycle { orig: iter.clone(), iter }
2125
}
2226
}

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: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ pub struct FlatMap<I, U: IntoIterator, F> {
1414
}
1515

1616
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> {
18-
FlatMap { inner: FlattenCompat::new(iter.map(f)) }
17+
#[rustc_const_unstable(feature = "iter_internals", issue = "none")]
18+
pub(in crate::iter) const fn new(iter: I, f: F) -> FlatMap<I, U, F> {
19+
FlatMap { inner: FlattenCompat::new(Map::new(iter, f)) }
1920
}
2021
}
2122

@@ -152,7 +153,8 @@ pub struct Flatten<I: Iterator<Item: IntoIterator>> {
152153
}
153154

154155
impl<I: Iterator<Item: IntoIterator>> Flatten<I> {
155-
pub(in super::super) fn new(iter: I) -> Flatten<I> {
156+
#[rustc_const_unstable(feature = "iter_internals", issue = "none")]
157+
pub(in super::super) const fn new(iter: I) -> Flatten<I> {
156158
Flatten { inner: FlattenCompat::new(iter) }
157159
}
158160
}
@@ -270,13 +272,10 @@ struct FlattenCompat<I, U> {
270272
frontiter: Option<U>,
271273
backiter: Option<U>,
272274
}
273-
impl<I, U> FlattenCompat<I, U>
274-
where
275-
I: Iterator,
276-
{
275+
impl<I, U> FlattenCompat<I, U> {
277276
/// Adapts an iterator by flattening it, for use in `flatten()` and `flat_map()`.
278-
fn new(iter: I) -> FlattenCompat<I, U> {
279-
FlattenCompat { iter: iter.fuse(), frontiter: None, backiter: None }
277+
const fn new(iter: I) -> FlattenCompat<I, U> {
278+
FlattenCompat { iter: super::Fuse::new(iter), frontiter: None, backiter: None }
280279
}
281280
}
282281

0 commit comments

Comments
 (0)