Skip to content

Commit 9afdbe6

Browse files
committed
Document become keyword
1 parent 7cf2e9a commit 9afdbe6

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

library/std/src/keyword_docs.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,6 +1228,69 @@ mod ref_keyword {}
12281228
/// ```
12291229
mod return_keyword {}
12301230

1231+
#[doc(keyword = "become")]
1232+
//
1233+
/// Perform a tail-call of a function.
1234+
///
1235+
/// A `become` transfers the execution flow to a function in such a way, that
1236+
/// returning from the callee returns to the caller of the current function:
1237+
///
1238+
/// ```
1239+
/// #![feature(explicit_tail_calls)]
1240+
///
1241+
/// fn a() -> u32 {
1242+
/// become b();
1243+
/// }
1244+
///
1245+
/// fn b() -> u32 {
1246+
/// return 2; // this return directly returns to the main ---+
1247+
/// } // |
1248+
/// // |
1249+
/// fn main() { // |
1250+
/// let res = a(); // <--------------------------------------+
1251+
/// assert_eq!(res, 2);
1252+
/// }
1253+
/// ```
1254+
///
1255+
/// This is an optimization that allows function calls to not exhaust the stack.
1256+
/// This is most useful for (mutually) recursive algorithms, but may be used in
1257+
/// other cases too.
1258+
///
1259+
/// It is guaranteed that the call will not cause unbounded stack growth if it
1260+
/// is part of a recursive cycle in the call graph.
1261+
///
1262+
/// For example note that the functions `halt` and `halt_loop` below are
1263+
/// identical, they both do nothing, forever. However `stack_overflow` is
1264+
/// different from them, even though it is written almost identically to
1265+
/// `halt`, `stack_overflow` exhausts the stack and so causes a stack
1266+
/// overflow, instead of running forever.
1267+
///
1268+
///
1269+
/// ```
1270+
/// #![feature(explicit_tail_calls)]
1271+
///
1272+
/// # #[allow(unreachable_code)]
1273+
/// fn halt() -> ! {
1274+
/// become halt()
1275+
/// }
1276+
///
1277+
/// fn halt_loop() -> ! {
1278+
/// loop {}
1279+
/// }
1280+
///
1281+
/// # #[allow(unconditional_recursion)]
1282+
/// fn stack_overflow() -> ! {
1283+
/// stack_overflow() // implicit return
1284+
/// }
1285+
/// ```
1286+
///
1287+
/// Note that from the algorithmic standpoint loops and tail-calls are
1288+
/// interchangeable, you can always rewrite a loop to use tail-calls
1289+
/// instead and vice versa. They are, however, very different in the code
1290+
/// structure, so sometimes one approach can make more sense that the other.
1291+
#[cfg(not(bootstrap))]
1292+
mod become_keyword {}
1293+
12311294
#[doc(keyword = "self")]
12321295
//
12331296
/// The receiver of a method, or the current module.

0 commit comments

Comments
 (0)