Mark DoubleEndedIterator as #[const_trait] using rustc_do_not_const_check, implement const Iterator and DoubleEndedIterator for Range.
This commit is contained in:
parent
7bc67ef6e0
commit
8a9d6bf4fd
@ -1,4 +1,5 @@
|
||||
use crate::convert::TryFrom;
|
||||
use crate::marker::Destruct;
|
||||
use crate::mem;
|
||||
use crate::ops::{self, Try};
|
||||
|
||||
@ -522,6 +523,7 @@ impl ExactSizeIterator for ops::RangeInclusive<$t> { }
|
||||
}
|
||||
|
||||
/// Specialization implementations for `Range`.
|
||||
#[const_trait]
|
||||
trait RangeIteratorImpl {
|
||||
type Item;
|
||||
|
||||
@ -536,7 +538,7 @@ trait RangeIteratorImpl {
|
||||
fn spec_advance_back_by(&mut self, n: usize) -> Result<(), usize>;
|
||||
}
|
||||
|
||||
impl<A: Step> RangeIteratorImpl for ops::Range<A> {
|
||||
impl<A: ~const Step + ~const Destruct> const RangeIteratorImpl for ops::Range<A> {
|
||||
type Item = A;
|
||||
|
||||
#[inline]
|
||||
@ -622,7 +624,7 @@ impl<A: Step> RangeIteratorImpl for ops::Range<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
|
||||
impl<T: ~const TrustedStep + ~const Destruct> const RangeIteratorImpl for ops::Range<T> {
|
||||
#[inline]
|
||||
fn spec_next(&mut self) -> Option<T> {
|
||||
if self.start < self.end {
|
||||
@ -710,7 +712,8 @@ fn spec_advance_back_by(&mut self, n: usize) -> Result<(), usize> {
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A: Step> Iterator for ops::Range<A> {
|
||||
#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
|
||||
impl<A: ~const Step + ~const Destruct> const Iterator for ops::Range<A> {
|
||||
type Item = A;
|
||||
|
||||
#[inline]
|
||||
@ -820,7 +823,8 @@ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A: Step> DoubleEndedIterator for ops::Range<A> {
|
||||
#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
|
||||
impl<A: ~const Step + ~const Destruct> const DoubleEndedIterator for ops::Range<A> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<A> {
|
||||
self.spec_next_back()
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::marker::Destruct;
|
||||
use crate::ops::{ControlFlow, Try};
|
||||
|
||||
/// An iterator able to yield elements from both ends.
|
||||
@ -37,6 +38,7 @@
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "DoubleEndedIterator")]
|
||||
#[const_trait]
|
||||
pub trait DoubleEndedIterator: Iterator {
|
||||
/// Removes and returns an element from the end of the iterator.
|
||||
///
|
||||
@ -131,7 +133,10 @@ pub trait DoubleEndedIterator: Iterator {
|
||||
/// [`Err(k)`]: Err
|
||||
#[inline]
|
||||
#[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")]
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), usize>
|
||||
where
|
||||
Self::Item: ~const Destruct,
|
||||
{
|
||||
for i in 0..n {
|
||||
self.next_back().ok_or(i)?;
|
||||
}
|
||||
@ -181,6 +186,7 @@ fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "iter_nth_back", since = "1.37.0")]
|
||||
#[rustc_do_not_const_check]
|
||||
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
|
||||
self.advance_back_by(n).ok()?;
|
||||
self.next_back()
|
||||
@ -218,6 +224,7 @@ fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "iterator_try_fold", since = "1.27.0")]
|
||||
#[rustc_do_not_const_check]
|
||||
fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
|
||||
where
|
||||
Self: Sized,
|
||||
@ -289,6 +296,7 @@ fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
|
||||
#[doc(alias = "foldr")]
|
||||
#[inline]
|
||||
#[stable(feature = "iter_rfold", since = "1.27.0")]
|
||||
#[rustc_do_not_const_check]
|
||||
fn rfold<B, F>(mut self, init: B, mut f: F) -> B
|
||||
where
|
||||
Self: Sized,
|
||||
@ -344,6 +352,7 @@ fn rfold<B, F>(mut self, init: B, mut f: F) -> B
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "iter_rfind", since = "1.27.0")]
|
||||
#[rustc_do_not_const_check]
|
||||
fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
|
||||
where
|
||||
Self: Sized,
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::array;
|
||||
use crate::cmp::{self, Ordering};
|
||||
use crate::marker::Destruct;
|
||||
use crate::ops::{ChangeOutputType, ControlFlow, FromResidual, Residual, Try};
|
||||
|
||||
use super::super::try_process;
|
||||
@ -336,8 +337,10 @@ fn some<T>(_: Option<T>, x: T) -> Option<T> {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")]
|
||||
#[rustc_do_not_const_check]
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), usize>
|
||||
where
|
||||
Self::Item: ~const Destruct,
|
||||
{
|
||||
for i in 0..n {
|
||||
self.next().ok_or(i)?;
|
||||
}
|
||||
@ -385,8 +388,10 @@ fn advance_by(&mut self, n: usize) -> Result<(), usize> {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_do_not_const_check]
|
||||
fn nth(&mut self, n: usize) -> Option<Self::Item> {
|
||||
fn nth(&mut self, n: usize) -> Option<Self::Item>
|
||||
where
|
||||
Self::Item: ~const Destruct,
|
||||
{
|
||||
self.advance_by(n).ok()?;
|
||||
self.next()
|
||||
}
|
||||
|
@ -123,6 +123,7 @@
|
||||
#![feature(const_index_range_slice_index)]
|
||||
#![feature(const_inherent_unchecked_arith)]
|
||||
#![feature(const_int_unchecked_arith)]
|
||||
#![feature(const_intoiterator_identity)]
|
||||
#![feature(const_intrinsic_forget)]
|
||||
#![feature(const_ipv4)]
|
||||
#![feature(const_ipv6)]
|
||||
|
36
library/core/tests/iter/consts.rs
Normal file
36
library/core/tests/iter/consts.rs
Normal file
@ -0,0 +1,36 @@
|
||||
#[test]
|
||||
fn const_manual_iter() {
|
||||
struct S(bool);
|
||||
|
||||
impl const Iterator for S {
|
||||
type Item = ();
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.0 == false {
|
||||
self.0 = true;
|
||||
Some(())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
const {
|
||||
let mut val = S(false);
|
||||
assert!(val.next().is_some());
|
||||
assert!(val.next().is_none());
|
||||
assert!(val.next().is_none());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn const_range() {
|
||||
const {
|
||||
let mut arr = [0; 3];
|
||||
for i in 0..arr.len() {
|
||||
arr[i] = i;
|
||||
}
|
||||
assert!(arr[0] == 0);
|
||||
assert!(arr[1] == 1);
|
||||
assert!(arr[2] == 2);
|
||||
}
|
||||
}
|
@ -20,6 +20,8 @@
|
||||
mod sources;
|
||||
mod traits;
|
||||
|
||||
mod consts;
|
||||
|
||||
use core::cell::Cell;
|
||||
use core::convert::TryFrom;
|
||||
use core::iter::*;
|
||||
|
@ -12,8 +12,11 @@
|
||||
#![feature(const_caller_location)]
|
||||
#![feature(const_cell_into_inner)]
|
||||
#![feature(const_convert)]
|
||||
#![feature(const_for)]
|
||||
#![feature(const_hash)]
|
||||
#![feature(const_heap)]
|
||||
#![feature(const_intoiterator_identity)]
|
||||
#![feature(const_iter)]
|
||||
#![feature(const_maybe_uninit_as_mut_ptr)]
|
||||
#![feature(const_maybe_uninit_assume_init_read)]
|
||||
#![feature(const_nonnull_new)]
|
||||
|
@ -228,5 +228,4 @@ fn evens_squared(n: usize) -> _ {
|
||||
|
||||
const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
|
||||
//~^ ERROR the trait bound
|
||||
//~| ERROR the trait bound
|
||||
//~| ERROR the placeholder
|
||||
|
@ -437,19 +437,6 @@ LL | fn evens_squared(n: usize) -> _ {
|
||||
| not allowed in type signatures
|
||||
| help: replace with an appropriate return type: `impl Iterator<Item = usize>`
|
||||
|
||||
error[E0277]: the trait bound `std::ops::Range<{integer}>: Iterator` is not satisfied
|
||||
--> $DIR/typeck_type_placeholder_item.rs:229:22
|
||||
|
|
||||
LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
|
||||
| ^^^^^^ `std::ops::Range<{integer}>` is not an iterator
|
||||
|
|
||||
= help: the trait `~const Iterator` is not implemented for `std::ops::Range<{integer}>`
|
||||
note: the trait `Iterator` is implemented for `std::ops::Range<{integer}>`, but that implementation is not `const`
|
||||
--> $DIR/typeck_type_placeholder_item.rs:229:14
|
||||
|
|
||||
LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0277]: the trait bound `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>: Iterator` is not satisfied
|
||||
--> $DIR/typeck_type_placeholder_item.rs:229:45
|
||||
|
|
||||
@ -677,7 +664,7 @@ LL | const D: _ = 42;
|
||||
| not allowed in type signatures
|
||||
| help: replace with the correct type: `i32`
|
||||
|
||||
error: aborting due to 73 previous errors
|
||||
error: aborting due to 72 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0121, E0277, E0282, E0403.
|
||||
For more information about an error, try `rustc --explain E0121`.
|
||||
|
Loading…
Reference in New Issue
Block a user