mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 23:12:02 +00:00
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
This commit is contained in:
commit
a547055184
@ -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<T> = 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
|
||||
|
@ -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();
|
||||
|
@ -1280,7 +1280,7 @@ where
|
||||
#[inline]
|
||||
fn find<T, B>(
|
||||
f: &mut impl FnMut(T) -> Option<B>,
|
||||
) -> impl FnMut((), T) -> ControlFlow<(), B> + '_ {
|
||||
) -> impl FnMut((), T) -> ControlFlow<B> + '_ {
|
||||
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<Acc, R> + 'a {
|
||||
) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + 'a {
|
||||
move |acc, x| {
|
||||
if p(&x) {
|
||||
ControlFlow::from_try(fold(acc, x))
|
||||
@ -2372,7 +2372,7 @@ where
|
||||
fn check<T, Acc, R: Try<Ok = Acc>>(
|
||||
mut n: usize,
|
||||
mut fold: impl FnMut(Acc, T) -> R,
|
||||
) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> {
|
||||
) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> {
|
||||
move |acc, x| {
|
||||
n -= 1;
|
||||
let r = fold(acc, x);
|
||||
@ -2496,7 +2496,7 @@ where
|
||||
fn check<'a, T, Acc, R: Try<Ok = Acc>>(
|
||||
n: &'a mut usize,
|
||||
mut fold: impl FnMut(Acc, T) -> R + 'a,
|
||||
) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> + 'a {
|
||||
) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + '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<B>,
|
||||
mut fold: impl FnMut(Acc, B) -> R + 'a,
|
||||
) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> + 'a {
|
||||
) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + 'a {
|
||||
move |acc, x| match f(state, x) {
|
||||
None => ControlFlow::Break(try { acc }),
|
||||
Some(x) => ControlFlow::from_try(fold(acc, x)),
|
||||
|
@ -339,9 +339,7 @@ pub trait DoubleEndedIterator: Iterator {
|
||||
P: FnMut(&Self::Item) -> bool,
|
||||
{
|
||||
#[inline]
|
||||
fn check<T>(
|
||||
mut predicate: impl FnMut(&T) -> bool,
|
||||
) -> impl FnMut((), T) -> ControlFlow<(), T> {
|
||||
fn check<T>(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut((), T) -> ControlFlow<T> {
|
||||
move |(), x| {
|
||||
if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE }
|
||||
}
|
||||
|
@ -2109,7 +2109,7 @@ pub trait Iterator {
|
||||
F: FnMut(Self::Item) -> bool,
|
||||
{
|
||||
#[inline]
|
||||
fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<(), ()> {
|
||||
fn check<T>(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<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<(), ()> {
|
||||
fn check<T>(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<T>(
|
||||
mut predicate: impl FnMut(&T) -> bool,
|
||||
) -> impl FnMut((), T) -> ControlFlow<(), T> {
|
||||
fn check<T>(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut((), T) -> ControlFlow<T> {
|
||||
move |(), x| {
|
||||
if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE }
|
||||
}
|
||||
@ -2255,9 +2253,7 @@ pub trait Iterator {
|
||||
F: FnMut(Self::Item) -> Option<B>,
|
||||
{
|
||||
#[inline]
|
||||
fn check<T, B>(
|
||||
mut f: impl FnMut(T) -> Option<B>,
|
||||
) -> impl FnMut((), T) -> ControlFlow<(), B> {
|
||||
fn check<T, B>(mut f: impl FnMut(T) -> Option<B>) -> impl FnMut((), T) -> ControlFlow<B> {
|
||||
move |(), x| match f(x) {
|
||||
Some(x) => ControlFlow::Break(x),
|
||||
None => ControlFlow::CONTINUE,
|
||||
@ -2296,7 +2292,7 @@ pub trait Iterator {
|
||||
R: Try<Ok = bool>,
|
||||
{
|
||||
#[inline]
|
||||
fn check<F, T, R>(mut f: F) -> impl FnMut((), T) -> ControlFlow<(), Result<T, R::Error>>
|
||||
fn check<F, T, R>(mut f: F) -> impl FnMut((), T) -> ControlFlow<Result<T, R::Error>>
|
||||
where
|
||||
F: FnMut(&T) -> R,
|
||||
R: Try<Ok = bool>,
|
||||
|
@ -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<C, B> {
|
||||
pub enum ControlFlow<B, C = ()> {
|
||||
/// 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<C, B> {
|
||||
}
|
||||
|
||||
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
|
||||
impl<C, B> Try for ControlFlow<C, B> {
|
||||
impl<B, C> Try for ControlFlow<B, C> {
|
||||
type Ok = C;
|
||||
type Error = B;
|
||||
#[inline]
|
||||
@ -31,7 +31,7 @@ impl<C, B> Try for ControlFlow<C, B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, B> ControlFlow<C, B> {
|
||||
impl<B, C> ControlFlow<B, C> {
|
||||
/// Returns `true` if this is a `Break` variant.
|
||||
#[inline]
|
||||
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
|
||||
@ -58,7 +58,7 @@ impl<C, B> ControlFlow<C, B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Try> ControlFlow<R::Ok, R> {
|
||||
impl<R: Try> ControlFlow<R, R::Ok> {
|
||||
/// Create a `ControlFlow` from any type implementing `Try`.
|
||||
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
|
||||
#[inline]
|
||||
@ -80,7 +80,7 @@ impl<R: Try> ControlFlow<R::Ok, R> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<B> ControlFlow<(), B> {
|
||||
impl<B> ControlFlow<B, ()> {
|
||||
/// 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<B> ControlFlow<(), B> {
|
||||
pub const CONTINUE: Self = ControlFlow::Continue(());
|
||||
}
|
||||
|
||||
impl<C> ControlFlow<C, ()> {
|
||||
impl<C> 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.
|
||||
///
|
||||
|
Loading…
Reference in New Issue
Block a user