diff options
| author | oli <github35764891676564198441@oli-obk.de> | 2020-11-19 11:05:15 +0000 |
|---|---|---|
| committer | oli <github35764891676564198441@oli-obk.de> | 2020-11-19 11:05:15 +0000 |
| commit | a2f938ac52d8d1b3ee1cf94f18705e95f28ca0b8 (patch) | |
| tree | f4ad9440f976476ec9e1d275c3fe55ea5c7d95da | |
| parent | 30e49a9ead550551e879af64ba91a0316da1c422 (diff) | |
| download | rust-a2f938ac52d8d1b3ee1cf94f18705e95f28ca0b8.tar.gz rust-a2f938ac52d8d1b3ee1cf94f18705e95f28ca0b8.zip | |
Document that heap allocations are not guaranteed to happen, even if explicitly performed in the code
| -rw-r--r-- | library/core/src/alloc/global.rs | 13 | ||||
| -rw-r--r-- | library/core/src/alloc/mod.rs | 12 |
2 files changed, 25 insertions, 0 deletions
diff --git a/library/core/src/alloc/global.rs b/library/core/src/alloc/global.rs index c198797e650..65406125a3d 100644 --- a/library/core/src/alloc/global.rs +++ b/library/core/src/alloc/global.rs @@ -53,6 +53,19 @@ use crate::ptr; /// * `Layout` queries and calculations in general must be correct. Callers of /// this trait are allowed to rely on the contracts defined on each method, /// 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. +/// More concretely, the following code example is unsound, irrespective of whether your +/// custom allocator allows counting how many allocations have happened. +/// +/// ```rust,ignore +/// drop(Box::new(42)); +/// let number_of_heap_allocs = /* call private allocator API */; +/// unsafe { std::intrinsics::assume(number_of_heap_allocs > 0); } +/// ``` #[stable(feature = "global_alloc", since = "1.28.0")] pub unsafe trait GlobalAlloc { /// Allocate memory as described by the given `layout`. diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs index c61c19cc7d1..47d5ad9ad56 100644 --- a/library/core/src/alloc/mod.rs +++ b/library/core/src/alloc/mod.rs @@ -94,6 +94,18 @@ pub unsafe trait AllocRef { /// The returned block may have a larger size than specified by `layout.size()`, and may or may /// not have its contents initialized. /// + /// Note that you may not rely on this method actually getting called, even if there are calls + /// 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. + /// More concretely, the following code example is unsound, irrespective of whether your + /// custom allocator allows counting how many allocations have happened. + /// + /// ```rust,ignore + /// Global::dealloc(Global::alloc(some_layout)); + /// let number_of_heap_allocs = /* call private allocator API */; + /// unsafe { std::intrinsics::assume(number_of_heap_allocs > 0); } + /// ``` + /// /// # Errors /// /// Returning `Err` indicates that either memory is exhausted or `layout` does not meet |
