From fac272688e9d561b1fff71621323682d23e4c31d Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 4 Sep 2020 00:59:41 -0700 Subject: [PATCH] Use ops::ControlFlow in graph::iterate --- .../rustc_data_structures/src/graph/iterate/mod.rs | 13 +++++-------- compiler/rustc_data_structures/src/lib.rs | 1 + compiler/rustc_mir_build/src/lib.rs | 1 + compiler/rustc_mir_build/src/lints.rs | 6 +++--- library/core/src/iter/adapters/mod.rs | 2 +- library/core/src/iter/traits/double_ended.rs | 2 +- library/core/src/ops/control_flow.rs | 7 +++++++ 7 files changed, 19 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_data_structures/src/graph/iterate/mod.rs b/compiler/rustc_data_structures/src/graph/iterate/mod.rs index 64ff6130ddf..8946666d961 100644 --- a/compiler/rustc_data_structures/src/graph/iterate/mod.rs +++ b/compiler/rustc_data_structures/src/graph/iterate/mod.rs @@ -87,11 +87,8 @@ where } /// Allows searches to terminate early with a value. -#[derive(Clone, Copy, Debug)] -pub enum ControlFlow { - Break(T), - Continue, -} +// 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. /// @@ -260,12 +257,12 @@ where _node: G::Node, _prior_status: Option, ) -> ControlFlow { - ControlFlow::Continue + ControlFlow::CONTINUE } /// Called after all nodes reachable from this one have been examined. fn node_settled(&mut self, _node: G::Node) -> ControlFlow { - ControlFlow::Continue + ControlFlow::CONTINUE } /// Behave as if no edges exist from `source` to `target`. @@ -290,7 +287,7 @@ where ) -> ControlFlow { match prior_status { Some(NodeStatus::Visited) => ControlFlow::Break(()), - _ => ControlFlow::Continue, + _ => ControlFlow::CONTINUE, } } } diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index de4e7a13424..88c160e93b6 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -8,6 +8,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![allow(incomplete_features)] +#![feature(control_flow_enum)] #![feature(in_band_lifetimes)] #![feature(unboxed_closures)] #![feature(generators)] diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 313bb979a51..e55180ff4be 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -6,6 +6,7 @@ #![feature(box_syntax)] #![feature(const_fn)] #![feature(const_panic)] +#![feature(control_flow_enum)] #![feature(crate_visibility_modifier)] #![feature(bool_to_option)] #![feature(or_patterns)] diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs index fd2d5a4abd4..b85ada15ed5 100644 --- a/compiler/rustc_mir_build/src/lints.rs +++ b/compiler/rustc_mir_build/src/lints.rs @@ -117,7 +117,7 @@ impl<'mir, 'tcx> TriColorVisitor<&'mir Body<'tcx>> for Search<'mir, 'tcx> { // A diverging InlineAsm is treated as non-recursing TerminatorKind::InlineAsm { destination, .. } => { if destination.is_some() { - ControlFlow::Continue + ControlFlow::CONTINUE } else { ControlFlow::Break(NonRecursive) } @@ -131,7 +131,7 @@ impl<'mir, 'tcx> TriColorVisitor<&'mir Body<'tcx>> for Search<'mir, 'tcx> { | TerminatorKind::FalseEdge { .. } | TerminatorKind::FalseUnwind { .. } | TerminatorKind::Goto { .. } - | TerminatorKind::SwitchInt { .. } => ControlFlow::Continue, + | TerminatorKind::SwitchInt { .. } => ControlFlow::CONTINUE, } } @@ -144,7 +144,7 @@ impl<'mir, 'tcx> TriColorVisitor<&'mir Body<'tcx>> for Search<'mir, 'tcx> { } } - ControlFlow::Continue + ControlFlow::CONTINUE } fn ignore_edge(&mut self, bb: BasicBlock, target: BasicBlock) -> bool { diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs index c3f1269401a..d89874eb7a9 100644 --- a/library/core/src/iter/adapters/mod.rs +++ b/library/core/src/iter/adapters/mod.rs @@ -1273,7 +1273,7 @@ where ) -> impl FnMut((), T) -> ControlFlow<(), B> + '_ { move |(), x| match f(x) { Some(x) => ControlFlow::Break(x), - None => ControlFlow::Continue(()), + None => ControlFlow::CONTINUE, } } diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs index f50807116bd..a025bc8b560 100644 --- a/library/core/src/iter/traits/double_ended.rs +++ b/library/core/src/iter/traits/double_ended.rs @@ -310,7 +310,7 @@ pub trait DoubleEndedIterator: Iterator { mut predicate: impl FnMut(&T) -> bool, ) -> impl FnMut((), T) -> ControlFlow<(), T> { move |(), x| { - if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::Continue(()) } + if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE } } } diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index 687d423dcb6..3f0cce4e18a 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -65,3 +65,10 @@ impl ControlFlow { } } } + +impl 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. + #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] + pub const CONTINUE: Self = ControlFlow::Continue(()); +}