diff --git a/apps/wordcraft/src/print.rs b/apps/wordcraft/src/print.rs index de52a6360..47b3e91de 100644 --- a/apps/wordcraft/src/print.rs +++ b/apps/wordcraft/src/print.rs @@ -17,7 +17,7 @@ pub fn discover() -> Discover { static JOBS: std::sync::Mutex>> = std::sync::Mutex::new(Vec::new()); pub fn finish_pending_jobs() { - let workers = std::mem::take(&mut *JOBS.lock().unwrap_or_else(|poison| poison.into_inner())); + let workers = std::mem::take(&mut *JOBS.lock().unwrap_or_else(std::sync::PoisonError::into_inner)); for worker in workers { if worker.join().is_err() { log::error!("the print worker stopped unexpectedly during shutdown"); @@ -46,7 +46,7 @@ pub fn submit() -> Submit { let _ = sender.send(craft_print::submit(&bytes, &job).map_err(|error| error.to_string())); }); if let Ok(worker) = worker { - let mut jobs = JOBS.lock().unwrap_or_else(|poison| poison.into_inner()); + let mut jobs = JOBS.lock().unwrap_or_else(std::sync::PoisonError::into_inner); jobs.retain(|job| !job.is_finished()); jobs.push(worker); } diff --git a/crates/engine/src/session.rs b/crates/engine/src/session.rs index 071cb48f5..511573ec6 100644 --- a/crates/engine/src/session.rs +++ b/crates/engine/src/session.rs @@ -1406,7 +1406,7 @@ impl Session { /// [`crate::cmd::protect::Facts`] for the document as it is now, cached per revision. fn protect_facts(&self) -> crate::cmd::protect::Facts { let key = (self.document_id, self.rev, self.author.clone()); - let mut cache = self.protect_facts.lock().unwrap_or_else(|e| e.into_inner()); + let mut cache = self.protect_facts.lock().unwrap_or_else(std::sync::PoisonError::into_inner); if let Some((k, f)) = cache.as_ref() && *k == key { diff --git a/crates/fonts/src/fontdb.rs b/crates/fonts/src/fontdb.rs index 583d2ae9b..946e6e6fe 100644 --- a/crates/fonts/src/fontdb.rs +++ b/crates/fonts/src/fontdb.rs @@ -101,10 +101,10 @@ impl FaceRef { pub fn of(face: &Arc) -> FaceRef { static LEAKED: RwLock>> = RwLock::new(Vec::new()); let id = face.id as usize; - if let Some(Some(f)) = LEAKED.read().unwrap_or_else(|e| e.into_inner()).get(id) { + if let Some(Some(f)) = LEAKED.read().unwrap_or_else(std::sync::PoisonError::into_inner).get(id) { return FaceRef(f); } - let mut w = LEAKED.write().unwrap_or_else(|e| e.into_inner()); + let mut w = LEAKED.write().unwrap_or_else(std::sync::PoisonError::into_inner); if w.len() <= id { w.resize(id + 1, None); } @@ -1023,11 +1023,11 @@ impl FontDb { pub fn set_system_fallback(&self, on: bool) { #[cfg(not(target_arch = "wasm32"))] { - self.sys.lock().unwrap_or_else(|e| e.into_inner()).enabled = on; + self.sys.lock().unwrap_or_else(std::sync::PoisonError::into_inner).enabled = on; } // Misses remembered while it was off may be found now. - self.fallbacks.write().unwrap_or_else(|e| e.into_inner()).map.clear(); - *self.run_fallbacks.write().unwrap_or_else(|e| e.into_inner()) = RunFallbackCache::default(); + self.fallbacks.write().unwrap_or_else(std::sync::PoisonError::into_inner).map.clear(); + *self.run_fallbacks.write().unwrap_or_else(std::sync::PoisonError::into_inner) = RunFallbackCache::default(); #[cfg(target_arch = "wasm32")] let _ = on; } @@ -1041,14 +1041,14 @@ impl FontDb { } fn read_faces(&self) -> std::sync::RwLockReadGuard<'_, Vec>> { - self.faces.read().unwrap_or_else(|e| e.into_inner()) + self.faces.read().unwrap_or_else(std::sync::PoisonError::into_inner) } /// The system font catalog, scanned first if it hasn't been yet. #[cfg(not(target_arch = "wasm32"))] fn read_catalog(&self) -> std::sync::RwLockReadGuard<'_, Vec> { self.ensure_catalog(); - self.catalog.read().unwrap_or_else(|e| e.into_inner()) + self.catalog.read().unwrap_or_else(std::sync::PoisonError::into_inner) } /// Family names available (loaded plus cataloged system fonts), sorted and deduplicated. Like @@ -1184,7 +1184,7 @@ impl FontDb { } } } - let mut faces = self.faces.write().unwrap_or_else(|e| e.into_inner()); + let mut faces = self.faces.write().unwrap_or_else(std::sync::PoisonError::into_inner); let mut added = 0; for f in new { if !faces.iter().any(|g| g.family.eq_ignore_ascii_case(&f.family) && g.style.eq_ignore_ascii_case(&f.style)) { @@ -1263,7 +1263,7 @@ impl FontDb { } let n = found.len(); log::debug!("cataloged {n} system font faces"); - *self.catalog.write().unwrap_or_else(|e| e.into_inner()) = found; + *self.catalog.write().unwrap_or_else(std::sync::PoisonError::into_inner) = found; self.catalog_gen.fetch_add(1, Ordering::AcqRel); n } @@ -1273,7 +1273,7 @@ impl FontDb { /// its styles. Returns whether any face was added. #[cfg(not(target_arch = "wasm32"))] fn load_cataloged(&self, family: &str) -> bool { - let _loading = self.loading.lock().unwrap_or_else(|e| e.into_inner()); + let _loading = self.loading.lock().unwrap_or_else(std::sync::PoisonError::into_inner); // Another lookup may have loaded it while this one waited. if self.is_loaded(family) { return true; @@ -1282,7 +1282,7 @@ impl FontDb { let files = paths.iter().filter_map(|p| std::fs::read(p).ok()).map(|b| (b, None)).collect(); let added = self.add_fonts(files) > 0; // The fallback searches' index: these files are loaded fonts now. - let mut index = self.coverage.lock().unwrap_or_else(|e| e.into_inner()); + let mut index = self.coverage.lock().unwrap_or_else(std::sync::PoisonError::into_inner); for file in index.files.iter_mut().filter(|f| paths.contains(&f.path)) { file.used = true; } @@ -1471,7 +1471,7 @@ impl FontDb { let mut f = make_face(base.bytes.clone(), base.index, base.family.clone(), style.to_string(), base.legacy_family.clone(), coords)?; f.local_names = base.local_names.clone(); let f = Arc::new(f); - self.faces.write().unwrap_or_else(|e| e.into_inner()).push(f.clone()); + self.faces.write().unwrap_or_else(std::sync::PoisonError::into_inner).push(f.clone()); Some(f) } @@ -1540,7 +1540,7 @@ impl FontDb { fn cached_fallback(&self, c: char, exclude: u32) -> Option> { let n = self.read_faces().len(); { - let cache = self.fallbacks.read().unwrap_or_else(|e| e.into_inner()); + let cache = self.fallbacks.read().unwrap_or_else(std::sync::PoisonError::into_inner); if cache.faces == n && let Some(hit) = cache.map.get(&(c, exclude)) { @@ -1554,7 +1554,7 @@ impl FontDb { if n != self.read_faces().len() { return found; } - let mut cache = self.fallbacks.write().unwrap_or_else(|e| e.into_inner()); + let mut cache = self.fallbacks.write().unwrap_or_else(std::sync::PoisonError::into_inner); if cache.faces != n || cache.map.len() >= FALLBACK_CACHE_MAX { cache.map.clear(); cache.faces = n; @@ -1587,7 +1587,7 @@ impl FontDb { } #[cfg(not(target_arch = "wasm32"))] { - let enabled = self.sys.lock().unwrap_or_else(|e| e.into_inner()).enabled; + let enabled = self.sys.lock().unwrap_or_else(std::sync::PoisonError::into_inner).enabled; if enabled { self.load_cataloged(FAMILY); } @@ -1599,7 +1599,7 @@ impl FontDb { /// one search at a time. #[cfg(not(target_arch = "wasm32"))] fn system_search(&self, c: char, exclude: u32) -> (Option>, usize) { - let _searching = self.searching.lock().unwrap_or_else(|e| e.into_inner()); + let _searching = self.searching.lock().unwrap_or_else(std::sync::PoisonError::into_inner); // A search that held the lock first may have loaded a font covering `c`: choose among the // loaded faces again before loading more. let (found, n) = self.loaded_fallback(c, exclude); @@ -1660,7 +1660,7 @@ impl FontDb { let key = (set, exclude, bold, italic); let n = self.read_faces().len(); { - let cache = self.run_fallbacks.read().unwrap_or_else(|e| e.into_inner()); + let cache = self.run_fallbacks.read().unwrap_or_else(std::sync::PoisonError::into_inner); if cache.faces == n && let Some(hit) = cache.map.get(&key) { @@ -1671,7 +1671,7 @@ impl FontDb { // meanwhile by another thread (one its search, or a family named by a document) must make // a miss count as stale, not as the answer for the new count. let (found, n) = self.search_run(&key.0, exclude, bold, italic); - let mut cache = self.run_fallbacks.write().unwrap_or_else(|e| e.into_inner()); + let mut cache = self.run_fallbacks.write().unwrap_or_else(std::sync::PoisonError::into_inner); if cache.faces != n || cache.map.len() >= RUN_FALLBACK_CACHE_MAX || cache.chars.saturating_add(key.0.len()) > RUN_FALLBACK_CACHE_CHARS { cache.map.clear(); cache.faces = n; @@ -1750,7 +1750,7 @@ impl FontDb { return false; } { - let sys = self.sys.lock().unwrap_or_else(|e| e.into_inner()); + let sys = self.sys.lock().unwrap_or_else(std::sync::PoisonError::into_inner); if !sys.enabled || sys.misses.contains(&c) { return false; } @@ -1764,7 +1764,7 @@ impl FontDb { if self.is_loaded(fam) || !cataloged.iter().any(|f| f.eq_ignore_ascii_case(fam)) { continue; } - if !self.sys.lock().unwrap_or_else(|e| e.into_inner()).tried.insert(fam) { + if !self.sys.lock().unwrap_or_else(std::sync::PoisonError::into_inner).tried.insert(fam) { continue; } self.load_cataloged(fam); @@ -1775,7 +1775,7 @@ impl FontDb { if self.indexed_fallback(c) { return true; } - let mut sys = self.sys.lock().unwrap_or_else(|e| e.into_inner()); + let mut sys = self.sys.lock().unwrap_or_else(std::sync::PoisonError::into_inner); if sys.misses.len() >= SYS_MISSES_MAX { sys.misses.clear(); } @@ -1795,7 +1795,7 @@ impl FontDb { /// before the Regular. #[cfg(not(target_arch = "wasm32"))] fn indexed_run_fallback(&self, chars: &[char]) { - if !self.sys.lock().unwrap_or_else(|e| e.into_inner()).enabled || chars.iter().any(|c| c.is_control()) { + if !self.sys.lock().unwrap_or_else(std::sync::PoisonError::into_inner).enabled || chars.iter().any(|c| c.is_control()) { return; } self.load_indexed(chars, true); @@ -1811,13 +1811,14 @@ impl FontDb { let covered = |db: &FontDb| db.read_faces().iter().any(|f| chars.iter().all(|c| f.covers(*c))); let cps: Vec = chars.iter().map(|c| u32::from(*c)).collect(); let maps_all = |ranges: &[(u32, u32)]| cps.iter().all(|cp| ranges_hold(ranges, *cp)); - let mut index = self.coverage.lock().unwrap_or_else(|e| e.into_inner()); + let mut index = self.coverage.lock().unwrap_or_else(std::sync::PoisonError::into_inner); let generation = self.catalog_gen.load(Ordering::Acquire); if index.generation != Some(generation) { // A new scan (or the first search): keep what is known of files still installed. let mut known: HashMap = std::mem::take(&mut index.files).into_iter().map(|f| (f.path.clone(), f)).collect(); - let mut paths: Vec = self.catalog.read().unwrap_or_else(|e| e.into_inner()).iter().map(|e| e.path.clone()).collect(); + let mut paths: Vec = + self.catalog.read().unwrap_or_else(std::sync::PoisonError::into_inner).iter().map(|e| e.path.clone()).collect(); paths.sort(); paths.dedup(); let files = paths @@ -1880,11 +1881,11 @@ impl FontDb { /// Glyph outline in font units, y-down (flipped), cached per (face, glyph). pub fn outline(&self, face: &FontFace, gid: u32) -> Arc { let key = (face.id, gid); - if let Some(p) = self.outlines.lock().unwrap_or_else(|e| e.into_inner()).get(&key) { + if let Some(p) = self.outlines.lock().unwrap_or_else(std::sync::PoisonError::into_inner).get(&key) { return p.clone(); } let p = Arc::new(face.glyph_outline(gid)); - let mut cache = self.outlines.lock().unwrap_or_else(|e| e.into_inner()); + let mut cache = self.outlines.lock().unwrap_or_else(std::sync::PoisonError::into_inner); if cache.len() >= OUTLINE_CACHE_MAX { cache.clear(); } diff --git a/crates/fonts/src/math.rs b/crates/fonts/src/math.rs index ba49c2099..0570c1781 100644 --- a/crates/fonts/src/math.rs +++ b/crates/fonts/src/math.rs @@ -260,7 +260,7 @@ pub fn parse(b: &[u8]) -> Option { pub fn table(face: &FontFace) -> Option> { static CACHE: OnceLock>>>> = OnceLock::new(); let cache = CACHE.get_or_init(|| Mutex::new(HashMap::new())); - if let Some(t) = cache.lock().unwrap_or_else(|e| e.into_inner()).get(&face.id()) { + if let Some(t) = cache.lock().unwrap_or_else(std::sync::PoisonError::into_inner).get(&face.id()) { return t.clone(); } let t = face @@ -268,7 +268,7 @@ pub fn table(face: &FontFace) -> Option> { .and_then(|f| f.table_data(skrifa::raw::types::Tag::new(b"MATH")).map(|d| d.as_bytes().to_vec())) .and_then(|bytes| parse(&bytes)) .map(Arc::new); - cache.lock().unwrap_or_else(|e| e.into_inner()).insert(face.id(), t.clone()); + cache.lock().unwrap_or_else(std::sync::PoisonError::into_inner).insert(face.id(), t.clone()); t } diff --git a/crates/fonts/src/word.rs b/crates/fonts/src/word.rs index 5d6a638c7..58cac891b 100644 --- a/crates/fonts/src/word.rs +++ b/crates/fonts/src/word.rs @@ -389,7 +389,7 @@ pub fn resolve(family: &str, bold: bool, italic: bool) -> Resolved { let cacheable = family.len() <= FAMILY_KEY_MAX; let key = (if cacheable { family.to_string() } else { String::new() }, bold, italic); { - let mut c = cache.lock().unwrap_or_else(|e| e.into_inner()); + let mut c = cache.lock().unwrap_or_else(std::sync::PoisonError::into_inner); if c.0 != generation { *c = (generation, HashMap::new()); } @@ -409,7 +409,7 @@ pub fn resolve(family: &str, bold: bool, italic: bool) -> Resolved { }; let face = db.face(&fam, style_name(bold, italic)); let r = Resolved { synth_bold: bold && face.weight < 600.0, synth_italic: italic && !face.italic, substituted, face: FaceRef::of(&face) }; - let mut c = cache.lock().unwrap_or_else(|e| e.into_inner()); + let mut c = cache.lock().unwrap_or_else(std::sync::PoisonError::into_inner); if cacheable && c.0 == generation { if c.1.len() >= FAMILY_CACHE_MAX { c.1.clear(); @@ -431,7 +431,7 @@ fn hhea_line(ascender: i16, descender: i16, line_gap: i16) -> (f64, f64) { pub fn line_metrics(face: &crate::FontFace) -> (f64, f64) { static CACHE: OnceLock>> = OnceLock::new(); let cache = CACHE.get_or_init(|| Mutex::new(HashMap::new())); - if let Some(v) = cache.lock().unwrap_or_else(|e| e.into_inner()).get(&face.id()) { + if let Some(v) = cache.lock().unwrap_or_else(std::sync::PoisonError::into_inner).get(&face.id()) { return *v; } let mut v = (face.ascent.max(1.0), face.descent.abs()); @@ -447,7 +447,7 @@ pub fn line_metrics(face: &crate::FontFace) -> (f64, f64) { v = m; } } - cache.lock().unwrap_or_else(|e| e.into_inner()).insert(face.id(), v); + cache.lock().unwrap_or_else(std::sync::PoisonError::into_inner).insert(face.id(), v); v } diff --git a/crates/proof/src/cs/mod.rs b/crates/proof/src/cs/mod.rs index 7a910c72d..fee7c561c 100644 --- a/crates/proof/src/cs/mod.rs +++ b/crates/proof/src/cs/mod.rs @@ -31,11 +31,11 @@ const NAMES: &[&str] = &["cs_CZ", "cs-CZ", "cs"]; /// [`install_dictionary`], or an empty one when none is available (Czech spelling is off /// then; see [`has_dictionary`]). pub fn dictionary() -> Arc { - if let Some(d) = DICT.read().unwrap_or_else(|e| e.into_inner()).dict.as_ref() { + if let Some(d) = DICT.read().unwrap_or_else(std::sync::PoisonError::into_inner).dict.as_ref() { return d.clone(); } let loaded = Arc::new(load_installed()); - let mut slot = DICT.write().unwrap_or_else(|e| e.into_inner()); + let mut slot = DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner); // Another thread (or an install) may have filled it meanwhile: that one wins. slot.dict.get_or_insert(loaded).clone() } @@ -56,7 +56,7 @@ fn load_installed() -> AffixDict { /// UTF-8), for example one the user picked. On error the current dictionary stays. pub fn install_dictionary(aff: &str, dic: &str) -> Result<(), String> { let d = AffixDict::from_hunspell(aff, dic, &[])?; - let mut slot = DICT.write().unwrap_or_else(|e| e.into_inner()); + let mut slot = DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner); slot.dict = Some(Arc::new(d)); slot.in_memory = true; Ok(()) @@ -65,7 +65,7 @@ pub fn install_dictionary(aff: &str, dic: &str) -> Result<(), String> { /// Forget the loaded dictionary, so the next check looks for an installed one again (after /// [`crate::hunspell::set_dictionary_dir`] or a dictionary was installed). pub fn reload_dictionary() { - let mut slot = DICT.write().unwrap_or_else(|e| e.into_inner()); + let mut slot = DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner); slot.dict = None; slot.in_memory = false; } @@ -75,7 +75,7 @@ pub fn reload_dictionary() { /// none. A dictionary given with [`install_dictionary`] has no file and isn't reported, even if a /// matching file also happens to exist. pub fn installed_path() -> Option { - if DICT.read().unwrap_or_else(|e| e.into_inner()).in_memory { + if DICT.read().unwrap_or_else(std::sync::PoisonError::into_inner).in_memory { return None; } crate::hunspell::find(NAMES).map(|(_, dic)| dic) diff --git a/crates/proof/src/hr/mod.rs b/crates/proof/src/hr/mod.rs index 1c89b4fac..ee9d58e92 100644 --- a/crates/proof/src/hr/mod.rs +++ b/crates/proof/src/hr/mod.rs @@ -25,11 +25,11 @@ const NAMES: &[&str] = &["hr_HR", "hr-HR", "hr"]; /// [`install_dictionary`], or an empty one when none is available (Croatian spelling is off /// then; see [`has_dictionary`]). pub fn dictionary() -> Arc { - if let Some(d) = DICT.read().unwrap_or_else(|e| e.into_inner()).as_ref() { + if let Some(d) = DICT.read().unwrap_or_else(std::sync::PoisonError::into_inner).as_ref() { return d.clone(); } let loaded = Arc::new(load_installed()); - let mut slot = DICT.write().unwrap_or_else(|e| e.into_inner()); + let mut slot = DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner); // Another thread (or an install) may have filled it meanwhile: that one wins. slot.get_or_insert(loaded).clone() } @@ -51,14 +51,14 @@ fn load_installed() -> AffixDict { /// UTF-8), for example one the user picked. On error the current dictionary stays. pub fn install_dictionary(aff: &str, dic: &str) -> Result<(), String> { let d = AffixDict::from_hunspell(aff, dic, &[])?; - *DICT.write().unwrap_or_else(|e| e.into_inner()) = Some(Arc::new(d)); + *DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner) = Some(Arc::new(d)); Ok(()) } /// Forget the loaded dictionary, so the next check looks for an installed one again (after /// [`crate::hunspell::set_dictionary_dir`] or a dictionary was installed). pub fn reload_dictionary() { - *DICT.write().unwrap_or_else(|e| e.into_inner()) = None; + *DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner) = None; } /// The `.dic` file of the Hunspell `hr_HR` dictionary found in the dictionaries folder or the diff --git a/crates/proof/src/hunspell.rs b/crates/proof/src/hunspell.rs index 6f0cab1de..0e4303beb 100644 --- a/crates/proof/src/hunspell.rs +++ b/crates/proof/src/hunspell.rs @@ -27,7 +27,7 @@ static LOAD_ERRORS: RwLock> = RwLock::new(Vec::ne /// Remember (or, for `Ok`, forget) why the dictionary `key` found at `dic` failed to load, and /// hand the result back unchanged. pub fn note_load(key: &str, dic: &Path, result: Result) -> Result { - let mut errors = LOAD_ERRORS.write().unwrap_or_else(|e| e.into_inner()); + let mut errors = LOAD_ERRORS.write().unwrap_or_else(std::sync::PoisonError::into_inner); errors.retain(|(k, _, _)| k != key); if let Err(e) = &result { errors.push((key.to_string(), dic.to_path_buf(), e.clone())); @@ -37,19 +37,19 @@ pub fn note_load(key: &str, dic: &Path, result: Result) -> Result< /// Forget the load error of the dictionary `key` (none found, or it is about to be searched for again). pub fn clear_load_error(key: &str) { - LOAD_ERRORS.write().unwrap_or_else(|e| e.into_inner()).retain(|(k, _, _)| k != key); + LOAD_ERRORS.write().unwrap_or_else(std::sync::PoisonError::into_inner).retain(|(k, _, _)| k != key); } /// The `.dic` file and the reason of the last failed load of the dictionary `key`, if any. pub fn load_error(key: &str) -> Option<(PathBuf, String)> { - LOAD_ERRORS.read().unwrap_or_else(|e| e.into_inner()).iter().find(|(k, _, _)| k == key).map(|(_, p, e)| (p.clone(), e.clone())) + LOAD_ERRORS.read().unwrap_or_else(std::sync::PoisonError::into_inner).iter().find(|(k, _, _)| k == key).map(|(_, p, e)| (p.clone(), e.clone())) } /// Search `dir` before the system locations (a "dictionaries folder" setting); `None` clears it. /// Takes effect for dictionaries not loaded yet. pub fn set_dictionary_dir(dir: Option) { - *EXTRA_DIR.write().unwrap_or_else(|e| e.into_inner()) = dir; - LOAD_ERRORS.write().unwrap_or_else(|e| e.into_inner()).clear(); // they belong to the old search path + *EXTRA_DIR.write().unwrap_or_else(std::sync::PoisonError::into_inner) = dir; + LOAD_ERRORS.write().unwrap_or_else(std::sync::PoisonError::into_inner).clear(); // they belong to the old search path } /// The LibreOffice extension directories a Hunspell dictionary name may live in: LibreOffice's @@ -67,7 +67,7 @@ fn lo_ext_dirs(name: &str) -> Vec { /// language is being searched for, adds LibreOffice's extension folders for it (`dict-pt-BR`). pub fn search_dirs(lo_exts: Option<&[String]>) -> Vec { let mut dirs: Vec = Vec::new(); - if let Some(d) = EXTRA_DIR.read().unwrap_or_else(|e| e.into_inner()).clone() { + if let Some(d) = EXTRA_DIR.read().unwrap_or_else(std::sync::PoisonError::into_inner).clone() { dirs.push(d); } if cfg!(target_arch = "wasm32") { diff --git a/crates/proof/src/id/mod.rs b/crates/proof/src/id/mod.rs index 09771e852..012babc0e 100644 --- a/crates/proof/src/id/mod.rs +++ b/crates/proof/src/id/mod.rs @@ -30,11 +30,11 @@ const CLITICS: &[&str] = &["se", "nya", "ku", "mu", "lah", "kah", "pun"]; /// [`install_dictionary`], or an empty one when none is available (Indonesian spelling is off /// then; see [`has_dictionary`]). pub fn dictionary() -> Arc { - if let Some(d) = DICT.read().unwrap_or_else(|e| e.into_inner()).as_ref() { + if let Some(d) = DICT.read().unwrap_or_else(std::sync::PoisonError::into_inner).as_ref() { return d.clone(); } let loaded = Arc::new(load_installed()); - let mut slot = DICT.write().unwrap_or_else(|e| e.into_inner()); + let mut slot = DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner); // Another thread (or an install) may have filled it meanwhile: that one wins. slot.get_or_insert(loaded).clone() } @@ -55,14 +55,14 @@ fn load_installed() -> AffixDict { /// UTF-8), for example one the user picked. On error the current dictionary stays. pub fn install_dictionary(aff: &str, dic: &str) -> Result<(), String> { let d = AffixDict::from_hunspell(aff, dic, &[])?; - *DICT.write().unwrap_or_else(|e| e.into_inner()) = Some(Arc::new(d)); + *DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner) = Some(Arc::new(d)); Ok(()) } /// Forget the loaded dictionary, so the next check looks for an installed one again (after /// [`crate::hunspell::set_dictionary_dir`] or a dictionary was installed). pub fn reload_dictionary() { - *DICT.write().unwrap_or_else(|e| e.into_inner()) = None; + *DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner) = None; } /// The `.dic` file of the Hunspell `id_ID` dictionary found in the dictionaries folder or the diff --git a/crates/proof/src/it/mod.rs b/crates/proof/src/it/mod.rs index 0e11ccaae..027006a69 100644 --- a/crates/proof/src/it/mod.rs +++ b/crates/proof/src/it/mod.rs @@ -34,11 +34,11 @@ const NAMES: &[&str] = &["it_IT", "it_CH", "it-IT", "it"]; /// [`install_dictionary`], or an empty one when none is available (Italian spelling is off /// then; see [`has_dictionary`]). pub fn dictionary() -> Arc { - if let Some(d) = DICT.read().unwrap_or_else(|e| e.into_inner()).as_ref() { + if let Some(d) = DICT.read().unwrap_or_else(std::sync::PoisonError::into_inner).as_ref() { return d.clone(); } let loaded = Arc::new(load_installed()); - let mut slot = DICT.write().unwrap_or_else(|e| e.into_inner()); + let mut slot = DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner); // Another thread (or an install) may have filled it meanwhile: that one wins. slot.get_or_insert(loaded).clone() } @@ -59,14 +59,14 @@ fn load_installed() -> AffixDict { /// UTF-8), for example one the user picked. On error the current dictionary stays. pub fn install_dictionary(aff: &str, dic: &str) -> Result<(), String> { let d = AffixDict::from_hunspell(aff, dic, &[])?; - *DICT.write().unwrap_or_else(|e| e.into_inner()) = Some(Arc::new(d)); + *DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner) = Some(Arc::new(d)); Ok(()) } /// Forget the loaded dictionary, so the next check looks for an installed one again (after /// [`crate::hunspell::set_dictionary_dir`] or a dictionary was installed). pub fn reload_dictionary() { - *DICT.write().unwrap_or_else(|e| e.into_inner()) = None; + *DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner) = None; } /// The `.dic` file of the Hunspell `it_IT` dictionary found in the dictionaries folder or the diff --git a/crates/proof/src/lib.rs b/crates/proof/src/lib.rs index 38f274c75..de5967829 100644 --- a/crates/proof/src/lib.rs +++ b/crates/proof/src/lib.rs @@ -116,14 +116,14 @@ static DICTIONARY_GENERATION: AtomicU64 = AtomicU64::new(0); /// Add a word to the user dictionary ("Add to Dictionary"). It applies to every language. pub fn add_word(w: &str) { - if user_words().write().unwrap_or_else(|e| e.into_inner()).insert(w.to_lowercase()) { + if user_words().write().unwrap_or_else(std::sync::PoisonError::into_inner).insert(w.to_lowercase()) { DICTIONARY_GENERATION.fetch_add(1, Ordering::Relaxed); } } /// Take a word out of the user dictionary (File › Options › Proofing). Returns whether it was there. pub fn remove_word(w: &str) -> bool { - let removed = user_words().write().unwrap_or_else(|e| e.into_inner()).remove(&w.to_lowercase()); + let removed = user_words().write().unwrap_or_else(std::sync::PoisonError::into_inner).remove(&w.to_lowercase()); if removed { DICTIONARY_GENERATION.fetch_add(1, Ordering::Relaxed); } @@ -138,7 +138,7 @@ fn ignored_words() -> &'static RwLock> { /// Ignore a word everywhere until the app closes ("Ignore All"). Unlike [`add_word`] it isn't /// part of the user dictionary: it is never listed, saved or loaded, as in Word. pub fn ignore_word(w: &str) { - if ignored_words().write().unwrap_or_else(|e| e.into_inner()).insert(w.to_lowercase()) { + if ignored_words().write().unwrap_or_else(std::sync::PoisonError::into_inner).insert(w.to_lowercase()) { DICTIONARY_GENERATION.fetch_add(1, Ordering::Relaxed); } } @@ -198,13 +198,13 @@ pub fn dictionary_generation() -> u64 { /// Is `lower` (a lower-case word) in the user dictionary or ignored? pub(crate) fn in_user_dictionary(lower: &str) -> bool { - user_words().read().unwrap_or_else(|e| e.into_inner()).contains(lower) - || ignored_words().read().unwrap_or_else(|e| e.into_inner()).contains(lower) + user_words().read().unwrap_or_else(std::sync::PoisonError::into_inner).contains(lower) + || ignored_words().read().unwrap_or_else(std::sync::PoisonError::into_inner).contains(lower) } /// Words in the user dictionary. pub fn user_dictionary() -> Vec { - let mut v: Vec = user_words().read().unwrap_or_else(|e| e.into_inner()).iter().cloned().collect(); + let mut v: Vec = user_words().read().unwrap_or_else(std::sync::PoisonError::into_inner).iter().cloned().collect(); v.sort(); v } @@ -252,7 +252,7 @@ fn read_dictionary_file(path: &std::path::Path) -> Vec { /// never a panic and never an error that stops startup. Returns the words added. pub fn load_user_dictionary(path: &std::path::Path) -> Vec { let words = read_dictionary_file(path); - let mut set = user_words().write().unwrap_or_else(|e| e.into_inner()); + let mut set = user_words().write().unwrap_or_else(std::sync::PoisonError::into_inner); let mut added = Vec::new(); for w in words { if set.len() >= MAX_CUSTOM_WORDS { @@ -278,7 +278,7 @@ pub fn save_user_dictionary(path: &std::path::Path, removed: &[String]) -> std:: let removed: HashSet = removed.iter().map(|w| w.to_lowercase()).collect(); let on_disk = read_dictionary_file(path); { - let mut set = user_words().write().unwrap_or_else(|e| e.into_inner()); + let mut set = user_words().write().unwrap_or_else(std::sync::PoisonError::into_inner); let mut changed = false; for w in on_disk { if set.len() >= MAX_CUSTOM_WORDS { @@ -334,7 +334,9 @@ fn known_core(w: &str) -> bool { if base_known(d, w) || COMMON.split(' ').any(|c| c == w) { return true; } - if user_words().read().unwrap_or_else(|e| e.into_inner()).contains(w) || ignored_words().read().unwrap_or_else(|e| e.into_inner()).contains(w) { + if user_words().read().unwrap_or_else(std::sync::PoisonError::into_inner).contains(w) + || ignored_words().read().unwrap_or_else(std::sync::PoisonError::into_inner).contains(w) + { return true; } // Inflections. diff --git a/crates/proof/src/pl/mod.rs b/crates/proof/src/pl/mod.rs index 76fa455ec..18c968feb 100644 --- a/crates/proof/src/pl/mod.rs +++ b/crates/proof/src/pl/mod.rs @@ -33,11 +33,11 @@ const NAMES: &[&str] = &["pl_PL", "pl-PL", "pl"]; /// [`install_dictionary`], or an empty one when none is available (Polish spelling is off then; /// see [`has_dictionary`]). pub fn dictionary() -> Arc { - if let Some(d) = DICT.read().unwrap_or_else(|e| e.into_inner()).as_ref() { + if let Some(d) = DICT.read().unwrap_or_else(std::sync::PoisonError::into_inner).as_ref() { return d.clone(); } let loaded = Arc::new(load_installed()); - let mut slot = DICT.write().unwrap_or_else(|e| e.into_inner()); + let mut slot = DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner); // Another thread (or an install) may have filled it meanwhile: that one wins. slot.get_or_insert(loaded).clone() } @@ -58,14 +58,14 @@ fn load_installed() -> AffixDict { /// for example one the user picked. On error the current dictionary stays. pub fn install_dictionary(aff: &str, dic: &str) -> Result<(), String> { let d = AffixDict::from_hunspell(aff, dic, &[])?; - *DICT.write().unwrap_or_else(|e| e.into_inner()) = Some(Arc::new(d)); + *DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner) = Some(Arc::new(d)); Ok(()) } /// Forget the loaded dictionary, so the next check looks for an installed one again (after /// [`crate::hunspell::set_dictionary_dir`] or a dictionary was installed). pub fn reload_dictionary() { - *DICT.write().unwrap_or_else(|e| e.into_inner()) = None; + *DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner) = None; } /// The `.dic` file of the installed Polish dictionary, searching the dictionaries folder and diff --git a/crates/proof/src/pt/mod.rs b/crates/proof/src/pt/mod.rs index 3a8b059fc..de4198259 100644 --- a/crates/proof/src/pt/mod.rs +++ b/crates/proof/src/pt/mod.rs @@ -32,11 +32,11 @@ const NAMES: &[&str] = &["pt_BR", "pt-BR", "pt"]; /// [`install_dictionary`], or an empty one when none is available (Portuguese spelling is off /// then; see [`has_dictionary`]). pub fn dictionary() -> Arc { - if let Some(d) = DICT.read().unwrap_or_else(|e| e.into_inner()).as_ref() { + if let Some(d) = DICT.read().unwrap_or_else(std::sync::PoisonError::into_inner).as_ref() { return d.clone(); } let loaded = Arc::new(load_installed()); - let mut slot = DICT.write().unwrap_or_else(|e| e.into_inner()); + let mut slot = DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner); // Another thread (or an install) may have filled it meanwhile: that one wins. slot.get_or_insert(loaded).clone() } @@ -57,14 +57,14 @@ fn load_installed() -> AffixDict { /// UTF-8), for example one the user picked. On error the current dictionary stays. pub fn install_dictionary(aff: &str, dic: &str) -> Result<(), String> { let d = AffixDict::from_hunspell(aff, dic, &[])?; - *DICT.write().unwrap_or_else(|e| e.into_inner()) = Some(Arc::new(d)); + *DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner) = Some(Arc::new(d)); Ok(()) } /// Forget the loaded dictionary, so the next check looks for an installed one again (after /// [`crate::hunspell::set_dictionary_dir`] or a dictionary was installed). pub fn reload_dictionary() { - *DICT.write().unwrap_or_else(|e| e.into_inner()) = None; + *DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner) = None; } /// The `.dic` file of the installed Portuguese dictionary, searching the dictionaries folder and diff --git a/crates/proof/src/ru/mod.rs b/crates/proof/src/ru/mod.rs index 50faac380..c92e27125 100644 --- a/crates/proof/src/ru/mod.rs +++ b/crates/proof/src/ru/mod.rs @@ -52,11 +52,11 @@ const NAMES: &[&str] = &["ru_RU", "ru-RU", "ru"]; /// [`install_dictionary`], or an empty one when none is available (Russian spelling is off then; /// see [`has_dictionary`]). pub fn dictionary() -> Arc { - if let Some(d) = DICT.read().unwrap_or_else(|e| e.into_inner()).dict.as_ref() { + if let Some(d) = DICT.read().unwrap_or_else(std::sync::PoisonError::into_inner).dict.as_ref() { return d.clone(); } let loaded = Arc::new(load_installed()); - let mut slot = DICT.write().unwrap_or_else(|e| e.into_inner()); + let mut slot = DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner); // Another thread (or an install) may have filled it meanwhile: that one wins. slot.dict.get_or_insert(loaded).clone() } @@ -77,7 +77,7 @@ fn load_installed() -> AffixDict { /// for example one the user picked. On error the current dictionary stays. pub fn install_dictionary(aff: &str, dic: &str) -> Result<(), String> { let d = AffixDict::from_hunspell(aff, dic, &[])?; - let mut slot = DICT.write().unwrap_or_else(|e| e.into_inner()); + let mut slot = DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner); slot.dict = Some(Arc::new(d)); slot.in_memory = true; Ok(()) @@ -86,7 +86,7 @@ pub fn install_dictionary(aff: &str, dic: &str) -> Result<(), String> { /// Forget the loaded dictionary, so the next check looks for an installed one again (after /// [`crate::hunspell::set_dictionary_dir`] or a dictionary was installed). pub fn reload_dictionary() { - let mut slot = DICT.write().unwrap_or_else(|e| e.into_inner()); + let mut slot = DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner); slot.dict = None; slot.in_memory = false; } @@ -96,7 +96,7 @@ pub fn reload_dictionary() { /// none. A dictionary given with [`install_dictionary`] has no file and isn't reported, even if a /// matching file also happens to exist. pub fn installed_path() -> Option { - if DICT.read().unwrap_or_else(|e| e.into_inner()).in_memory { + if DICT.read().unwrap_or_else(std::sync::PoisonError::into_inner).in_memory { return None; } crate::hunspell::find(NAMES).map(|(_, dic)| dic) diff --git a/crates/proof/src/tr/mod.rs b/crates/proof/src/tr/mod.rs index d814dc2a3..bcab1546b 100644 --- a/crates/proof/src/tr/mod.rs +++ b/crates/proof/src/tr/mod.rs @@ -30,11 +30,11 @@ const NAMES: &[&str] = &["tr_TR", "tr-TR", "tr"]; /// The Turkish dictionary: the installed Hunspell `tr_TR` (read on first use), one given with /// [`install_dictionary`], or an empty one when none is available. pub fn dictionary() -> Arc { - if let Some(d) = DICT.read().unwrap_or_else(|e| e.into_inner()).as_ref() { + if let Some(d) = DICT.read().unwrap_or_else(std::sync::PoisonError::into_inner).as_ref() { return d.clone(); } let loaded = Arc::new(load_installed()); - let mut slot = DICT.write().unwrap_or_else(|e| e.into_inner()); + let mut slot = DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner); slot.get_or_insert(loaded).clone() } @@ -61,13 +61,13 @@ fn load_installed() -> TrDict { /// Use this Turkish dictionary from now on. pub fn install_dictionary(aff: &str, dic: &str) -> Result<(), String> { let d = TrDict::from_hunspell(aff, dic)?; - *DICT.write().unwrap_or_else(|e| e.into_inner()) = Some(Arc::new(d)); + *DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner) = Some(Arc::new(d)); Ok(()) } /// Reload the dictionary on next check. pub fn reload_dictionary() { - *DICT.write().unwrap_or_else(|e| e.into_inner()) = None; + *DICT.write().unwrap_or_else(std::sync::PoisonError::into_inner) = None; } /// The `.dic` file of the Hunspell `tr_TR` dictionary found in the dictionaries folder or the diff --git a/crates/render/src/lib.rs b/crates/render/src/lib.rs index cd6e4be84..f264db557 100644 --- a/crates/render/src/lib.rs +++ b/crates/render/src/lib.rs @@ -181,7 +181,7 @@ impl MediaCache { } fn lock(m: &Mutex) -> std::sync::MutexGuard<'_, T> { - m.lock().unwrap_or_else(|e| e.into_inner()) + m.lock().unwrap_or_else(std::sync::PoisonError::into_inner) } fn images() -> &'static Mutex>>> { diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index 59fb5b892..a089ef1a1 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -2566,7 +2566,7 @@ impl WordApp { /// recipient lists (CSV/TSV, spreadsheets, or a text file asked for as one) load as recipients. fn drain_inbox(&mut self) { let Some(inbox) = self.services.inbox.clone() else { return }; - let files = std::mem::take(&mut *inbox.lock().unwrap_or_else(|e| e.into_inner())); + let files = std::mem::take(&mut *inbox.lock().unwrap_or_else(std::sync::PoisonError::into_inner)); let mut placed_picture = false; for (name, bytes) in files { let lower = name.to_ascii_lowercase(); @@ -2600,7 +2600,7 @@ impl WordApp { /// otherwise so the focused field's own paste applies (a text field ignores a picture). fn drain_pasted(&mut self) { let Some(pasted) = self.services.pasted.clone() else { return }; - let pictures = std::mem::take(&mut *pasted.lock().unwrap_or_else(|e| e.into_inner())); + let pictures = std::mem::take(&mut *pasted.lock().unwrap_or_else(std::sync::PoisonError::into_inner)); let target = paste_target(self.canvas.focused, self.ui.backstage, self.dialog.is_some() || self.file_dialog_open()); for (_, bytes) in pictures { if !target {