From 820c1c50d850d8b51a55d1550de6cd200417d632 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Wed, 10 May 2023 09:19:31 +0000 Subject: [PATCH 1/2] Document `become` keyword --- library/std/src/keyword_docs.rs | 63 +++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs index eb46f4e54bb67..27dfda7480ee3 100644 --- a/library/std/src/keyword_docs.rs +++ b/library/std/src/keyword_docs.rs @@ -1228,6 +1228,69 @@ mod ref_keyword {} /// ``` mod return_keyword {} +#[doc(keyword = "become")] +// +/// Perform a tail-call of a function. +/// +/// A `become` transfers the execution flow to a function in such a way, that +/// returning from the callee returns to the caller of the current function: +/// +/// ``` +/// #![feature(explicit_tail_calls)] +/// +/// fn a() -> u32 { +/// become b(); +/// } +/// +/// fn b() -> u32 { +/// return 2; // this return directly returns to the main ---+ +/// } // | +/// // | +/// fn main() { // | +/// let res = a(); // <--------------------------------------+ +/// assert_eq!(res, 2); +/// } +/// ``` +/// +/// This is an optimization that allows function calls to not exhaust the stack. +/// This is most useful for (mutually) recursive algorithms, but may be used in +/// other cases too. +/// +/// It is guaranteed that the call will not cause unbounded stack growth if it +/// is part of a recursive cycle in the call graph. +/// +/// For example note that the functions `halt` and `halt_loop` below are +/// identical, they both do nothing, forever. However `stack_overflow` is +/// different from them, even though it is written almost identically to +/// `halt`, `stack_overflow` exhausts the stack and so causes a stack +/// overflow, instead of running forever. +/// +/// +/// ``` +/// #![feature(explicit_tail_calls)] +/// +/// # #[allow(unreachable_code)] +/// fn halt() -> ! { +/// become halt() +/// } +/// +/// fn halt_loop() -> ! { +/// loop {} +/// } +/// +/// # #[allow(unconditional_recursion)] +/// fn stack_overflow() -> ! { +/// stack_overflow() // implicit return +/// } +/// ``` +/// +/// Note that from the algorithmic standpoint loops and tail-calls are +/// interchangeable, you can always rewrite a loop to use tail-calls +/// instead and vice versa. They are, however, very different in the code +/// structure, so sometimes one approach can make more sense that the other. +#[cfg(not(bootstrap))] +mod become_keyword {} + #[doc(keyword = "self")] // /// The receiver of a method, or the current module. From 0888a94e7ad08656343d6d1e736d42179ddeb913 Mon Sep 17 00:00:00 2001 From: Waffle Maybe Date: Wed, 28 Jun 2023 18:49:26 +0400 Subject: [PATCH 2/2] Fix typos Co-authored-by: Rageking8 <106309953+Rageking8@users.noreply.github.com> --- library/std/src/keyword_docs.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs index 27dfda7480ee3..d2c5836972278 100644 --- a/library/std/src/keyword_docs.rs +++ b/library/std/src/keyword_docs.rs @@ -1260,7 +1260,7 @@ mod return_keyword {} /// is part of a recursive cycle in the call graph. /// /// For example note that the functions `halt` and `halt_loop` below are -/// identical, they both do nothing, forever. However `stack_overflow` is +/// identical, they both do nothing, forever. However, `stack_overflow` is /// different from them, even though it is written almost identically to /// `halt`, `stack_overflow` exhausts the stack and so causes a stack /// overflow, instead of running forever. @@ -1284,10 +1284,10 @@ mod return_keyword {} /// } /// ``` /// -/// Note that from the algorithmic standpoint loops and tail-calls are +/// Note that from an algorithmic standpoint, loops and tail-calls are /// interchangeable, you can always rewrite a loop to use tail-calls /// instead and vice versa. They are, however, very different in the code -/// structure, so sometimes one approach can make more sense that the other. +/// structure, so sometimes one approach can make more sense than the other. #[cfg(not(bootstrap))] mod become_keyword {}