Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document that heap allocations are not guaranteed to happen, even if explicitly performed in the code #79045

Merged
15 changes: 9 additions & 6 deletions library/core/src/alloc/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,12 @@ use crate::ptr;
/// and implementors must ensure such contracts remain true.
///
/// * You may not rely on allocations actually happening, even if there are explicit
/// heap allocations in the source. The optimizer may detect allocation/deallocation
/// pairs that it can instead move to stack allocations/deallocations and thus never
/// invoke the allocator here.
/// heap allocations in the source.
/// The optimizer may detect unused allocations that it can either
/// eliminate entirely or move to the stack and thus never invoke the allocator here. The
oli-obk marked this conversation as resolved.
Show resolved Hide resolved
/// optimizer may further assume that allocation is infallible, so code that used to fail due
/// to allocator failures may now suddenly work because the optimizer worked around the
/// need for an allocation.
/// More concretely, the following code example is unsound, irrespective of whether your
oli-obk marked this conversation as resolved.
Show resolved Hide resolved
/// custom allocator allows counting how many allocations have happened.
///
Expand All @@ -67,10 +70,10 @@ use crate::ptr;
/// unsafe { std::intrinsics::assume(number_of_heap_allocs > 0); }
/// ```
///
/// Note that allocation/deallocation pairs being moved to the stack is not the only
/// Note that the optimizations mentioned above are not the only
/// optimization that can be applied. You may generally not rely on heap allocations
/// happening, if they can be removed without changing program behaviour.
/// Whether allocations happen or not is not part of the program behaviour, even if it
/// happening if they can be removed without changing program behavior.
/// Whether allocations happen or not is not part of the program behavior, even if it
/// could be detected via an allocator that tracks allocations by printing or otherwise
/// having side effects.
#[stable(feature = "global_alloc", since = "1.28.0")]
Expand Down
14 changes: 12 additions & 2 deletions library/core/src/alloc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,11 @@ pub unsafe trait AllocRef {
/// not have its contents initialized.
///
/// Note that you may not rely on this method actually getting called, even if there are calls
oli-obk marked this conversation as resolved.
Show resolved Hide resolved
/// to it in the source. The optimizer may detect allocation/deallocation pairs that it can
/// instead move to stack allocations/deallocations and thus never invoke the allocator here.
/// to it in the source. The optimizer may detect unused allocations that it can either
/// eliminate entirely or move to the stack and thus never invoke the allocator here. The
oli-obk marked this conversation as resolved.
Show resolved Hide resolved
/// optimizer may further assume that allocation is infallible, so code that used to fail due
/// to allocator failures may now suddenly work because the optimizer worked around the
/// need for an allocation.
/// More concretely, the following code example is unsound, irrespective of whether your
/// custom allocator allows counting how many allocations have happened.
///
Expand All @@ -106,6 +109,13 @@ pub unsafe trait AllocRef {
/// unsafe { std::intrinsics::assume(number_of_heap_allocs > 0); }
/// ```
///
/// Note that the optimizations mentioned above are not the only
/// optimization that can be applied. You may generally not rely on heap allocations
/// happening if they can be removed without changing program behavior.
/// Whether allocations happen or not is not part of the program behavior, even if it
/// could be detected via an allocator that tracks allocations by printing or otherwise
/// having side effects.
///
/// # Errors
///
/// Returning `Err` indicates that either memory is exhausted or `layout` does not meet
Expand Down