diff --git a/compiler/rustc_data_structures/src/graph/iterate/mod.rs b/compiler/rustc_data_structures/src/graph/iterate/mod.rs index bc3d1ce53bac5..5f42d46e28575 100644 --- a/compiler/rustc_data_structures/src/graph/iterate/mod.rs +++ b/compiler/rustc_data_structures/src/graph/iterate/mod.rs @@ -1,6 +1,7 @@ use super::{DirectedGraph, WithNumNodes, WithStartNode, WithSuccessors}; use rustc_index::bit_set::BitSet; use rustc_index::vec::IndexVec; +use std::ops::ControlFlow; #[cfg(test)] mod tests; @@ -86,10 +87,6 @@ where } } -/// Allows searches to terminate early with a value. -// FIXME (#75744): remove the alias once the generics are in a better order and `C=()`. -pub type ControlFlow = std::ops::ControlFlow<(), T>; - /// The status of a node in the depth-first search. /// /// See the documentation of `TriColorDepthFirstSearch` to see how a node's status is updated diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs index a9620b83124e0..576b537c01766 100644 --- a/compiler/rustc_mir_build/src/lints.rs +++ b/compiler/rustc_mir_build/src/lints.rs @@ -1,5 +1,5 @@ use rustc_data_structures::graph::iterate::{ - ControlFlow, NodeStatus, TriColorDepthFirstSearch, TriColorVisitor, + NodeStatus, TriColorDepthFirstSearch, TriColorVisitor, }; use rustc_hir::intravisit::FnKind; use rustc_middle::hir::map::blocks::FnLikeNode; @@ -8,6 +8,7 @@ use rustc_middle::ty::subst::{GenericArg, InternalSubsts}; use rustc_middle::ty::{self, AssocItem, AssocItemContainer, Instance, TyCtxt}; use rustc_session::lint::builtin::UNCONDITIONAL_RECURSION; use rustc_span::Span; +use std::ops::ControlFlow; crate fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) { let def_id = body.source.def_id().expect_local(); diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs index bf30dcb7689fa..9c8e639c2d802 100644 --- a/library/core/src/iter/adapters/mod.rs +++ b/library/core/src/iter/adapters/mod.rs @@ -1280,7 +1280,7 @@ where #[inline] fn find( f: &mut impl FnMut(T) -> Option, - ) -> impl FnMut((), T) -> ControlFlow<(), B> + '_ { + ) -> impl FnMut((), T) -> ControlFlow + '_ { move |(), x| match f(x) { Some(x) => ControlFlow::Break(x), None => ControlFlow::CONTINUE, @@ -2059,7 +2059,7 @@ where flag: &'a mut bool, p: &'a mut impl FnMut(&T) -> bool, mut fold: impl FnMut(Acc, T) -> R + 'a, - ) -> impl FnMut(Acc, T) -> ControlFlow + 'a { + ) -> impl FnMut(Acc, T) -> ControlFlow + 'a { move |acc, x| { if p(&x) { ControlFlow::from_try(fold(acc, x)) @@ -2372,7 +2372,7 @@ where fn check>( mut n: usize, mut fold: impl FnMut(Acc, T) -> R, - ) -> impl FnMut(Acc, T) -> ControlFlow { + ) -> impl FnMut(Acc, T) -> ControlFlow { move |acc, x| { n -= 1; let r = fold(acc, x); @@ -2496,7 +2496,7 @@ where fn check<'a, T, Acc, R: Try>( n: &'a mut usize, mut fold: impl FnMut(Acc, T) -> R + 'a, - ) -> impl FnMut(Acc, T) -> ControlFlow + 'a { + ) -> impl FnMut(Acc, T) -> ControlFlow + 'a { move |acc, x| { *n -= 1; let r = fold(acc, x); @@ -2681,7 +2681,7 @@ where state: &'a mut St, f: &'a mut impl FnMut(&mut St, T) -> Option, mut fold: impl FnMut(Acc, B) -> R + 'a, - ) -> impl FnMut(Acc, T) -> ControlFlow + 'a { + ) -> impl FnMut(Acc, T) -> ControlFlow + 'a { move |acc, x| match f(state, x) { None => ControlFlow::Break(try { acc }), Some(x) => ControlFlow::from_try(fold(acc, x)), diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs index 87fe3c210402e..6f8cb6b5a65b6 100644 --- a/library/core/src/iter/traits/double_ended.rs +++ b/library/core/src/iter/traits/double_ended.rs @@ -339,9 +339,7 @@ pub trait DoubleEndedIterator: Iterator { P: FnMut(&Self::Item) -> bool, { #[inline] - fn check( - mut predicate: impl FnMut(&T) -> bool, - ) -> impl FnMut((), T) -> ControlFlow<(), T> { + fn check(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut((), T) -> ControlFlow { move |(), x| { if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE } } diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 18b4adc23e8ef..7fc60caec2a73 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -2109,7 +2109,7 @@ pub trait Iterator { F: FnMut(Self::Item) -> bool, { #[inline] - fn check(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<(), ()> { + fn check(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<()> { move |(), x| { if f(x) { ControlFlow::CONTINUE } else { ControlFlow::BREAK } } @@ -2162,7 +2162,7 @@ pub trait Iterator { F: FnMut(Self::Item) -> bool, { #[inline] - fn check(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<(), ()> { + fn check(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<()> { move |(), x| { if f(x) { ControlFlow::BREAK } else { ControlFlow::CONTINUE } } @@ -2222,9 +2222,7 @@ pub trait Iterator { P: FnMut(&Self::Item) -> bool, { #[inline] - fn check( - mut predicate: impl FnMut(&T) -> bool, - ) -> impl FnMut((), T) -> ControlFlow<(), T> { + fn check(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut((), T) -> ControlFlow { move |(), x| { if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE } } @@ -2255,9 +2253,7 @@ pub trait Iterator { F: FnMut(Self::Item) -> Option, { #[inline] - fn check( - mut f: impl FnMut(T) -> Option, - ) -> impl FnMut((), T) -> ControlFlow<(), B> { + fn check(mut f: impl FnMut(T) -> Option) -> impl FnMut((), T) -> ControlFlow { move |(), x| match f(x) { Some(x) => ControlFlow::Break(x), None => ControlFlow::CONTINUE, @@ -2296,7 +2292,7 @@ pub trait Iterator { R: Try, { #[inline] - fn check(mut f: F) -> impl FnMut((), T) -> ControlFlow<(), Result> + fn check(mut f: F) -> impl FnMut((), T) -> ControlFlow> where F: FnMut(&T) -> R, R: Try, diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index 3bca3ff97332b..5ede1ba8e2c10 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -3,7 +3,7 @@ use crate::ops::Try; /// Used to make try_fold closures more like normal loops #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] #[derive(Debug, Clone, Copy, PartialEq)] -pub enum ControlFlow { +pub enum ControlFlow { /// Continue in the loop, using the given value for the next iteration Continue(C), /// Exit the loop, yielding the given value @@ -11,7 +11,7 @@ pub enum ControlFlow { } #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] -impl Try for ControlFlow { +impl Try for ControlFlow { type Ok = C; type Error = B; #[inline] @@ -31,7 +31,7 @@ impl Try for ControlFlow { } } -impl ControlFlow { +impl ControlFlow { /// Returns `true` if this is a `Break` variant. #[inline] #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] @@ -58,7 +58,7 @@ impl ControlFlow { } } -impl ControlFlow { +impl ControlFlow { /// Create a `ControlFlow` from any type implementing `Try`. #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] #[inline] @@ -80,7 +80,7 @@ impl ControlFlow { } } -impl ControlFlow<(), B> { +impl ControlFlow { /// It's frequently the case that there's no value needed with `Continue`, /// so this provides a way to avoid typing `(())`, if you prefer it. /// @@ -102,7 +102,7 @@ impl ControlFlow<(), B> { pub const CONTINUE: Self = ControlFlow::Continue(()); } -impl ControlFlow { +impl ControlFlow<(), C> { /// APIs like `try_for_each` don't need values with `Break`, /// so this provides a way to avoid typing `(())`, if you prefer it. ///