Skip to content

Commit 52f021f

Browse files
committed
Replace unsafe static mut patterns with once_cell
1 parent 75ee54e commit 52f021f

File tree

7 files changed

+25
-30
lines changed

7 files changed

+25
-30
lines changed

Cargo.lock

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cache/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ edition = "2024"
55

66
[dependencies]
77
lru = "0.16.0"
8+
once_cell = "1.21.3"

cache/src/cache.rs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use lru::LruCache;
2+
use once_cell::unsync::Lazy;
23
use std::{any::Any, num::NonZeroUsize, rc::Rc};
34

45
use crate::Observable;
@@ -7,29 +8,22 @@ type CacheKey = *const dyn Observable;
78

89
const CACHE_CAP: usize = 128;
910

10-
static mut CACHE: Option<LruCache<CacheKey, Rc<dyn Any>>> = None;
11-
12-
fn cache() -> &'static mut LruCache<CacheKey, Rc<dyn Any>> {
13-
#[allow(static_mut_refs)]
14-
unsafe {
15-
CACHE.get_or_insert_with(|| LruCache::new(NonZeroUsize::new(CACHE_CAP).unwrap()))
16-
}
17-
}
11+
static mut CACHE: Lazy<LruCache<CacheKey, Rc<dyn Any>>> =
12+
Lazy::new(|| LruCache::new(NonZeroUsize::new(CACHE_CAP).unwrap()));
1813

1914
pub fn touch<T: 'static>(key: &'static dyn Observable) -> Option<Rc<T>> {
20-
cache()
21-
.get(&(key as _))
15+
unsafe { (*CACHE).get(&(key as _)) }
2216
.map(Rc::clone)
2317
.filter(|rc| rc.is::<T>())
2418
.map(|rc| unsafe { Rc::from_raw(Rc::into_raw(rc) as *const T) })
2519
}
2620

2721
pub fn store_in_cache<T: 'static>(key: &'static dyn Observable, val: T) -> Rc<T> {
2822
let rc = Rc::new(val);
29-
cache().put(key, Rc::clone(&rc) as _);
23+
unsafe { (*CACHE).put(key, Rc::clone(&rc) as _) };
3024
rc
3125
}
3226

3327
pub fn remove_from_cache(key: &'static dyn Observable) {
34-
cache().pop(&(key as _));
28+
unsafe { (*CACHE).pop(&(key as _)) };
3529
}

cache/src/call_stack.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,17 @@
1-
use crate::Observable;
1+
use once_cell::sync::Lazy;
22

3-
static mut CALL_STACK: Option<Vec<&'static dyn Observable>> = None;
3+
use crate::Observable;
44

5-
fn call_stack() -> &'static mut Vec<&'static dyn Observable> {
6-
#[allow(static_mut_refs)]
7-
unsafe {
8-
CALL_STACK.get_or_insert_with(Vec::new)
9-
}
10-
}
5+
static mut CALL_STACK: Lazy<Vec<&'static dyn Observable>> = Lazy::new(Vec::new);
116

127
pub fn push(op: &'static dyn Observable) {
13-
call_stack().push(op)
8+
unsafe { (*CALL_STACK).push(op) }
149
}
1510

1611
pub fn last() -> Option<&'static &'static dyn Observable> {
17-
call_stack().last()
12+
unsafe { (*CALL_STACK).last() }
1813
}
1914

2015
pub fn pop() -> Option<&'static dyn Observable> {
21-
call_stack().pop()
16+
unsafe { (*CALL_STACK).pop() }
2217
}

macros/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ edition = "2024"
77
proc-macro = true
88

99
[dependencies]
10+
once_cell = "1.21.3"
1011
proc-macro2 = "1.0.95"
1112
quote = "1.0.40"
1213
syn = { version = "2.0.104", features = ["full"] }

macros/src/lib.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,12 @@ pub fn memo(_attr: TokenStream, item: TokenStream) -> TokenStream {
3232
let memo_ident = format_ident!("{}", ident.to_string().to_uppercase());
3333

3434
let expanded = quote! {
35-
static mut #memo_ident: Option<cache::Memo<#output_ty, fn() -> #output_ty>> = None;
35+
static mut #memo_ident: once_cell::unsync::Lazy<cache::Memo<#output_ty, fn() -> #output_ty>> = once_cell::unsync::Lazy::new(|| cache::Memo::new(|| #block));
3636

3737
#vis #sig
3838
where #output_ty: Clone + 'static
3939
{
40-
#[allow(static_mut_refs)]
41-
unsafe { &mut #memo_ident }.get_or_insert_with(|| cache::Memo::new(|| #block)).get()
40+
unsafe { (*#memo_ident).get() }
4241
}
4342
};
4443

macros/tests/dep.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,7 @@ fn complex_dependency_memo_test() {
7171
assert_eq!(d2, d1);
7272
assert_eq!(e2, e1);
7373

74-
#[allow(static_mut_refs)]
75-
if let Some(memo) = unsafe { &SOURCE_A } {
76-
memo.invalidate();
77-
}
74+
unsafe { (*SOURCE_A).invalidate() };
7875

7976
unsafe { SOURCE_A_CALLED = false };
8077
unsafe { SOURCE_C_CALLED = false };

0 commit comments

Comments
 (0)