Skip to content

Commit a547055

Browse files
Rollup merge of #76614 - NoraCodes:nora/control_flow_enum, r=scottmcm
change the order of type arguments on ControlFlow This allows ControlFlow<BreakType> which is much more ergonomic for common iterator combinator use cases. Addresses one component of #75744
2 parents 01a38f0 + bc23179 commit a547055

File tree

6 files changed

+20
-28
lines changed

6 files changed

+20
-28
lines changed

compiler/rustc_data_structures/src/graph/iterate/mod.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use super::{DirectedGraph, WithNumNodes, WithStartNode, WithSuccessors};
22
use rustc_index::bit_set::BitSet;
33
use rustc_index::vec::IndexVec;
4+
use std::ops::ControlFlow;
45

56
#[cfg(test)]
67
mod tests;
@@ -86,10 +87,6 @@ where
8687
}
8788
}
8889

89-
/// Allows searches to terminate early with a value.
90-
// FIXME (#75744): remove the alias once the generics are in a better order and `C=()`.
91-
pub type ControlFlow<T> = std::ops::ControlFlow<(), T>;
92-
9390
/// The status of a node in the depth-first search.
9491
///
9592
/// See the documentation of `TriColorDepthFirstSearch` to see how a node's status is updated

compiler/rustc_mir_build/src/lints.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use rustc_data_structures::graph::iterate::{
2-
ControlFlow, NodeStatus, TriColorDepthFirstSearch, TriColorVisitor,
2+
NodeStatus, TriColorDepthFirstSearch, TriColorVisitor,
33
};
44
use rustc_hir::intravisit::FnKind;
55
use rustc_middle::hir::map::blocks::FnLikeNode;
@@ -8,6 +8,7 @@ use rustc_middle::ty::subst::{GenericArg, InternalSubsts};
88
use rustc_middle::ty::{self, AssocItem, AssocItemContainer, Instance, TyCtxt};
99
use rustc_session::lint::builtin::UNCONDITIONAL_RECURSION;
1010
use rustc_span::Span;
11+
use std::ops::ControlFlow;
1112

1213
crate fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
1314
let def_id = body.source.def_id().expect_local();

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

+5-5
Original file line numberDiff line numberDiff line change
@@ -1280,7 +1280,7 @@ where
12801280
#[inline]
12811281
fn find<T, B>(
12821282
f: &mut impl FnMut(T) -> Option<B>,
1283-
) -> impl FnMut((), T) -> ControlFlow<(), B> + '_ {
1283+
) -> impl FnMut((), T) -> ControlFlow<B> + '_ {
12841284
move |(), x| match f(x) {
12851285
Some(x) => ControlFlow::Break(x),
12861286
None => ControlFlow::CONTINUE,
@@ -2059,7 +2059,7 @@ where
20592059
flag: &'a mut bool,
20602060
p: &'a mut impl FnMut(&T) -> bool,
20612061
mut fold: impl FnMut(Acc, T) -> R + 'a,
2062-
) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> + 'a {
2062+
) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + 'a {
20632063
move |acc, x| {
20642064
if p(&x) {
20652065
ControlFlow::from_try(fold(acc, x))
@@ -2372,7 +2372,7 @@ where
23722372
fn check<T, Acc, R: Try<Ok = Acc>>(
23732373
mut n: usize,
23742374
mut fold: impl FnMut(Acc, T) -> R,
2375-
) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> {
2375+
) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> {
23762376
move |acc, x| {
23772377
n -= 1;
23782378
let r = fold(acc, x);
@@ -2496,7 +2496,7 @@ where
24962496
fn check<'a, T, Acc, R: Try<Ok = Acc>>(
24972497
n: &'a mut usize,
24982498
mut fold: impl FnMut(Acc, T) -> R + 'a,
2499-
) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> + 'a {
2499+
) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + 'a {
25002500
move |acc, x| {
25012501
*n -= 1;
25022502
let r = fold(acc, x);
@@ -2681,7 +2681,7 @@ where
26812681
state: &'a mut St,
26822682
f: &'a mut impl FnMut(&mut St, T) -> Option<B>,
26832683
mut fold: impl FnMut(Acc, B) -> R + 'a,
2684-
) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> + 'a {
2684+
) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + 'a {
26852685
move |acc, x| match f(state, x) {
26862686
None => ControlFlow::Break(try { acc }),
26872687
Some(x) => ControlFlow::from_try(fold(acc, x)),

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

+1-3
Original file line numberDiff line numberDiff line change
@@ -339,9 +339,7 @@ pub trait DoubleEndedIterator: Iterator {
339339
P: FnMut(&Self::Item) -> bool,
340340
{
341341
#[inline]
342-
fn check<T>(
343-
mut predicate: impl FnMut(&T) -> bool,
344-
) -> impl FnMut((), T) -> ControlFlow<(), T> {
342+
fn check<T>(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut((), T) -> ControlFlow<T> {
345343
move |(), x| {
346344
if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE }
347345
}

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

+5-9
Original file line numberDiff line numberDiff line change
@@ -2109,7 +2109,7 @@ pub trait Iterator {
21092109
F: FnMut(Self::Item) -> bool,
21102110
{
21112111
#[inline]
2112-
fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<(), ()> {
2112+
fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<()> {
21132113
move |(), x| {
21142114
if f(x) { ControlFlow::CONTINUE } else { ControlFlow::BREAK }
21152115
}
@@ -2162,7 +2162,7 @@ pub trait Iterator {
21622162
F: FnMut(Self::Item) -> bool,
21632163
{
21642164
#[inline]
2165-
fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<(), ()> {
2165+
fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<()> {
21662166
move |(), x| {
21672167
if f(x) { ControlFlow::BREAK } else { ControlFlow::CONTINUE }
21682168
}
@@ -2222,9 +2222,7 @@ pub trait Iterator {
22222222
P: FnMut(&Self::Item) -> bool,
22232223
{
22242224
#[inline]
2225-
fn check<T>(
2226-
mut predicate: impl FnMut(&T) -> bool,
2227-
) -> impl FnMut((), T) -> ControlFlow<(), T> {
2225+
fn check<T>(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut((), T) -> ControlFlow<T> {
22282226
move |(), x| {
22292227
if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE }
22302228
}
@@ -2255,9 +2253,7 @@ pub trait Iterator {
22552253
F: FnMut(Self::Item) -> Option<B>,
22562254
{
22572255
#[inline]
2258-
fn check<T, B>(
2259-
mut f: impl FnMut(T) -> Option<B>,
2260-
) -> impl FnMut((), T) -> ControlFlow<(), B> {
2256+
fn check<T, B>(mut f: impl FnMut(T) -> Option<B>) -> impl FnMut((), T) -> ControlFlow<B> {
22612257
move |(), x| match f(x) {
22622258
Some(x) => ControlFlow::Break(x),
22632259
None => ControlFlow::CONTINUE,
@@ -2296,7 +2292,7 @@ pub trait Iterator {
22962292
R: Try<Ok = bool>,
22972293
{
22982294
#[inline]
2299-
fn check<F, T, R>(mut f: F) -> impl FnMut((), T) -> ControlFlow<(), Result<T, R::Error>>
2295+
fn check<F, T, R>(mut f: F) -> impl FnMut((), T) -> ControlFlow<Result<T, R::Error>>
23002296
where
23012297
F: FnMut(&T) -> R,
23022298
R: Try<Ok = bool>,

library/core/src/ops/control_flow.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ use crate::ops::Try;
33
/// Used to make try_fold closures more like normal loops
44
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
55
#[derive(Debug, Clone, Copy, PartialEq)]
6-
pub enum ControlFlow<C, B> {
6+
pub enum ControlFlow<B, C = ()> {
77
/// Continue in the loop, using the given value for the next iteration
88
Continue(C),
99
/// Exit the loop, yielding the given value
1010
Break(B),
1111
}
1212

1313
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
14-
impl<C, B> Try for ControlFlow<C, B> {
14+
impl<B, C> Try for ControlFlow<B, C> {
1515
type Ok = C;
1616
type Error = B;
1717
#[inline]
@@ -31,7 +31,7 @@ impl<C, B> Try for ControlFlow<C, B> {
3131
}
3232
}
3333

34-
impl<C, B> ControlFlow<C, B> {
34+
impl<B, C> ControlFlow<B, C> {
3535
/// Returns `true` if this is a `Break` variant.
3636
#[inline]
3737
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
@@ -58,7 +58,7 @@ impl<C, B> ControlFlow<C, B> {
5858
}
5959
}
6060

61-
impl<R: Try> ControlFlow<R::Ok, R> {
61+
impl<R: Try> ControlFlow<R, R::Ok> {
6262
/// Create a `ControlFlow` from any type implementing `Try`.
6363
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
6464
#[inline]
@@ -80,7 +80,7 @@ impl<R: Try> ControlFlow<R::Ok, R> {
8080
}
8181
}
8282

83-
impl<B> ControlFlow<(), B> {
83+
impl<B> ControlFlow<B, ()> {
8484
/// It's frequently the case that there's no value needed with `Continue`,
8585
/// so this provides a way to avoid typing `(())`, if you prefer it.
8686
///
@@ -102,7 +102,7 @@ impl<B> ControlFlow<(), B> {
102102
pub const CONTINUE: Self = ControlFlow::Continue(());
103103
}
104104

105-
impl<C> ControlFlow<C, ()> {
105+
impl<C> ControlFlow<(), C> {
106106
/// APIs like `try_for_each` don't need values with `Break`,
107107
/// so this provides a way to avoid typing `(())`, if you prefer it.
108108
///

0 commit comments

Comments
 (0)