Fixes #9681 where WeakConcurrentBag.addToLongTermStorage caused NPE in Scala Native when forking 10K fibers.

Root Cause

ConcurrentHashMap.newKeySet() in Scala Native has a race condition in treeifyBin() when under high concurrency. This is a known upstream Scala Native issue (https://github.com/scala-native/scala-native/issues/4388).

When many fibers are forked simultaneously, WeakConcurrentBag.addToLongTermStorage calls Platform.newConcurrentSet which previously used ConcurrentHashMap.newKeySet() — triggering the buggy KeySetView / treeifyBin code path.

Fix

Replace both newConcurrentSet overloads in Scala Native’s PlatformSpecific with:

Collections.newSetFromMap(new ConcurrentHashMap[A, java.lang.Boolean]())
Collections.newSetFromMap(new ConcurrentHashMap[A, java.lang.Boolean](initialCapacity))

This avoids the KeySetView / treeifyBin code path entirely. The approach is consistent with the existing newWeakSet implementation which already uses Collections.newSetFromMap. The JVM implementation is unchanged.

Test

Added WeakConcurrentBagNativeSpec — a nativeOnly stress test that forks 10,000 fibers in parallel, directly exercising the addToLongTermStorage path that previously caused the NPE.

Closes #9681

/claim #9681

Claim

Total prize pool $150
Total paid $0
Status Pending
Submitted March 11, 2026
Last updated March 11, 2026

Contributors

CH

CharlesWong

@CharlesWong

100%

Sponsors

ZI

ZIO

@ZIO

$150