From ca2d2fa28391fec6e022cede26b400c85afb8c0c Mon Sep 17 00:00:00 2001 From: The8472 Date: Fri, 17 Sep 2021 00:24:36 +0200 Subject: [PATCH] Don't inline OnceCell initialization closures --- library/core/src/lazy.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) 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 @@ pub fn get_or_try_init(&self, f: F) -> Result<&T, E> 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: F) -> Result + where + F: FnOnce() -> Result, + { + 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