Skip to content

Compound assignment to a DECLARED static class field is silently dropped (K.n += 1 leaves K.n unchanged; = and ++ work) — both modes #9526

Description

@proggeramlug
class K { static n = 1; }
K.n = 5;   console.log(K.n);   // 5      (correct)
K.n += 1;  console.log(K.n);   // node 6   Perry 5
K["n"] += 1; console.log(K.n); // node 7   Perry 5
const k = "n"; K[k] += 1; console.log(K.n); // node 8   Perry 5
K.n++;     console.log(K.n);   // node 9   Perry 6   (`++` itself is applied; the three `+=` were lost)

Identical in an ESM .ts module (strict) and a .cts script (sloppy). Compound assignment to a declared static field is silently dropped; plain = (Expr::PutValueSet) and ++ (Expr::PropertyUpdate) on the same field are applied. An undeclared static (class D {}; (D as any).m = 1; (D as any).m += 12) is correct in both modes, so the dynamic class-property bag is not the problem — the declared static field has its own storage that the = and ++ lanes reach and the Expr::PropertySet lane (o.x += 1, o["x"] += 1, o[k] += 1, and presumably for (K.n of …) / [K.n] = …) does not: the store presumably lands in the class's dynamic-property bag and the next read of K.n comes from the static slot.

Reproduced on fix/propertyset-strict (PR #9519's head, main + two commits that do not touch static fields); the strict lane there is byte-identical to main, so this is pre-existing on main in both modes. Found while building the #9495 fixture (which now uses an undeclared static as its class-ref control instead). Not a strictness or prototype-walk defect — #9459 / #9495 leave it as it was.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions