Found while fixing #10623 (PR #10636). Reproduces on clean main, unrelated to that PR.
class NoCtorUrl extends URL {}
const u = new NoCtorUrl("https://example.com/path");
console.log(u.hostname, u.pathname);
Node: example.com /path
Perry: undefined undefined
This is not an argument-forwarding defect. The explicit form fails identically:
class ExplicitUrl extends URL {
constructor(href: string) { super(href); } // same result: undefined undefined
}
That distinguishes it from #10623 (implicit ctor not forwarding to a native base) and from #10635 (rest array
over-allocated when forwarding) — the arguments arrive; the instance simply never gets URL's internal state.
Where it likely lives
crates/perry-codegen/src/lower_call/new.rs, the is_other_builtin_constructor_name /
parent_is_uncallable_builtin gate. A comment on that mechanism states in substance that Perry cannot give a
subclass instance a builtin's internal slots, so super() to such a base is a deliberate best-effort no-op — and
the observed silent-undefined, no-throw behaviour matches that exactly.
Two things to confirm before fixing: (1) that URL is literally in that matched name list (inferred from the
comment plus behaviour, not re-read); (2) the reporter's URL tests all ran inside a closure wrapper, the same
context that triggers a separate Map/Set defect — so isolate at true top level first to rule out that confound,
even though the mechanism named above reads as a compile-time, scope-independent decision.
If this really is a deliberate limitation rather than a bug, the right outcome may be a clear thrown error
instead of silently producing an object with undefined everywhere.
Found while fixing #10623 (PR #10636). Reproduces on clean
main, unrelated to that PR.Node:
example.com /pathPerry:
undefined undefinedThis is not an argument-forwarding defect. The explicit form fails identically:
That distinguishes it from #10623 (implicit ctor not forwarding to a native base) and from #10635 (rest array
over-allocated when forwarding) — the arguments arrive; the instance simply never gets URL's internal state.
Where it likely lives
crates/perry-codegen/src/lower_call/new.rs, theis_other_builtin_constructor_name/parent_is_uncallable_builtingate. A comment on that mechanism states in substance that Perry cannot give asubclass instance a builtin's internal slots, so
super()to such a base is a deliberate best-effort no-op — andthe observed silent-
undefined, no-throw behaviour matches that exactly.Two things to confirm before fixing: (1) that
URLis literally in that matched name list (inferred from thecomment plus behaviour, not re-read); (2) the reporter's URL tests all ran inside a closure wrapper, the same
context that triggers a separate Map/Set defect — so isolate at true top level first to rule out that confound,
even though the mechanism named above reads as a compile-time, scope-independent decision.
If this really is a deliberate limitation rather than a bug, the right outcome may be a clear thrown error
instead of silently producing an object with
undefinedeverywhere.