Skip to content

[compiler] Default parameter values are not applied on dynamic dispatch #11562

Description

Default parameter values are not applied when a method is called through dynamic dispatch. A call through an interface-typed or any-typed reference passes only the arguments written at the call site; the missing ones arrive as undefined and the parameter initializer never runs.

Repro: https://makecode.com/_EjWTcAMaqhyX

interface Shape {
    scaled(x: number, factor?: number): number;
}

class Thing implements Shape {
    scaled(x: number, factor = 5) {
        return x * factor;
    }
}

const t = new Thing();
const s: Shape = t;

console.log(t.scaled(2));   // 10  -- static call, default applied
console.log(s.scaled(2));   // NaN -- same object via interface: default not applied

Root cause is in the emitter, not a backend: defaults are filled in at the call site from the statically known signature (addDefaultParametersAndTypeCheck). A dynamically dispatched call site has no signature, so nothing fills the argument, and there is no callee-side default application to catch it -- the arity wrapper pads with undefined. A fix likely means emitting callee-side default application for methods reachable through dynamic dispatch.

It seems like a not-recent bug: reproduces on pxt v12.3.14 (the release prior to my recent optimizations), and the call-site filling mechanism dates to 2017.

A ready-made red test is checked in disabled: uncomment the REPRO block in tests/compile-test/lang-test0/57defaultparamdispatch.ts (added in #11561) and gulp testlang fails with qzdp:iface. The file's active assertions pin the behavior that must hold regardless of the fix (concrete-path defaults, explicit-argument calls, and agreement between the interface and any paths).

Workaround: pass every argument explicitly at dynamic call sites, or have the callee test for undefined itself.

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