Skip to content

codegen: user method named like a String builtin (internals.trim(value, schema)) mis-lowered to String.prototype.<m> on non-string receivers — joi #5271

Description

@proggeramlug

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugConfirmed defect or regression

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions