Skip to content

Commit a2f938a

Browse files
committed
Document that heap allocations are not guaranteed to happen, even if explicitly performed in the code
1 parent 30e49a9 commit a2f938a

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

library/core/src/alloc/global.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,19 @@ use crate::ptr;
5353
/// * `Layout` queries and calculations in general must be correct. Callers of
5454
/// this trait are allowed to rely on the contracts defined on each method,
5555
/// and implementors must ensure such contracts remain true.
56+
///
57+
/// * You may not rely on allocations actually happening, even if there are explicit
58+
/// heap allocations in the source. The optimizer may detect allocation/deallocation
59+
/// pairs that it can instead move to stack allocations/deallocations and thus never
60+
/// invoke the allocator here.
61+
/// More concretely, the following code example is unsound, irrespective of whether your
62+
/// custom allocator allows counting how many allocations have happened.
63+
///
64+
/// ```rust,ignore
65+
/// drop(Box::new(42));
66+
/// let number_of_heap_allocs = /* call private allocator API */;
67+
/// unsafe { std::intrinsics::assume(number_of_heap_allocs > 0); }
68+
/// ```
5669
#[stable(feature = "global_alloc", since = "1.28.0")]
5770
pub unsafe trait GlobalAlloc {
5871
/// Allocate memory as described by the given `layout`.

library/core/src/alloc/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,18 @@ pub unsafe trait AllocRef {
9494
/// The returned block may have a larger size than specified by `layout.size()`, and may or may
9595
/// not have its contents initialized.
9696
///
97+
/// Note that you may not rely on this method actually getting called, even if there are calls
98+
/// to it in the source. The optimizer may detect allocation/deallocation pairs that it can
99+
/// instead move to stack allocations/deallocations and thus never invoke the allocator here.
100+
/// More concretely, the following code example is unsound, irrespective of whether your
101+
/// custom allocator allows counting how many allocations have happened.
102+
///
103+
/// ```rust,ignore
104+
/// Global::dealloc(Global::alloc(some_layout));
105+
/// let number_of_heap_allocs = /* call private allocator API */;
106+
/// unsafe { std::intrinsics::assume(number_of_heap_allocs > 0); }
107+
/// ```
108+
///
97109
/// # Errors
98110
///
99111
/// Returning `Err` indicates that either memory is exhausted or `layout` does not meet

0 commit comments

Comments
 (0)