Skip to content

Commit d0af125

Browse files
committed
Rename and expose LoopState as ControlFlow
1 parent eb9e7c3 commit d0af125

File tree

6 files changed

+113
-99
lines changed

6 files changed

+113
-99
lines changed

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

+19-19
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use crate::cmp;
22
use crate::fmt;
33
use crate::intrinsics;
4-
use crate::ops::{Add, AddAssign, Try};
4+
use crate::ops::{Add, AddAssign, Try, ControlFlow};
55

6-
use super::{from_fn, LoopState};
6+
use super::from_fn;
77
use super::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator, TrustedLen};
88

99
mod chain;
@@ -1164,10 +1164,10 @@ where
11641164
#[inline]
11651165
fn find<T, B>(
11661166
f: &mut impl FnMut(T) -> Option<B>,
1167-
) -> impl FnMut((), T) -> LoopState<(), B> + '_ {
1167+
) -> impl FnMut((), T) -> ControlFlow<(), B> + '_ {
11681168
move |(), x| match f(x) {
1169-
Some(x) => LoopState::Break(x),
1170-
None => LoopState::Continue(()),
1169+
Some(x) => ControlFlow::Break(x),
1170+
None => ControlFlow::Continue(()),
11711171
}
11721172
}
11731173

@@ -1864,13 +1864,13 @@ where
18641864
flag: &'a mut bool,
18651865
p: &'a mut impl FnMut(&T) -> bool,
18661866
mut fold: impl FnMut(Acc, T) -> R + 'a,
1867-
) -> impl FnMut(Acc, T) -> LoopState<Acc, R> + 'a {
1867+
) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> + 'a {
18681868
move |acc, x| {
18691869
if p(&x) {
1870-
LoopState::from_try(fold(acc, x))
1870+
ControlFlow::from_try(fold(acc, x))
18711871
} else {
18721872
*flag = true;
1873-
LoopState::Break(Try::from_ok(acc))
1873+
ControlFlow::Break(Try::from_ok(acc))
18741874
}
18751875
}
18761876
}
@@ -1963,8 +1963,8 @@ where
19631963
{
19641964
let Self { iter, predicate } = self;
19651965
iter.try_fold(init, |acc, x| match predicate(x) {
1966-
Some(item) => LoopState::from_try(fold(acc, item)),
1967-
None => LoopState::Break(Try::from_ok(acc)),
1966+
Some(item) => ControlFlow::from_try(fold(acc, item)),
1967+
None => ControlFlow::Break(Try::from_ok(acc)),
19681968
})
19691969
.into_try()
19701970
}
@@ -2135,11 +2135,11 @@ where
21352135
fn check<T, Acc, R: Try<Ok = Acc>>(
21362136
mut n: usize,
21372137
mut fold: impl FnMut(Acc, T) -> R,
2138-
) -> impl FnMut(Acc, T) -> LoopState<Acc, R> {
2138+
) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> {
21392139
move |acc, x| {
21402140
n -= 1;
21412141
let r = fold(acc, x);
2142-
if n == 0 { LoopState::Break(r) } else { LoopState::from_try(r) }
2142+
if n == 0 { ControlFlow::Break(r) } else { ControlFlow::from_try(r) }
21432143
}
21442144
}
21452145

@@ -2246,11 +2246,11 @@ where
22462246
fn check<'a, T, Acc, R: Try<Ok = Acc>>(
22472247
n: &'a mut usize,
22482248
mut fold: impl FnMut(Acc, T) -> R + 'a,
2249-
) -> impl FnMut(Acc, T) -> LoopState<Acc, R> + 'a {
2249+
) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> + 'a {
22502250
move |acc, x| {
22512251
*n -= 1;
22522252
let r = fold(acc, x);
2253-
if *n == 0 { LoopState::Break(r) } else { LoopState::from_try(r) }
2253+
if *n == 0 { ControlFlow::Break(r) } else { ControlFlow::from_try(r) }
22542254
}
22552255
}
22562256

@@ -2414,10 +2414,10 @@ where
24142414
state: &'a mut St,
24152415
f: &'a mut impl FnMut(&mut St, T) -> Option<B>,
24162416
mut fold: impl FnMut(Acc, B) -> R + 'a,
2417-
) -> impl FnMut(Acc, T) -> LoopState<Acc, R> + 'a {
2417+
) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> + 'a {
24182418
move |acc, x| match f(state, x) {
2419-
None => LoopState::Break(Try::from_ok(acc)),
2420-
Some(x) => LoopState::from_try(fold(acc, x)),
2419+
None => ControlFlow::Break(Try::from_ok(acc)),
2420+
Some(x) => ControlFlow::from_try(fold(acc, x)),
24212421
}
24222422
}
24232423

@@ -2638,10 +2638,10 @@ where
26382638
let error = &mut *self.error;
26392639
self.iter
26402640
.try_fold(init, |acc, x| match x {
2641-
Ok(x) => LoopState::from_try(f(acc, x)),
2641+
Ok(x) => ControlFlow::from_try(f(acc, x)),
26422642
Err(e) => {
26432643
*error = Err(e);
2644-
LoopState::Break(Try::from_ok(acc))
2644+
ControlFlow::Break(Try::from_ok(acc))
26452645
}
26462646
})
26472647
.into_try()

library/core/src/iter/mod.rs

-55
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,6 @@
308308
309309
#![stable(feature = "rust1", since = "1.0.0")]
310310

311-
use crate::ops::Try;
312-
313311
#[stable(feature = "rust1", since = "1.0.0")]
314312
pub use self::traits::Iterator;
315313

@@ -368,56 +366,3 @@ mod range;
368366
mod sources;
369367
mod traits;
370368

371-
/// Used to make try_fold closures more like normal loops
372-
#[derive(PartialEq)]
373-
enum LoopState<C, B> {
374-
Continue(C),
375-
Break(B),
376-
}
377-
378-
impl<C, B> Try for LoopState<C, B> {
379-
type Ok = C;
380-
type Error = B;
381-
#[inline]
382-
fn into_result(self) -> Result<Self::Ok, Self::Error> {
383-
match self {
384-
LoopState::Continue(y) => Ok(y),
385-
LoopState::Break(x) => Err(x),
386-
}
387-
}
388-
#[inline]
389-
fn from_error(v: Self::Error) -> Self {
390-
LoopState::Break(v)
391-
}
392-
#[inline]
393-
fn from_ok(v: Self::Ok) -> Self {
394-
LoopState::Continue(v)
395-
}
396-
}
397-
398-
impl<C, B> LoopState<C, B> {
399-
#[inline]
400-
fn break_value(self) -> Option<B> {
401-
match self {
402-
LoopState::Continue(..) => None,
403-
LoopState::Break(x) => Some(x),
404-
}
405-
}
406-
}
407-
408-
impl<R: Try> LoopState<R::Ok, R> {
409-
#[inline]
410-
fn from_try(r: R) -> Self {
411-
match Try::into_result(r) {
412-
Ok(v) => LoopState::Continue(v),
413-
Err(v) => LoopState::Break(Try::from_error(v)),
414-
}
415-
}
416-
#[inline]
417-
fn into_try(self) -> R {
418-
match self {
419-
LoopState::Continue(v) => Try::from_ok(v),
420-
LoopState::Break(v) => v,
421-
}
422-
}
423-
}

library/core/src/iter/traits/double_ended.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
use crate::iter::LoopState;
2-
use crate::ops::Try;
1+
use crate::ops::{Try, ControlFlow};
32

43
/// An iterator able to yield elements from both ends.
54
///
@@ -309,9 +308,9 @@ pub trait DoubleEndedIterator: Iterator {
309308
#[inline]
310309
fn check<T>(
311310
mut predicate: impl FnMut(&T) -> bool,
312-
) -> impl FnMut((), T) -> LoopState<(), T> {
311+
) -> impl FnMut((), T) -> ControlFlow<(), T> {
313312
move |(), x| {
314-
if predicate(&x) { LoopState::Break(x) } else { LoopState::Continue(()) }
313+
if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::Continue(()) }
315314
}
316315
}
317316

library/core/src/iter/traits/iterator.rs

+20-21
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
// can't split that into multiple files.
44

55
use crate::cmp::{self, Ordering};
6-
use crate::ops::{Add, Try};
6+
use crate::ops::{Add, Try, ControlFlow};
77

8-
use super::super::LoopState;
98
use super::super::TrustedRandomAccess;
109
use super::super::{Chain, Cloned, Copied, Cycle, Enumerate, Filter, FilterMap, Fuse};
1110
use super::super::{FlatMap, Flatten};
@@ -2088,12 +2087,12 @@ pub trait Iterator {
20882087
F: FnMut(Self::Item) -> bool,
20892088
{
20902089
#[inline]
2091-
fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> LoopState<(), ()> {
2090+
fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<(), ()> {
20922091
move |(), x| {
2093-
if f(x) { LoopState::Continue(()) } else { LoopState::Break(()) }
2092+
if f(x) { ControlFlow::Continue(()) } else { ControlFlow::Break(()) }
20942093
}
20952094
}
2096-
self.try_fold((), check(f)) == LoopState::Continue(())
2095+
self.try_fold((), check(f)) == ControlFlow::Continue(())
20972096
}
20982097

20992098
/// Tests if any element of the iterator matches a predicate.
@@ -2141,13 +2140,13 @@ pub trait Iterator {
21412140
F: FnMut(Self::Item) -> bool,
21422141
{
21432142
#[inline]
2144-
fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> LoopState<(), ()> {
2143+
fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<(), ()> {
21452144
move |(), x| {
2146-
if f(x) { LoopState::Break(()) } else { LoopState::Continue(()) }
2145+
if f(x) { ControlFlow::Break(()) } else { ControlFlow::Continue(()) }
21472146
}
21482147
}
21492148

2150-
self.try_fold((), check(f)) == LoopState::Break(())
2149+
self.try_fold((), check(f)) == ControlFlow::Break(())
21512150
}
21522151

21532152
/// Searches for an element of an iterator that satisfies a predicate.
@@ -2203,9 +2202,9 @@ pub trait Iterator {
22032202
#[inline]
22042203
fn check<T>(
22052204
mut predicate: impl FnMut(&T) -> bool,
2206-
) -> impl FnMut((), T) -> LoopState<(), T> {
2205+
) -> impl FnMut((), T) -> ControlFlow<(), T> {
22072206
move |(), x| {
2208-
if predicate(&x) { LoopState::Break(x) } else { LoopState::Continue(()) }
2207+
if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::Continue(()) }
22092208
}
22102209
}
22112210

@@ -2235,10 +2234,10 @@ pub trait Iterator {
22352234
F: FnMut(Self::Item) -> Option<B>,
22362235
{
22372236
#[inline]
2238-
fn check<T, B>(mut f: impl FnMut(T) -> Option<B>) -> impl FnMut((), T) -> LoopState<(), B> {
2237+
fn check<T, B>(mut f: impl FnMut(T) -> Option<B>) -> impl FnMut((), T) -> ControlFlow<(), B> {
22392238
move |(), x| match f(x) {
2240-
Some(x) => LoopState::Break(x),
2241-
None => LoopState::Continue(()),
2239+
Some(x) => ControlFlow::Break(x),
2240+
None => ControlFlow::Continue(()),
22422241
}
22432242
}
22442243

@@ -2274,15 +2273,15 @@ pub trait Iterator {
22742273
R: Try<Ok = bool>,
22752274
{
22762275
#[inline]
2277-
fn check<F, T, R>(mut f: F) -> impl FnMut((), T) -> LoopState<(), Result<T, R::Error>>
2276+
fn check<F, T, R>(mut f: F) -> impl FnMut((), T) -> ControlFlow<(), Result<T, R::Error>>
22782277
where
22792278
F: FnMut(&T) -> R,
22802279
R: Try<Ok = bool>,
22812280
{
22822281
move |(), x| match f(&x).into_result() {
2283-
Ok(false) => LoopState::Continue(()),
2284-
Ok(true) => LoopState::Break(Ok(x)),
2285-
Err(x) => LoopState::Break(Err(x)),
2282+
Ok(false) => ControlFlow::Continue(()),
2283+
Ok(true) => ControlFlow::Break(Ok(x)),
2284+
Err(x) => ControlFlow::Break(Err(x)),
22862285
}
22872286
}
22882287

@@ -2352,10 +2351,10 @@ pub trait Iterator {
23522351
#[inline]
23532352
fn check<T>(
23542353
mut predicate: impl FnMut(T) -> bool,
2355-
) -> impl FnMut(usize, T) -> LoopState<usize, usize> {
2354+
) -> impl FnMut(usize, T) -> ControlFlow<usize, usize> {
23562355
// The addition might panic on overflow
23572356
move |i, x| {
2358-
if predicate(x) { LoopState::Break(i) } else { LoopState::Continue(Add::add(i, 1)) }
2357+
if predicate(x) { ControlFlow::Break(i) } else { ControlFlow::Continue(Add::add(i, 1)) }
23592358
}
23602359
}
23612360

@@ -2411,10 +2410,10 @@ pub trait Iterator {
24112410
#[inline]
24122411
fn check<T>(
24132412
mut predicate: impl FnMut(T) -> bool,
2414-
) -> impl FnMut(usize, T) -> LoopState<usize, usize> {
2413+
) -> impl FnMut(usize, T) -> ControlFlow<usize, usize> {
24152414
move |i, x| {
24162415
let i = i - 1;
2417-
if predicate(x) { LoopState::Break(i) } else { LoopState::Continue(i) }
2416+
if predicate(x) { ControlFlow::Break(i) } else { ControlFlow::Continue(i) }
24182417
}
24192418
}
24202419

library/core/src/ops/control_flow.rs

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
use crate::ops::Try;
2+
3+
/// Used to make try_fold closures more like normal loops
4+
#[unstable(feature="control_flow_enum", reason="new API", issue="75744")]
5+
#[derive(Debug, Clone, Copy, PartialEq)]
6+
pub enum ControlFlow<C, B> {
7+
/// Continue in the loop, using the given value for the next iteration
8+
Continue(C),
9+
/// Exit the loop, yielding the given value
10+
Break(B),
11+
}
12+
13+
#[unstable(feature="control_flow_enum", reason="new API", issue="75744")]
14+
impl<C, B> Try for ControlFlow<C, B> {
15+
type Ok = C;
16+
type Error = B;
17+
#[inline]
18+
fn into_result(self) -> Result<Self::Ok, Self::Error> {
19+
match self {
20+
ControlFlow::Continue(y) => Ok(y),
21+
ControlFlow::Break(x) => Err(x),
22+
}
23+
}
24+
#[inline]
25+
fn from_error(v: Self::Error) -> Self {
26+
ControlFlow::Break(v)
27+
}
28+
#[inline]
29+
fn from_ok(v: Self::Ok) -> Self {
30+
ControlFlow::Continue(v)
31+
}
32+
}
33+
34+
impl<C, B> ControlFlow<C, B> {
35+
/// Converts the `ControlFlow` into an `Option` which is `Some` if the
36+
/// `ControlFlow` was `Break` and `None` otherwise.
37+
#[inline]
38+
#[unstable(feature="control_flow_enum", reason="new API", issue="75744")]
39+
pub fn break_value(self) -> Option<B> {
40+
match self {
41+
ControlFlow::Continue(..) => None,
42+
ControlFlow::Break(x) => Some(x),
43+
}
44+
}
45+
}
46+
47+
impl<R: Try> ControlFlow<R::Ok, R> {
48+
/// Create a `ControlFlow` from any type implementing `Try`.
49+
#[unstable(feature="control_flow_enum", reason="new API", issue="75744")]
50+
#[inline]
51+
pub fn from_try(r: R) -> Self {
52+
match Try::into_result(r) {
53+
Ok(v) => ControlFlow::Continue(v),
54+
Err(v) => ControlFlow::Break(Try::from_error(v)),
55+
}
56+
}
57+
58+
/// Convert a `ControlFlow` into any type implementing `Try`;
59+
#[unstable(feature="control_flow_enum", reason="new API", issue="75744")]
60+
#[inline]
61+
pub fn into_try(self) -> R {
62+
match self {
63+
ControlFlow::Continue(v) => Try::from_ok(v),
64+
ControlFlow::Break(v) => v,
65+
}
66+
}
67+
}

library/core/src/ops/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ mod index;
148148
mod range;
149149
mod r#try;
150150
mod unsize;
151+
mod control_flow;
151152

152153
#[stable(feature = "rust1", since = "1.0.0")]
153154
pub use self::arith::{Add, Div, Mul, Neg, Rem, Sub};
@@ -191,3 +192,6 @@ pub use self::unsize::CoerceUnsized;
191192

192193
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
193194
pub use self::unsize::DispatchFromDyn;
195+
196+
#[unstable(feature="control_flow_enum", reason="new API", issue="75744")]
197+
pub use self::control_flow::ControlFlow;

0 commit comments

Comments
 (0)