about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThe8472 <git@infinite-source.de>2021-09-17 00:24:36 +0200
committerThe8472 <git@infinite-source.de>2021-09-17 00:24:36 +0200
commitca2d2fa28391fec6e022cede26b400c85afb8c0c (patch)
tree532473844ac7fe6788b202ec0c30d74bca08c6a0
parent237bb5e0088782945d2c3146e4907e3a5e9c7c2c (diff)
downloadrust-ca2d2fa28391fec6e022cede26b400c85afb8c0c.tar.gz
rust-ca2d2fa28391fec6e022cede26b400c85afb8c0c.zip
Don't inline OnceCell initialization closures
-rw-r--r--library/core/src/lazy.rs11
1 files changed, 10 insertions, 1 deletions
diff --git a/library/core/src/lazy.rs b/library/core/src/lazy.rs
index 2c517371c2c..e6bea462fa9 100644
--- a/library/core/src/lazy.rs
+++ b/library/core/src/lazy.rs
@@ -214,7 +214,16 @@ impl<T> OnceCell<T> {
         if let Some(val) = self.get() {
             return Ok(val);
         }
-        let val = f()?;
+        /// Avoid inlining the initialization closure into the common path that fetches
+        /// the already initialized value
+        #[cold]
+        fn outlined_call<F, T, E>(f: F) -> Result<T, E>
+        where
+            F: FnOnce() -> Result<T, E>,
+        {
+            f()
+        }
+        let val = outlined_call(f)?;
         // Note that *some* forms of reentrant initialization might lead to
         // UB (see `reentrant_init` test). I believe that just removing this
         // `assert`, while keeping `set/get` would be sound, but it seems