Audit finding from general-audit @ 00aa515 (2026-04-27)
Severity: low (code quality / safety doc)
Category: safety / unsafe
File: crates/web/src/state_bridge.rs:87
Obvious fix: yes
Description
unsafe impl<T: Send + Sync + 'static, U: PartialEq + Clone + Send + Sync + 'static> Send
for DerivedStateActor<T, U>
{
}
Bare unsafe impl Send w/ zero // SAFETY: rationale. Compare crates/actor/src/addr.rs:87-91 which documents why unsafe impl Sync for Addr<A> holds (channel sender is Send+Sync, PhantomData<A> blocks auto-derive).
DerivedStateActor fields:
source: StateRef<T> — Send if T: Send
selector: Arc<dyn Fn(&T) -> U + Send + Sync> — Send by bound
cached: Arc<Mutex<Option<U>>> — Send if U: Send
write: SendWrapper<WriteSignal<U>> — SendWrapper already unconditional Send
All fields look Send-clean already, so the impl may be redundant — or papering over a hidden non-Send (e.g. Leptos signal internals). Either way, no comment = future maintainer can't tell which.
Impact / Threat
Low. WASM is single-threaded so multi-thread races aren't reachable today. But:
- Removes review-time safety check — future change to fields could silently invalidate the impl.
- Violates project convention: every other unsafe in workspace has rationale (
addr.rs:87 precedent).
- Hides whether the impl is redundant (delete it) or load-bearing (document why).
Suggested fix
Either:
- Delete: try removing the
unsafe impl and let auto-derive fire; if compiles, drop it.
- Document: add
// SAFETY: … comment explaining which field blocks auto-derive and why manually asserting Send is sound (likely "WASM single-threaded; SendWrapper provides runtime check on cross-thread access").
Verify
sed -n '85,91p' crates/web/src/state_bridge.rs
# Compare:
sed -n '85,91p' crates/actor/src/addr.rs
Audit finding from general-audit @
00aa515(2026-04-27)Severity: low (code quality / safety doc)
Category: safety / unsafe
File:
crates/web/src/state_bridge.rs:87Obvious fix: yes
Description
Bare
unsafe impl Sendw/ zero// SAFETY:rationale. Comparecrates/actor/src/addr.rs:87-91which documents whyunsafe impl Sync for Addr<A>holds (channel sender is Send+Sync,PhantomData<A>blocks auto-derive).DerivedStateActorfields:source: StateRef<T>— Send if T: Sendselector: Arc<dyn Fn(&T) -> U + Send + Sync>— Send by boundcached: Arc<Mutex<Option<U>>>— Send if U: Sendwrite: SendWrapper<WriteSignal<U>>—SendWrapperalready unconditional SendAll fields look Send-clean already, so the impl may be redundant — or papering over a hidden non-Send (e.g. Leptos signal internals). Either way, no comment = future maintainer can't tell which.
Impact / Threat
Low. WASM is single-threaded so multi-thread races aren't reachable today. But:
addr.rs:87precedent).Suggested fix
Either:
unsafe impland let auto-derive fire; if compiles, drop it.// SAFETY: …comment explaining which field blocks auto-derive and why manually asserting Send is sound (likely "WASM single-threaded; SendWrapper provides runtime check on cross-thread access").Verify