E08040: Reassignment/mutation within possible 'safe method access' scope is not allowed
What went wrong
You're re-pointing a variable inside a safe access block (protected by ?, or by a guard). This breaks the safety guarantee because the check was on the OLD value.
Every store counts: an assignment (':', ':=', '=', ':=?'), whether it is a statement or the pre-flow of a nested construct. Inside 'if o?', both a statement 'o := other()' and a nested 'if o := other() then o?' re-point o, and each is this error. (The [EXAMPLE] section below shows a re-point with ':' inside 'if chosen?', and the fix: check each Optional in its own branch.)
A construct's OWN head is the proof, not a re-point: 'while o :=? next() then more' is what makes o safe in that loop. It is an error only when an enclosing scope had already proven o safe.
Worked examples
Compilable examples demonstrating this error and the correct fix:
- ek9 -q 1960 (Can I give an Optional a new value inside the 'if o?' block that checked it?)
- ek9 -q 86 (How do Result guard patterns and ternary access work?)
- ek9 -q 84 (What operations does Optional support in EK9?)
How to fix it
- Don't re-point the checked variable inside its protection block
- Use a different variable for the new value: 'if replacement <- other()'
- Re-point after the protection block has ended
Common causes
- Modifying Optional/Result variable inside its protection block
- Assigning to checked variable after guard
- A nested 'if o := other() then o?' inside 'if o?'
- An inner loop or try whose own head re-points a variable an outer 'if o?' already checked
See also
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E08040: Reassignment/mutation within possible 'safe method access' scope is not allowed
#!ek9 defines module error.e08040.bad defines function describe() -> primary as Optional of String fallback as Optional of String <- rtn as String: "none" chosen <- primary if chosen? chosen: fallback rtn: chosen.get()
Fixed: Use the checked value; check the other one separately
#!ek9 defines module error.e08040.good defines function describe() -> primary as Optional of String fallback as Optional of String <- rtn as String: "none" if primary? rtn: primary.get() else if fallback? rtn: fallback.get()
Questions and answers
These Q&A entries show E08040 and its fix:
- Q84: What operations does Optional support in EK9?
- Q86: How do Result guard patterns and ternary access work?
- Q1379: Why can't I call get() in a do-while body when the trailing while condition checks the Optional?
- Q1960: Can I give an Optional a new value inside the 'if o?' block that checked it?
- Q1982: Which ways of combining the guard operators does the compiler reject, and what should I write instead?