diff --git a/Cargo.lock b/Cargo.lock index c3f385609e6..170caf849b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1367,7 +1367,7 @@ version = "0.3.5" dependencies = [ "icu", "icu_collections", - "lazy_static", + "once_cell", "toml", "wasmer", "wasmer-wasi", @@ -1478,10 +1478,10 @@ dependencies = [ "icu_segmenter", "icu_timezone", "itertools", - "lazy_static", "log", "memchr", "ndarray", + "once_cell", "postcard", "rayon", "serde", @@ -2319,9 +2319,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.17.1" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "oorandom" diff --git a/components/collections/codepointtrie_builder/Cargo.toml b/components/collections/codepointtrie_builder/Cargo.toml index a271ecff6dd..b140f947c72 100644 --- a/components/collections/codepointtrie_builder/Cargo.toml +++ b/components/collections/codepointtrie_builder/Cargo.toml @@ -32,7 +32,7 @@ independent = true [features] # Use the wasm builder default = ["wasm"] -wasm = ["wasmer", "wasmer-wasi"] +wasm = ["wasmer", "wasmer-wasi", "once_cell"] # Use the ICU4C builder # needs the ICU4C_LIB_PATH variable set and pointing to an ICU4C lib folder # containing dylibs. If you want to use staticlibs, set ICU4C_LINK_STATICALLY. @@ -42,8 +42,8 @@ icu4c = ["zerovec"] [dependencies] icu_collections = { version = "1.2.0", path = "..", features = ["serde"] } zerovec = { version = "0.9.4", path = "../../../utils/zerovec", optional = true } -lazy_static = "1.4.0" toml = "0.5" +once_cell = { version = "1.18.0", optional = true } [dependencies.wasmer] version = "2.2.1" diff --git a/components/collections/codepointtrie_builder/src/wasm.rs b/components/collections/codepointtrie_builder/src/wasm.rs index 1b95ff66500..b692d6626b1 100644 --- a/components/collections/codepointtrie_builder/src/wasm.rs +++ b/components/collections/codepointtrie_builder/src/wasm.rs @@ -6,16 +6,14 @@ use crate::CodePointTrieBuilder; use crate::CodePointTrieBuilderData; use icu_collections::codepointtrie::TrieType; use icu_collections::codepointtrie::TrieValue; -use lazy_static::lazy_static; +use once_cell::sync::OnceCell; use wasmer::{Instance, Module, Store}; use wasmer_wasi::{Pipe, WasiState}; const WASM_BYTES: &[u8] = include_bytes!("../list_to_ucptrie.wasm"); -lazy_static! { - static ref STORE: Store = Store::default(); - static ref MODULE: Module = Module::new(&STORE, WASM_BYTES).expect("valid WASM"); -} +static STORE: OnceCell = OnceCell::new(); +static MODULE: OnceCell = OnceCell::new(); pub(crate) fn run_wasm(builder: &CodePointTrieBuilder) -> String where @@ -39,9 +37,14 @@ where .finalize() .expect("valid arguments + in-memory filesystem"); + let module = MODULE.get_or_init(|| { + let store = STORE.get_or_init(Store::default); + Module::new(store, WASM_BYTES).expect("valid WASM") + }); + // Create the WebAssembly instance with the module and the WasiState - let import_object = wasi_env.import_object(&MODULE).expect("walid wasm file"); - let instance = Instance::new(&MODULE, &import_object).expect("valid wasm file"); + let import_object = wasi_env.import_object(module).expect("walid wasm file"); + let instance = Instance::new(module, &import_object).expect("valid wasm file"); // To write to the stdin, we need a mutable reference to the pipe // diff --git a/provider/datagen/Cargo.toml b/provider/datagen/Cargo.toml index 550d0e5cd24..c09e32f4a00 100644 --- a/provider/datagen/Cargo.toml +++ b/provider/datagen/Cargo.toml @@ -72,7 +72,6 @@ syn = {version = "2", features = ["parsing"], optional = true } displaydoc = { version = "0.2.3", default-features = false } elsa = "1.7" itertools = "0.10" -lazy_static = "1" log = "0.4" memchr = "2.5.0" ndarray = { version = "0.15.5", default-features = false } @@ -89,6 +88,7 @@ ureq = { version = "2", optional = true } clap = { version = "4", optional = true, features = ["derive"] } eyre = { version = "0.6", optional = true } simple_logger = { version = "4.1.0", default-features = false, optional = true } +once_cell = "1.18.0" [dev-dependencies] crlify = { version = "1.0.1", path = "../../utils/crlify" } diff --git a/provider/datagen/src/lib.rs b/provider/datagen/src/lib.rs index b72a262c8c9..3ab1bc5c0cb 100644 --- a/provider/datagen/src/lib.rs +++ b/provider/datagen/src/lib.rs @@ -190,20 +190,25 @@ impl DatagenProvider { #[cfg(test)] pub fn for_test() -> Self { + use once_cell::sync::OnceCell; + + static TEST_PROVIDER: OnceCell = OnceCell::new(); // Singleton so that all instantiations share the same cache. - lazy_static::lazy_static! { - static ref TEST_PROVIDER: DatagenProvider = { - let data_root = std::path::Path::new(core::env!("CARGO_MANIFEST_DIR")).join("tests/data"); + TEST_PROVIDER + .get_or_init(|| { + let data_root = + std::path::Path::new(core::env!("CARGO_MANIFEST_DIR")).join("tests/data"); DatagenProvider { // This is equivalent to `latest_tested` for the files defined in // `tools/testdata-scripts/globs.rs.data`. source: SourceData::offline() - .with_cldr(data_root.join("cldr"), Default::default()).unwrap() - .with_icuexport(data_root.join("icuexport")).unwrap(), + .with_cldr(data_root.join("cldr"), Default::default()) + .unwrap() + .with_icuexport(data_root.join("icuexport")) + .unwrap(), } - }; - } - TEST_PROVIDER.clone() + }) + .clone() } pub(crate) fn filter_data_locales( diff --git a/provider/datagen/src/registry.rs b/provider/datagen/src/registry.rs index fdaf0aabe89..5ee4913788c 100644 --- a/provider/datagen/src/registry.rs +++ b/provider/datagen/src/registry.rs @@ -42,8 +42,10 @@ macro_rules! registry { /// ); /// ``` pub fn key>(string: S) -> Option { - lazy_static::lazy_static! { - static ref LOOKUP: std::collections::HashMap<&'static str, Result> = [ + use once_cell::sync::OnceCell; + static LOOKUP: OnceCell>> = OnceCell::new(); + let lookup = LOOKUP.get_or_init(|| { + [ ("core/helloworld@1", Ok(icu_provider::hello_world::HelloWorldV1Marker::KEY)), $( $( @@ -55,10 +57,10 @@ macro_rules! registry { )+ ] .into_iter() - .collect(); - } + .collect() + }); let path = string.as_ref(); - match LOOKUP.get(path).copied() { + match lookup.get(path).copied() { None => { log::warn!("Unknown key {path:?}"); None diff --git a/provider/datagen/src/transform/cldr/datetime/mod.rs b/provider/datagen/src/transform/cldr/datetime/mod.rs index f3921b97d1c..d42e1eaec97 100644 --- a/provider/datagen/src/transform/cldr/datetime/mod.rs +++ b/provider/datagen/src/transform/cldr/datetime/mod.rs @@ -11,7 +11,7 @@ use icu_locid::{ }; use icu_provider::datagen::IterableDataProvider; use icu_provider::prelude::*; -use lazy_static::lazy_static; +use once_cell::sync::OnceCell; use std::collections::HashMap; use std::collections::HashSet; use std::str::FromStr; @@ -21,21 +21,25 @@ mod skeletons; mod symbols; pub mod week_data; -lazy_static! { - // BCP-47 value -> CLDR identifier - static ref SUPPORTED_CALS: HashMap = [ - (value!("gregory"), "gregorian"), - (value!("buddhist"), "buddhist"), - (value!("japanese"), "japanese"), - (value!("japanext"), "japanese"), - (value!("coptic"), "coptic"), - (value!("indian"), "indian"), - (value!("persian"), "persian"), - (value!("ethiopic"), "ethiopic"), - (value!("roc"), "roc"), - ] - .into_iter() - .collect(); +pub static SUPPORTED_CALS: OnceCell> = + OnceCell::new(); + +fn supported_cals() -> &'static HashMap { + SUPPORTED_CALS.get_or_init(|| { + [ + (value!("gregory"), "gregorian"), + (value!("buddhist"), "buddhist"), + (value!("japanese"), "japanese"), + (value!("japanext"), "japanese"), + (value!("coptic"), "coptic"), + (value!("indian"), "indian"), + (value!("persian"), "persian"), + (value!("ethiopic"), "ethiopic"), + (value!("roc"), "roc"), + ] + .into_iter() + .collect() + }) } macro_rules! impl_data_provider { @@ -58,7 +62,7 @@ macro_rules! impl_data_provider { value!($calendared) }; - let cldr_cal = SUPPORTED_CALS + let cldr_cal = supported_cals() .get(&calendar) .ok_or_else(|| DataErrorKind::MissingLocale.into_error())?; @@ -230,7 +234,7 @@ macro_rules! impl_data_provider { fn supported_locales(&self) -> Result, DataError> { let mut r = Vec::new(); if $calendared == "locale" { - for (cal_value, cldr_cal) in &*SUPPORTED_CALS { + for (cal_value, cldr_cal) in supported_cals() { r.extend( self.source .cldr()? @@ -253,7 +257,7 @@ macro_rules! impl_data_provider { } else { value!($calendared) }; - let cldr_cal = SUPPORTED_CALS + let cldr_cal = supported_cals() .get(&calendar) .ok_or_else(|| DataErrorKind::MissingLocale.into_error())?; r.extend( diff --git a/provider/datagen/src/transform/cldr/list/mod.rs b/provider/datagen/src/transform/cldr/list/mod.rs index 09dede59cf4..b06039cba3d 100644 --- a/provider/datagen/src/transform/cldr/list/mod.rs +++ b/provider/datagen/src/transform/cldr/list/mod.rs @@ -7,7 +7,7 @@ use icu_list::provider::*; use icu_locid::subtags::language; use icu_provider::datagen::IterableDataProvider; use icu_provider::prelude::*; -use lazy_static::lazy_static; +use once_cell::sync::OnceCell; use std::borrow::Cow; fn load>>( @@ -51,29 +51,33 @@ fn load>>( if langid.language == language!("es") { if M::KEY == AndListV1Marker::KEY || M::KEY == UnitListV1Marker::KEY { - lazy_static! { - // Starts with i or (hi but not hia/hie) - static ref I_SOUND: SerdeDFA<'static> = SerdeDFA::new( - Cow::Borrowed("i|hi([^ae]|$)") - ).expect("Valid regex"); - } + static I_SOUND: OnceCell> = OnceCell::new(); + + // Starts with i or (hi but not hia/hie) + let i_sound = I_SOUND.get_or_init(|| { + SerdeDFA::new(Cow::Borrowed("i|hi([^ae]|$)")).expect("Valid regex") + }); + // Replace " y " with " e " before /i/ sounds. // https://unicode.org/reports/tr35/tr35-general.html#:~:text=important.%20For%20example%3A-,Spanish,AND,-Use%20%E2%80%98e%E2%80%99%20instead patterns - .make_conditional("{0} y {1}", &I_SOUND, "{0} e {1}") + .make_conditional("{0} y {1}", i_sound, "{0} e {1}") .expect("valid pattern"); } else if M::KEY == OrListV1Marker::KEY { - lazy_static! { - // Starts with o, ho, 8 (including 80, 800, ...), or 11 either alone or followed - // by thousand groups and/or decimals (excluding e.g. 110, 1100, ...) - static ref O_SOUND: SerdeDFA<'static> = SerdeDFA::new( - Cow::Borrowed(r"o|ho|8|(11([\.  ]?[0-9]{3})*(,[0-9]*)?([^\.,[0-9]]|$))") - ).expect("Valid regex"); - } + static O_SOUND: OnceCell> = OnceCell::new(); + // Starts with o, ho, 8 (including 80, 800, ...), or 11 either alone or followed + // by thousand groups and/or decimals (excluding e.g. 110, 1100, ...) + let o_sound = O_SOUND.get_or_init(|| { + SerdeDFA::new(Cow::Borrowed( + r"o|ho|8|(11([\.  ]?[0-9]{3})*(,[0-9]*)?([^\.,[0-9]]|$))", + )) + .expect("Valid regex") + }); + // Replace " o " with " u " before /o/ sound. // https://unicode.org/reports/tr35/tr35-general.html#:~:text=agua%20e%20hielo-,OR,-Use%20%E2%80%98u%E2%80%99%20instead patterns - .make_conditional("{0} o {1}", &O_SOUND, "{0} u {1}") + .make_conditional("{0} o {1}", o_sound, "{0} u {1}") .expect("valid pattern"); } } diff --git a/provider/datagen/src/transform/cldr/relativetime/mod.rs b/provider/datagen/src/transform/cldr/relativetime/mod.rs index 1af4a17867e..dad6567b329 100644 --- a/provider/datagen/src/transform/cldr/relativetime/mod.rs +++ b/provider/datagen/src/transform/cldr/relativetime/mod.rs @@ -8,11 +8,13 @@ use crate::transform::cldr::cldr_serde; use icu_provider::datagen::IterableDataProvider; use icu_provider::prelude::*; use icu_relativetime::provider::*; -use lazy_static::lazy_static; +use once_cell::sync::OnceCell; use std::collections::{BTreeMap, HashMap}; -lazy_static! { - static ref DATAKEY_FILTERS: HashMap = { +pub static DATAKEY_FILTERS: OnceCell> = OnceCell::new(); + +fn datakey_filters() -> &'static HashMap { + DATAKEY_FILTERS.get_or_init(|| { [ (LongSecondRelativeTimeFormatDataV1Marker::KEY, "second"), ( @@ -62,9 +64,8 @@ lazy_static! { ] .into_iter() .collect() - }; + }) } - macro_rules! make_data_provider { ($($marker: ident),+ $(,)?) => { $( @@ -86,7 +87,7 @@ macro_rules! make_data_provider { .dates .fields; - let field = DATAKEY_FILTERS + let field = datakey_filters() .get(&$marker::KEY) .ok_or(DataErrorKind::MissingDataKey.into_error())?; diff --git a/tools/depcheck/src/allowlist.rs b/tools/depcheck/src/allowlist.rs index 7d921bf43f4..277e95a960e 100644 --- a/tools/depcheck/src/allowlist.rs +++ b/tools/depcheck/src/allowlist.rs @@ -141,12 +141,12 @@ pub const EXTRA_DATAGEN_DEPS: &[&str] = &[ "icu_codepointtrie_builder", "itertools", "itoa", - "lazy_static", "matrixmultiply", "ndarray", "num-complex", "num-integer", "num-traits", + "once_cell", "rawpointer", "regex-syntax", "ryu",