Repository: clap-rs/clap (language: rust)

Issue:
Replace lazy_static with once_cell
Many other projects have switched from `lazy_static` to `once_cell` because it offers a macro-free solution to the same problem (with the only caveat being missing `no_std` support which I'm pretty sure is irrelevant for clap). Would you be open to a PR that does the same thing here?

In the future, the `once_cell` dependency can likely be removed in favor of [the same functionality in `std`](https://github.com/rust-lang/rust/issues/74465).


Discussion / hints:

Fix patch:
diff --git a/Cargo.toml b/Cargo.toml
index 9f23fcb07ee..4448638efa3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -73,8 +73,8 @@ color = ["atty", "termcolor"]
 suggestions = ["strsim"]
 
 # Optional
-derive = ["clap_derive", "lazy_static"]
-cargo = ["lazy_static"] # Disable if you're not using Cargo, enables Cargo-env-var-dependent macros
+derive = ["clap_derive", "once_cell"]
+cargo = ["once_cell"] # Disable if you're not using Cargo, enables Cargo-env-var-dependent macros
 wrap_help = ["terminal_size", "textwrap/terminal_size"]
 yaml = ["yaml-rust"]
 env = [] # Use environment variables during arg parsing
@@ -101,9 +101,9 @@ yaml-rust = { version = "0.4.1",  optional = true }
 atty = { version = "0.2",  optional = true }
 termcolor = { version = "1.1.1", optional = true }
 terminal_size = { version = "0.1.12", optional = true }
-lazy_static = { version = "1", optional = true }
 regex = { version = "1.0", optional = true }
 backtrace = { version = "0.3", optional = true }
+once_cell = { version = "1.12.0", optional = true }
 
 [dev-dependencies]
 regex = "1.0"
diff --git a/clap_derive/src/attrs.rs b/clap_derive/src/attrs.rs
index ae784b519e3..39f1735557a 100644
--- a/clap_derive/src/attrs.rs
+++ b/clap_derive/src/attrs.rs
@@ -552,14 +552,11 @@ impl Attrs {
                         })
                     } else {
                         quote_spanned!(ident.span()=> {
-                            clap::lazy_static::lazy_static! {
-                                static ref DEFAULT_VALUE: &'static str = {
-                                    let val: #ty = #val;
-                                    let s = ::std::string::ToString::to_string(&val);
-                                    ::std::boxed::Box::leak(s.into_boxed_str())
-                                };
-                            }
-                            *DEFAULT_VALUE
+                            static DEFAULT_VALUE: clap::once_cell::sync::Lazy<String> = clap::once_cell::sync::Lazy::new(|| {
+                                let val: #ty = #val;
+                                ::std::string::ToString::to_string(&val)
+                            });
+                            &*DEFAULT_VALUE
                         })
                     };
 
@@ -595,14 +592,11 @@ impl Attrs {
                         })
                     } else {
                         quote_spanned!(ident.span()=> {
-                            clap::lazy_static::lazy_static! {
-                                static ref DEFAULT_VALUE: &'static ::std::ffi::OsStr = {
-                                    let val: #ty = #val;
-                                    let s: ::std::ffi::OsString = val.into();
-                                    ::std::boxed::Box::leak(s.into_boxed_os_str())
-                                };
-                            }
-                            *DEFAULT_VALUE
+                            static DEFAULT_VALUE: clap::once_cell::sync::Lazy<::std::ffi::OsString> = clap::once_cell::sync::Lazy::new(|| {
+                                let val: #ty = #val;
+                                ::std::ffi::OsString = val.into()
+                            });
+                            &*DEFAULT_VALUE
                         })
                     };
 
diff --git a/src/lib.rs b/src/lib.rs
index ae402e3548a..40019a92cee 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -72,7 +72,7 @@ pub use ValueEnum as ArgEnum;
 
 #[cfg(any(feature = "derive", feature = "cargo"))]
 #[doc(hidden)]
-pub use lazy_static;
+pub use once_cell;
 
 #[macro_use]
 #[allow(missing_docs)]
diff --git a/src/macros.rs b/src/macros.rs
index 0bbf6a14d46..8f91c85e838 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -235,9 +235,8 @@ macro_rules! crate_version {
 #[macro_export]
 macro_rules! crate_authors {
     ($sep:expr) => {{
-        clap::lazy_static::lazy_static! {
-            static ref CACHED: String = env!("CARGO_PKG_AUTHORS").replace(':', $sep);
-        }
+        static CACHED: clap::once_cell::sync::Lazy<String> =
+            clap::once_cell::sync::Lazy::new(|| env!("CARGO_PKG_AUTHORS").replace(':', $sep));
 
         let s: &'static str = &*CACHED;
         s


Test patch: