New Issue: [Bug]: Compiler-generated functions are missed during function-method ambiguity checks

28491, "DanilaFe", "[Bug]: Compiler-generated functions are missed during function-method ambiguity checks", "2026-03-03T22:15:43Z"

This is a weird one. Arkouda is a motivator. In particular, Arkouda has a class, ServerDaemon, which invokes a proc called deserialize in its body:

This deserialize method is actually a free-standing (non-method) procedure:

At first, this looks innocent. However, Dyno balked at this, and when I took a closer look, I realized why: this is normally an ambiguous call!

In Dyno and in production, the following program is ambiguous:

proc foo() {}
record R {
  proc foo() {}
  proc bar() { foo(); }
}

Specifically, we have an ambiguity between a method and a non-method call. This was implemented as part of Shadowing improvements by mppf · Pull Request #22917 · chapel-lang/chapel · GitHub, though I haven't nailed down the specific GitHub issue in which the method-non-method ambiguity was discussed.

So... why does Arkouda compile here? It turns out that the ambiguity error is emitted during scope resolution, but default functions aren't inserted until AFTER scope resolution. So, as a result, all default functions automatically have lower precedence when called with an implicit receiver than standalone procedures.

In other words, this is ambiguous:

proc bar(x, y) {}

record R {
  proc bar(x, y) {}
  proc foo() {
    bar(1, 2);
  }
}
(new R()).foo();

But this is not:

proc deserialize(x, y) {}

record R {
  /* generated proc deserialize (x, y) {} */
  proc foo() {
    bar(1, 2);
  }
}
(new R()).foo();