E08090: is not referenced anywhere, or not referenced after assignment

Category: E08xxx Pre-IR checks (flow analysis) · Reported in phase: FULL_RESOLUTION · Classification: NOT_REFERENCED · All error codes

What went wrong

You declared/assigned a variable but never used it afterward. Changing it in place ('+=', '-=', '++', '--', ':~:', ...) and never reading it is not a use: '++' and '--' are exactly '+= 1' and '-= 1'. The exception is a VIEW: when the call that gave the variable its value hands back part of something else (JSON.get, DictEntry.value, Iterator.next, or your own method returning one of its properties), mutating the variable changes that something, so it counts as a use. That case is decided at PRE_IR_CHECKS, so a fresh call result that is only changed is reported there. When the variable was bound to a PROPERTY ('alias <- counter.total') the change DOES happen: '<-' binds the same object the property holds, so the alias changes the property in place. Nothing is lost, it is just written the long way round - the message then names the property, and the direct form is the fix.

Worked examples

Compilable examples demonstrating this error and the correct fix:

  • ek9 -q 557 (How does EK9 detect dead code and redundant conditions?)
  • ek9 -q 248 (What does a specific EK9 error code mean?)

Rationale

EK9 flags unused variables to help catch bugs and keep code clean.

How to fix it

  1. Use the variable for its intended purpose
  2. Remove if truly unnecessary
  3. If the variable is an alias of a property that you only change ('alias <- counter.total' then 'alias++'), make the change on the property directly ('counter.total += 1', 'counter.total += 5') and drop the alias

Common causes

  • Leftover from refactoring
  • Planned to use but forgot
  • Debug code left in
  • Mutating a copy or a fresh result ('total <- name.upperCase(); total += "!"') and never reading it
  • Changing a property through a local alias ('t <- counter.total; t++') instead of on the property itself

See also

  • E08090: variable declared but unused (this error)
  • E08080: self-assignment

Examples

Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.

Fails with E08090: is not referenced anywhere, or not referenced after assignment

#!ek9
defines module error.e08090.bad

  defines record

    Counter
      total as Integer: Integer()

      default operator ?

  defines function

    area()
      ->
        width as Integer
        height as Integer
      <- rtn as Integer: width * height

      border <- 2

    label()
      <- rtn as String: "plain"
      suffix as String?

    bump()
      -> counter as Counter

      //The alias IS the property, so this DOES change counter.total - but the long way round.
      alias <- counter.total
      alias++

Fixed: Remove what is never used (or use it), and change a property directly

#!ek9
defines module error.e08090.good.fix

  defines record

    Counter
      total as Integer: Integer()

      default operator ?

  defines function

    area()
      ->
        width as Integer
        height as Integer
      <- rtn as Integer: width * height

    label()
      <- rtn as String: "plain"

    bump()
      -> counter as Counter

      counter.total += 1

Fixed: Remove the variable, or use it

#!ek9
defines module error.e08090.good

  defines class

    Order

      total as Integer?

      Order()
        total: Integer(10)

      getTotal()
        <- rtn as Integer: total

      default operator ?

  defines record

    Counter
      total as Integer: Integer()

      default operator ?

  defines function

    area()
      ->
        width as Integer
        height as Integer
      <- rtn as Integer: width * height

    framedArea()
      ->
        width as Integer
        height as Integer
      <- rtn as Integer?
      border <- 2
      rtn: (width + border) * (height + border)

    bumped()
      -> counter as Counter
      <- rtn as Integer: Integer()

      //Read after the change, so the alias is used.
      alias <- counter.total
      alias++
      rtn: alias

    bumpOrder()
      -> order as Order

      //A call's result may be a view of what the order holds, so changing it is a use of that.
      view <- order.getTotal()
      view++

Questions and answers

These Q&A entries show E08090 and its fix: