Migration Guide: nim-debra 0.8.0¶
Audience¶
Users with code calling withPin(handle): body (anonymous form) or
withPin(handle, named): body (named-overload form). withPin is
deprecated in 0.8.0 and targeted for removal in 0.9.0; new code should
use PinnedScope.
If your code does not call withPin and you do not annotate
ThreadHandle/Pinned/Unpinned/Retired/Neutralized/Registered/
DebraManager/RetireReady/PinnedScope types explicitly, the
0.7.x → 0.8.0 upgrade should be source-compatible thanks to the
ccSingle default on the new CC generic parameter.
Mechanical translation¶
Anonymous form (withPin(handle): body)¶
# Before (0.7.x):
withPin(handle):
# body referencing `it: Pinned[N]`
let r = retire(it, ptr, dtor)
# After (0.8.0):
block:
var scope = pinScope(unpinned(handle))
var ready = retireReady(scope.state)
discard ready.retire(ptr, dtor)
# =destroy auto-runs unpin + close at block exit
Key changes:
withPinis replaced bypinScope(unpinned(handle)), which returns aPinnedScope[N, ccSingle]value bound toscope.- The implicit
itbinding is replaced byscope.state(aPinned[N]on the pinned axis). retireis reached through the explicitretireReadychain rather than as a free proc onit.- Unpin and close happen automatically via
=destroywhenscopegoes out of scope, including on early-return and exception paths. No explicit cleanup is required.
Named-overload form (withPin(handle, named): body)¶
# Before (0.7.x):
withPin(handle, myPin):
# body referencing `myPin: Pinned[N]`
let r = retire(myPin, ptr, dtor)
# After (0.8.0):
block:
var myPin = pinScope(unpinned(handle))
var ready = retireReady(myPin.state)
discard ready.retire(ptr, dtor)
# =destroy auto-runs unpin + close at block exit
The named binding becomes the PinnedScope value itself; reach the
underlying Pinned[N] via myPin.state.
Cardinality opt-in (PinScopeCardinality)¶
0.8.0 introduces the PinScopeCardinality enum on the second generic
parameter (CC) of nine typestate-axis types:
ccSingle(default, safe): singlePinnedScopeper thread per lifetime. The compiler enforces single-pin discipline; the runtime invariants match the 0.7.x single-withPin-at-a-time model.ccMulti(opt-in, advanced): multi-pin patterns are permitted on this axis. Selected explicitly via[N, ccMulti]on the type annotation.
Foot-gun callout for ccMulti¶
ccMulti is not "use this if you're not sure." It is an explicit
opt-in for advanced patterns. When you opt in, you take on:
- Explicit reasoning about pin ordering — nested
PinnedScopelifetimes must form a stack, not an arbitrary DAG, or you risk reading from a retired bag. - Explicit reasoning about limbo-bag advancement — concurrent multi-pin scopes can stall epoch advancement if their lifetimes overlap with the manager's advance protocol in unexpected ways.
ccSingle is the right default. Reach for ccMulti only when you have
a concrete pattern that demands it and you have audited the pin
ordering and advance interaction.
AdvanceContext¶
No migration needed. AdvanceContext gained the CC parameter — its
field must accept a ptr DebraManager[MT, CC] for both cardinalities — but
the epoch advancement protocol itself is cardinality-uniform: pure atomic
arithmetic with no cardinality-dependent branching. Because CC defaults to
ccSingle, existing annotations on AdvanceContext values do not need to be
updated; ccMulti managers flow through automatically when constructed via
initDebraManager[N, ccMulti]().
Deprecation timeline¶
| Version | withPin status |
|---|---|
| 0.8.0 | Deprecated, still works, emits deprecation warning. |
| 0.9.0 | Planned removal. New code MUST use PinnedScope. |
There is no flag to silence the deprecation warning in 0.8.0; the intent is to make the migration visible at every call site so the 0.9.0 removal is a no-op for downstream code.
Self-evidence¶
nim-debra 0.8.0 itself migrated 17 internal withPin call sites to
PinnedScope across the source tree, plus 60+ DR-T6 explicit-annotation
sites widened to spell the CC second parameter. This is the same
translation the migration guide prescribes — proof the pattern works
end-to-end and is exercised by the 242-test suite across all five
backends (orc, arc, atomicArc, refc, cpp).