Skip to content

regression: rejected array element write no longer throws — non-writable inherited index (blocks release) #9478

Description

@proggeramlug

Symptom

cargo-test-perry (4/8) fails, blocking full-suite-gate and therefore any
release cut:

test reflect_define_property_non_writable_prototype_index_blocks_array_store ... FAILED
assertion `left == right` failed: reflect_define_property output must match Node
  left:  "no error 1 P\n"
  right: "TypeError 1 P\n"

Node confirms the test is correct

$ cat /tmp/dp.mjs
Reflect.defineProperty(Array.prototype, 11, { value: "P", writable: false, configurable: true });
const a = [];
let err = "no error";
try { a[11] = 1; } catch (e) { err = e.constructor.name; }
console.log(err, a.length, a[11]);

$ node /tmp/dp.mjs
TypeError 0 P

A write rejected by a non-writable inherited index must throw in strict mode.
Perry does not throw — so this is a regression, not a stale expectation.

Likely cause

The test was added by 0e9ba1d (#9392, "honor defineProperty prototype
index setters"), so it passed at that commit. Two later commits changed exactly
this semantics:

So the throw is now gated on strict mode, and this program is evidently not
being treated as strict. Either the strictness lowering does not reach this
path, or the test's program (a bare snippet with no import/export) is compiled
as a script rather than a module while node runs the equivalent as a module.

I have deliberately not guessed at the fix: which of those two it is
determines the correct change, and it sits inside an in-flight refactor
(#9418 / #9423 / #9426) whose author knows the intended semantics.

Why this should not be papered over

Unlike the pre-existing failures tolerated in #9385 and #9471, this one is a
new regression introduced this week. Ignoring it would ship a real behaviour
change: a rejected array-element write silently succeeding where the spec (and
node) require a TypeError.

Reproduce

cargo build -p perry -p perry-runtime-static -p perry-stdlib-static
RUST_TEST_THREADS=1 cargo test -p perry --test issue_9249_array_prototype_define_property

Activity

  1. proggeramlug commented on Sep 2, 2026

    @proggeramlug
    ContributorAuthor

    Retracting this — I used the wrong oracle. Perry is correct; the test expectation is stale.

    I originally compared against a .mjs file, which node treats as a module (hence strict, hence TypeError). The test compiles a bare .ts, and this project's oracle is node --experimental-strip-types, which runs it as a script (sloppy mode). Re-run with the right oracle:

    Perry, with "use strict":                      TypeError 1 P
    Perry, as written (script):                    no error 1 P
    node --experimental-strip-types, same .ts:     no error 1 P     <- identical to Perry
    

    So dcf1ec0fbc (#9426, "a rejected array element write throws only in strict mode") made Perry match node, and strictness demonstrably still works — the "use strict" run throws exactly as it should.

    The stale part is issue_9249_array_prototype_define_property.rs, which asserts TypeError from a sloppy-mode script. Its intent — proving a non-writable inherited index blocks the store — is still worth testing, so the fix is to run that case in strict mode rather than to weaken the assertion.

    Closing in favour of that test fix. Apologies for the noise; the lesson is to compare against the oracle the suite actually uses (node --experimental-strip-types on the .ts), not an equivalent .mjs.

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