Visitar URL original
Destructuring default can't read an earlier binding; block function can't see a later const; panic on static #field + private accessor pair · Issue #1002 · trynova/nova · GitHub
Skip to content

Destructuring default can't read an earlier binding; block function can't see a later const; panic on static #field + private accessor pair #1002

Open

Description

@trackoor

1. A destructuring default that reads an earlier binding of the same pattern throws inside any function or block.

function f() { const { a, b = a } = { a: 1 }; return b; }
print(f());

nova eval t1.js throws Uncaught exception: ReferenceError: can't access lexical declaration 'a' before initialization (expected 1). The same happens for let, var, [a, b = a], and parameters (({ width, height = width }) => ...), because IdentifierReference::compile treats any reference whose AST ancestor is the enclosing VariableDeclarator or FormalParameter as a self-referential TDZ access (bytecode_compiler.rs:879-885).

2. A function declared in a block can't see a const or let declared later in that block.

{ function h() { return c; } const c = 2; print(h()); }

nova eval t2.js throws Uncaught exception: ReferenceError: Cannot access undeclared variable 'c'. (expected 2). In block_declaration_instantiation.rs:144-160, FunctionDeclaration is compiled during handle_block_lexically_scoped_declaration before later lexical declarations in the same block have called enter_lexical_scope().

3. Panic on class definition with a static private field and an instance private getter/setter pair.

class A { static #a = 1; get #b() {} set #b(v) {} }

nova eval t3.js panics:

thread 'main' panicked at nova_vm/src/ecmascript/execution/environments/private_environment.rs:279:13:
Attempted to get PrivateName outside the Private Environment's range

instance_private_method_count is incremented for both get #b and set #b (class_definition_evaluation.rs:249), while private_name_lookup_map deduplicates the pair to one PrivateName, so the static private field offset (instance_private_field_count + instance_private_method_count + private_identifier) exceeds private_env.names.len().

4. pop(), shift(), and splice() on a non-extensible array throw TypeError.

const a = Object.preventExtensions([1, 2]);
print(a.pop());

nova eval t4.js throws Uncaught exception: TypeError: Could not set property. (expected 2). Array::internal_set_extensible sets elems.len_writable = value (array.rs:320), marking length as non-writable when extensions are prevented even though Object.preventExtensions leaves length writable.

Version: main (591bf7ba0d, 2026-11-07), cargo build --release -p nova_cli.

Credit: https://ucsbplse.github.io/

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