Context: corpus — blocks joi (node_modules/joi/lib/validator.js:359): internals.trim(value, schema) calls joi's own internals.trim (2 args), but perry statically lowers any .trim(...) to String.prototype.trim (0 args) regardless of receiver, then bails: perry-codegen: String.trim takes no args, got 2.
Root
The static String-method lowering fires for <recv>.trim(...) even when <recv> is a non-string object with its own trim method. The arity guard (String.trim takes no args, got N) then fails the compile. This generalizes to any user method that shares a name with a String (or other builtin) method.
Minimal repro
const internals = { trim(value: string, schema: any) { return value + ":" + schema; } };
console.log(internals.trim("a", "b"));
perry → Error: ... String.trim takes no args, got 2 (compile fails). Node → a:b.
Fix direction
Gate the static String-method lowering on a provably-string receiver (typed string / string literal). For object/any/unknown receivers — or when the arg count doesn't match the builtin's signature — route to normal dynamic method dispatch (the receiver's own member) instead of forcing String.prototype.<m> and erroring on arity. Likely in crates/perry-codegen/src/lower_string_method.rs (where the arity guard lives).
Impact
joi directly; broadly, any package with user methods named like String builtins (trim, split, replace, slice, …) on non-string receivers — a common collision.
Context: corpus — blocks joi (
node_modules/joi/lib/validator.js:359):internals.trim(value, schema)calls joi's owninternals.trim(2 args), but perry statically lowers any.trim(...)toString.prototype.trim(0 args) regardless of receiver, then bails:perry-codegen: String.trim takes no args, got 2.Root
The static String-method lowering fires for
<recv>.trim(...)even when<recv>is a non-string object with its owntrimmethod. The arity guard (String.trim takes no args, got N) then fails the compile. This generalizes to any user method that shares a name with a String (or other builtin) method.Minimal repro
perry →
Error: ... String.trim takes no args, got 2(compile fails). Node →a:b.Fix direction
Gate the static String-method lowering on a provably-string receiver (typed string / string literal). For object/
any/unknown receivers — or when the arg count doesn't match the builtin's signature — route to normal dynamic method dispatch (the receiver's own member) instead of forcingString.prototype.<m>and erroring on arity. Likely incrates/perry-codegen/src/lower_string_method.rs(where the arity guard lives).Impact
joi directly; broadly, any package with user methods named like String builtins (
trim,split,replace,slice, …) on non-string receivers — a common collision.