about summary refs log tree commit diff
diff options
context:
space:
mode:
authoroli <github35764891676564198441@oli-obk.de>2020-11-19 11:05:15 +0000
committeroli <github35764891676564198441@oli-obk.de>2020-11-19 11:05:15 +0000
commita2f938ac52d8d1b3ee1cf94f18705e95f28ca0b8 (patch)
treef4ad9440f976476ec9e1d275c3fe55ea5c7d95da
parent30e49a9ead550551e879af64ba91a0316da1c422 (diff)
downloadrust-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.rs13
-rw-r--r--library/core/src/alloc/mod.rs12
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