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
Symptom
cargo-test-perry (4/8)fails, blockingfull-suite-gateand therefore anyrelease cut:
Node confirms the test is correct
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:
dcf1ec0fbc— "a rejected array element write throws only in strict mode"(from fix(runtime): SIGPIPE, non-UTF-8 argv, and sloppy-mode array store strictness (#9402, #9401, #9394) #9418) (fix(runtime): a rejected array element write throws only in strict mode (from #9418) #9426)
e7436992f1— "ES module init is lowered strict (ESM module-init code is lowered with is_strict_fn: false — top-level strictness is wrong for some lowerings #9423); a rejected strictarr.lengththrows for a non-writable …"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