Skip to content
Merged
Changes from 3 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
31b3915
Some hygiene doc improvements
camsteffen Sep 3, 2025
faf0e14
Update the arm-* and aarch64-* platform docs.
thejpster Sep 7, 2025
f1abb70
Pick up changes from robamu that I missed.
thejpster Sep 10, 2025
b152974
tidy: check that error messages don't start with a capitalized letter
scrabsha Sep 3, 2025
3d3769a
Add missing links in platform-support.md
thejpster Sep 10, 2025
5a74222
Add aarch64-unknown-none to SUMMARY.md
thejpster Sep 10, 2025
409a1fb
Update aarch64-unknown-none.md to include -softfloat too
thejpster Sep 10, 2025
1621ce6
Cleanups from review comments.
thejpster Sep 11, 2025
a0d1f5a
Insert missing word.
thejpster Sep 11, 2025
5d8e41b
Revert "Constify SystemTime methods"
RalfJung Sep 12, 2025
4383a4f
Remove bullet points from the target maintainer list for the arm bare…
thejpster Sep 12, 2025
ea661e9
Re-order and re-work the aarch64-unknown-none platform support page.
thejpster Sep 12, 2025
2baa39e
also apply revert to wasip2
RalfJung Sep 13, 2025
d3b3bb9
Fix small typo in check-cfg.md
mikysett Sep 13, 2025
cc92254
Document `become` keyword
WaffleLapkin May 10, 2023
f13c8c2
fixup `become` kw documentation wrt `#[track_caller]`
WaffleLapkin Sep 13, 2025
f21d3fb
fix Condvar::wait_timeout docs
RalfJung Sep 13, 2025
afd324a
Note that these targets are bare-metal.
thejpster Sep 13, 2025
61a3593
c-variadic: document `core::ffi::VaArgSafe`
folkertdev Sep 11, 2025
a84bb32
c-variadic: test `...` with naked functions
folkertdev Sep 13, 2025
d28c31a
c-variadic: check that c-variadic functions cannot be tail-called
folkertdev Sep 13, 2025
a107ea1
c-variadic: check that inline attributes are accepted on c-variadic f…
folkertdev Sep 13, 2025
e9c80c7
Rollup merge of #113095 - WaffleLapkin:document_becoming_unuwuable, r…
jhpratt Sep 13, 2025
4ee860f
Rollup merge of #146159 - camsteffen:hygiene-docs, r=petrochenkov
jhpratt Sep 13, 2025
141cb38
Rollup merge of #146171 - scrabsha:push-wovnxxwltsun, r=WaffleLapkin
jhpratt Sep 13, 2025
04f17d8
Rollup merge of #146419 - thejpster:update-arm-target-docs, r=working…
jhpratt Sep 13, 2025
5d56e52
Rollup merge of #146473 - RalfJung:system-time-deconst, r=workingjubilee
jhpratt Sep 13, 2025
392d2fa
Rollup merge of #146506 - mikysett:patch-1, r=Urgau
jhpratt Sep 13, 2025
08db938
Rollup merge of #146517 - RalfJung:wait-timeout, r=joboet
jhpratt Sep 13, 2025
da1c27d
Rollup merge of #146521 - folkertdev:document-va-arg-safe, r=workingj…
jhpratt Sep 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions library/std/src/keyword_docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1257,6 +1257,108 @@ mod ref_keyword {}
/// [`async`]: ../std/keyword.async.html
mod return_keyword {}

#[doc(keyword = "become")]
//
/// Perform a tail-call of a function.
///
/// <div class="warning">
///
/// `feature(explicit_tail_calls)` is currently incomplete and may not work properly.
/// </div>
///
/// When tail calling a function, instead of its stack frame being added to the
/// stack, the stack frame of the caller is directly replaced with the callee's.
/// This means that as long as a loop in a call graph only uses tail calls, the
/// stack growth will be bounded.
///
/// This is useful for writing functional-style code (since it prevents recursion
/// from exhausting resources) or for code optimization (since a tail call
/// *might* be cheaper than a normal call, tail calls can be used in a similar
/// manner to computed goto).
///
/// Example of using `become` to implement functional-style `fold`:
/// ```
/// #![feature(explicit_tail_calls)]
/// #![expect(incomplete_features)]
///
/// fn fold<T: Copy, S>(slice: &[T], init: S, f: impl Fn(S, T) -> S) -> S {
/// match slice {
/// // without `become`, on big inputs this could easily overflow the
/// // stack. using a tail call guarantees that the stack will not grow unboundedly
/// [first, rest @ ..] => become fold(rest, f(init, *first), f),
/// [] => init,
/// }
/// }
/// ```
///
/// Compilers can already perform "tail call optimization" -- they can replace normal
/// calls with tail calls, although there are no guarantees that this will be done.
/// However, to perform TCO, the call needs to be the last thing that happens
/// in the functions and be returned from it. This requirement is often broken
/// by drop code for locals, which is run after computing the return expression:
///
/// ```
/// fn example() {
/// let string = "meow".to_owned();
/// println!("{string}");
/// return help(); // this is *not* the last thing that happens in `example`...
/// }
///
/// // ... because it is desugared to this:
/// fn example_desugared() {
/// let string = "meow".to_owned();
/// println!("{string}");
/// let tmp = help();
/// drop(string);
/// return tmp;
/// }
///
/// fn help() {}
/// ```
///
/// For this reason, `become` also changes the drop order, such that locals are
/// dropped *before* evaluating the call.
///
/// In order to guarantee that the compiler can perform a tail call, `become`
/// currently has these requirements:
/// 1. callee and caller must have the same ABI, arguments, and return type
/// 2. callee and caller must not have varargs
/// 3. caller must not be marked with `#[track_caller]`
/// - callee is allowed to be marked with `#[track_caller]` as otherwise
/// adding `#[track_caller]` would be a breaking change. if callee is
/// marked with `#[track_caller]` a tail call is not guaranteed.
/// 4. callee and caller cannot be a closure
/// (unless it's coerced to a function pointer)
///
/// It is possible to tail-call a function pointer:
/// ```
/// #![feature(explicit_tail_calls)]
/// #![expect(incomplete_features)]
///
/// #[derive(Copy, Clone)]
/// enum Inst { Inc, Dec }
///
/// fn dispatch(stream: &[Inst], state: u32) -> u32 {
/// const TABLE: &[fn(&[Inst], u32) -> u32] = &[increment, decrement];
/// match stream {
/// [inst, rest @ ..] => become TABLE[*inst as usize](rest, state),
/// [] => state,
/// }
/// }
///
/// fn increment(stream: &[Inst], state: u32) -> u32 {
/// become dispatch(stream, state + 1)
/// }
///
/// fn decrement(stream: &[Inst], state: u32) -> u32 {
/// become dispatch(stream, state - 1)
/// }
///
/// let program = &[Inst::Inc, Inst::Inc, Inst::Dec, Inst::Inc];
/// assert_eq!(dispatch(program, 0), 2);
/// ```
mod become_keyword {}

#[doc(keyword = "self")]
//
/// The receiver of a method, or the current module.
Expand Down