From 508fadab16ec36c57daa8f0361db60848d31c0f7 Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Sat, 23 Oct 2021 11:40:46 +0200 Subject: [PATCH 1/2] Update control_flow.rs Fix and extent ControlFlow `traverse_inorder` example 1. The existing example compiles on its own, but any usage fails to be monomorphised and so doesn't compile. Fix that by using Fn trait instead of FnMut. 2. Added an example usage of `traverse_inorder` showing how we can terminate the traversal early. Fixes #90063 --- library/core/src/ops/control_flow.rs | 29 +++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index cd2d57699c92c..ec00d0fe05b9c 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -34,17 +34,40 @@ use crate::{convert, ops}; /// } /// /// impl TreeNode { -/// pub fn traverse_inorder(&self, mut f: impl FnMut(&T) -> ControlFlow) -> ControlFlow { +/// pub fn traverse_inorder(&self, f: &impl Fn(&T) -> ControlFlow) -> ControlFlow { /// if let Some(left) = &self.left { -/// left.traverse_inorder(&mut f)?; +/// left.traverse_inorder(f)?; /// } /// f(&self.value)?; /// if let Some(right) = &self.right { -/// right.traverse_inorder(&mut f)?; +/// right.traverse_inorder(f)?; /// } /// ControlFlow::Continue(()) /// } /// } +/// +/// let node = TreeNode { +/// value: 0, +/// left: Some(Box::new(TreeNode { +/// value: 1, +/// left: None, +/// right: None +/// })), +/// right: Some(Box::new(TreeNode { +/// value: 2, +/// left: None, +/// right: None +/// })) +/// }; +/// +/// node.traverse_inorder(& |val| { +/// println!("{}", val); +/// if *val <= 0 { +/// ControlFlow::Break(()) +/// } else { +/// ControlFlow::Continue(()) +/// } +/// }); /// ``` #[stable(feature = "control_flow_enum_type", since = "1.55.0")] #[derive(Debug, Clone, Copy, PartialEq)] From f3795e27c1f4ab46626f17e027f54a96ab9ea77c Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Sat, 23 Oct 2021 11:40:46 +0200 Subject: [PATCH 2/2] Fix and extend ControlFlow `traverse_inorder` example 1. The existing example compiles on its own, but any usage fails to be monomorphised and so doesn't compile. Fix that by using a mutable reference as an input argument. 2. Added an example usage of `traverse_inorder` showing how we can terminate the traversal early. Fixes #90063 --- library/core/src/ops/control_flow.rs | 30 +++++++++++++++------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index ec00d0fe05b9c..776cea2ef791f 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -24,7 +24,7 @@ use crate::{convert, ops}; /// ``` /// /// A basic tree traversal: -/// ```no_run +/// ``` /// use std::ops::ControlFlow; /// /// pub struct TreeNode { @@ -34,7 +34,7 @@ use crate::{convert, ops}; /// } /// /// impl TreeNode { -/// pub fn traverse_inorder(&self, f: &impl Fn(&T) -> ControlFlow) -> ControlFlow { +/// pub fn traverse_inorder(&self, f: &mut impl FnMut(&T) -> ControlFlow) -> ControlFlow { /// if let Some(left) = &self.left { /// left.traverse_inorder(f)?; /// } @@ -44,30 +44,32 @@ use crate::{convert, ops}; /// } /// ControlFlow::Continue(()) /// } +/// fn leaf(value: T) -> Option>> { +/// Some(Box::new(Self { value, left: None, right: None })) +/// } /// } /// /// let node = TreeNode { /// value: 0, -/// left: Some(Box::new(TreeNode { -/// value: 1, -/// left: None, -/// right: None -/// })), +/// left: TreeNode::leaf(1), /// right: Some(Box::new(TreeNode { -/// value: 2, -/// left: None, -/// right: None +/// value: -1, +/// left: TreeNode::leaf(5), +/// right: TreeNode::leaf(2), /// })) /// }; +/// let mut sum = 0; /// -/// node.traverse_inorder(& |val| { -/// println!("{}", val); -/// if *val <= 0 { -/// ControlFlow::Break(()) +/// let res = node.traverse_inorder(&mut |val| { +/// if *val < 0 { +/// ControlFlow::Break(*val) /// } else { +/// sum += *val; /// ControlFlow::Continue(()) /// } /// }); +/// assert_eq!(res, ControlFlow::Break(-1)); +/// assert_eq!(sum, 6); /// ``` #[stable(feature = "control_flow_enum_type", since = "1.55.0")] #[derive(Debug, Clone, Copy, PartialEq)]