E08256: MutexLock construction is only allowed as a field initialiser on a class or component
What went wrong
MutexLock construction (the call to the MutexLock constructor) was attempted from a location that is not a field initialiser of a class or component. MutexLock construction is only allowed as the initialiser of a field on a class or component — for example:
MyHolder lockedValue as MutexLock of String: MutexLock("initial")
Locals, function returns, and constructions inside method bodies are all rejected.
Rationale
EK9's compile-time concurrency safety relies on every lock having a stable, field-rooted home. The compiler tracks lock identity statically across the program for data-race detection (slice 1) and deadlock detection (slice 2). Locks declared as locals, returned from functions, or constructed inside method bodies have transient lifetimes that defeat this analysis.
Restricting construction to field initialisers also keeps the API surface clean: callers see a class with protected operations, never the lock object itself.
How to fix it
- Wrap the lock in a class with the lock as a field (the [EXAMPLE] section below: a 'NameHolder' builds its 'MutexLock of String' in the field initialiser and changes it only through a MutexKey in 'rename()')
- Expose the protected operations as methods on the wrapping class. The lock never leaves the class.
- If the lock needs an initial value computed from constructor args, the wrapping class's field initialiser can call a helper that computes the value — but the MutexLock(...) call itself must be the field initialiser.
Common causes
- Treating MutexLock as a local variable holding "protected state" that gets shared via the local. Pass the wrapping class instead.
- Building a helper function that returns a fresh MutexLock. Replace with a class whose field initialiser builds it.
- Trying to construct the lock inside a method body to avoid the field-initialiser pattern. The field initialiser IS the only legal construction site.
Worked examples
- ek9 -q 158 (How do I protect shared data from concurrent access in EK9?)
See also
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E08256: MutexLock construction is only allowed as a field initialiser on a class or component
#!ek9 defines module error.e08256.bad defines function //Local MutexLock inside a function body — rejected. badLocalLock() lock <- MutexLock("Steve") require lock? //Returning a freshly-constructed MutexLock — rejected, because the //construction site is inside the function body, not a field initialiser. badReturningLock() <- rtn as MutexLock of String: MutexLock("Stephen")
Fixed: Construct a MutexLock only as a field initialiser of a class or component
#!ek9 defines module error.e08256.good defines class NameHolder name as MutexLock of String: MutexLock("Steve") rename() -> newName as String key <- (newName) is MutexKey of String as function lockedItem :=: newName require name.enter(key) default operator ?
Questions and answers
These Q&A entries show E08256 and its fix: