How does EK9 detect self-assignment and self-comparison?

← Code Quality · Ref: Q318

EK9 detects two categories of self-referential operations that are always programming errors.

SELF-ASSIGNMENT (E08080)

Assigning a variable to itself is always pointless. The value does not change. This typically happens from copy-paste errors where the developer duplicated a line and forgot to change one side. Example: 'name: name' assigns name to itself.

SELF-COMPARISON (E08081)

Comparing a variable to itself always produces a constant result. 'x == x' is always true. 'x <> x' is always false. 'x < x' is always false. These are never intentional and indicate a copy-paste error where the developer meant to compare two different variables.

FLAGGED OPERATORS

Self-comparison is detected for all comparison and containment operators: ==, <>, <, >, <=, >=, <=>, <~>, contains, and matches. Each of these produces a constant result when both sides are the same variable.

COPY-PASTE ERROR DETECTION

These checks exist specifically to catch copy-paste errors. When duplicating code, it is easy to write 'if price == price' instead of 'if price == discountedPrice'. Without this check, the bug silently evaluates to true and the discount logic is bypassed.

See Q311 for the full quality checks catalog. See Q239 for comparison operators. See Q637 for safe comparison patterns with distinct variable names.

Example

defines module qa.codequality.selfops

  defines function

    <?-
      Correct comparisons use different variables on each side.
      The compiler would reject x == x or x: x.
    -?>
    findCheaper() as pure
      ->
        priceA as Float
        priceB as Float
      <-
        cheaperPrice as Float: priceA

      if priceB < priceA
        cheaperPrice: priceB

    compareNames() as pure
      ->
        firstName as String
        lastName as String
      <-
        sameIdentity as Boolean: firstName == lastName

  defines program

    SelfOperationsDemo()
      stdout <- Stdout()

      shopPrice <- 29.99
      onlinePrice <- 24.99
      bestPrice <- findCheaper(shopPrice, onlinePrice)
      stdout.println(`Best price: ${bestPrice}`)

      givenName <- "John"
      familyName <- "Smith"
      identicalName <- compareNames(givenName, familyName)
      stdout.println(`Same name: ${identicalName}`)

Common mistakes

E08081 — Comparing a variable to itself always produces a constant result (always false for <). This is a copy-paste error. See ek9 -h E08081 for details.

Incorrect:

if priceA < priceA

Correct:

if priceB < priceA

E08080 — Assigning a variable to itself is pointless and indicates a copy-paste error. See ek9 -h E08080 for details.

Incorrect:

cheaperPrice: cheaperPrice

Correct:

cheaperPrice: priceB
Other ways to ask this
  • What is E08080 self-assignment in EK9?
  • How does EK9 catch copy-paste errors?
  • What does E08081 self-comparison mean?

Coming from another language?

Java: SonarQube has SelfAssignment and SelfComparison rules but optional. SpotBugs detects SA_FIELD_SELF_ASSIGNMENT. Rust: clippy has eq_op lint for self-comparison (warn by default). Go: go vet detects self-assignment in some cases. Python: no self-comparison detection in standard tools. C++: compiler warnings for some self-comparisons with -Wall. EK9: mandatory compiler error for both self-assignment and self-comparison, covers all comparison operators.

Keywords: paste, metric, error, comparison, E08081, E08080, constant, copy, clean-code, pointless, quality, self, assignment