Class OperatorKeepsValueUnsetOrError

java.lang.Object
org.ek9lang.compiler.phase5.OperatorKeepsValueUnsetOrError

final class OperatorKeepsValueUnsetOrError extends Object
E08096: an in-place operator applied to a value the compiler is SURE is unset, where the operator is one that keeps an unset value unset - text <- String() then text += "more", or count <- Integer() then count++. The operation can never give the value a value: the program runs and quietly leaves it unset.

🔑 Steve's rule (2026-10-26): fire ONLY when the compiler is sure the value is unset AND sure the operation cannot set it; anything uncertain is silent, never an error. Sure the value is unset: the value tracker holds it UNSET (a CONSTRUCTS_UNSET constructor, or if not x?); inside a loop the finding waits until every enclosing loop ends without writing the variable (ValueTrackingAnalyzer.reportWhenSure(ISymbol, Runnable)). Sure the operation cannot set it: the RESOLVED operator carries KEEPS_UNSET (UnsetKeepingOperator), which only the built-in literal types' += -= *= /= ++ -- do - a user type's operator never does, so it stays silent. Aliasing, calls and escapes leave the value unknown exactly as they always have.

A <- guard's variable in a later block of its own if chain is left to E08270, which reports every use there.

Not covered: x := x + 1 (a store of a new value, which is unset too, but through a different route).

  • Constructor Details

  • Method Details

    • constructedUnset

      void constructedUnset(ISymbol symbol, ISymbol type)
      symbol was given the value a CONSTRUCTS_UNSET constructor of type makes.
    • declaredWithoutValue

      void declaredWithoutValue(ISymbol symbol)
      symbol was declared as T?, with no value.
    • otherwiseGiven

      void otherwiseGiven(ISymbol symbol)
      symbol was given some other value, by a store or a narrowing.
    • narrowed

      void narrowed(ISymbol symbol)
      symbol was narrowed by a set-check (if not x?): known unset now because of the check.
    • keepsTargetUnset

      boolean keepsTargetUnset(EK9Parser.AssignmentStatementContext ctx, ISymbol target)
      An assignment statement x += y (any in-place operator but a store): true when its target is UNSET and the operator keeps it unset - the target then stays UNSET and the finding is made once the right-hand side has been walked (assignmentCompleted(EK9Parser.AssignmentStatementContext)).
    • assignmentCompleted

      void assignmentCompleted(EK9Parser.AssignmentStatementContext ctx)
      The right-hand side of an assignment statement has been walked: a target kept unset is reported if it is still known unset (a call in the right-hand side that may have changed it leaves it unknown, and silent).
    • keepsIncrementedUnset

      boolean keepsIncrementedUnset(EK9Parser.IdentifierContext ctx, ISymbol target)
      An identifier written in place by x++ or x--: true when it is UNSET and the operator keeps it unset - reported, and it stays UNSET.