@@ -1228,6 +1228,69 @@ mod ref_keyword {}
1228
1228
/// ```
1229
1229
mod return_keyword { }
1230
1230
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
+
1231
1294
#[ doc( keyword = "self" ) ]
1232
1295
//
1233
1296
/// The receiver of a method, or the current module.
0 commit comments