Skip to content

classes: named class-expression .name returns the outer binding name, not the class name #6679

Description

@proggeramlug

Found by the composition-stress differential harness (secret-tests/diffharness) Phase 1 bundle matrix (diverges at ALL 20 bundle shapes — a core semantics bug, not a lowering artifact). perry target/release/perry @ 2026-07-15.

Symptom

For a named class expression, the explicit name must win; perry returns the outer binding name instead.

const B = class Named {};
console.log(B.name);            // spec: "Named"   perry: "B"     <-- BUG
const A = class {};
console.log(A.name);            // spec: "A"        perry: "A"     (control: inferred name is correct)
node : Named \n A
perry: B \n A

perry applies assignment name-inference (SetFunctionName from the const B = target) even when the class expression already carries its own name, clobbering it.

Suspected subsystem

Class-expression .name binding — the "explicit name present" guard is skipped, so inferred-from-assignment overrides the declared class name. Same #6604/#6633 class-expression area as the open follow-up #6654, but a distinct symptom (.name value, not capture-refresh).

Repro

perry /tmp/c.ts -o /tmp/c && /tmp/c

Severity: low-medium — wrong string value; breaks code keyed on constructor.name (DI containers, serializers, discriminated dispatch).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugConfirmed defect or regressionparityCompatibility gap with Node.js, ECMAScript, or the supported ecosystem

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions