28599, "jabraham17", "[Bug]: Incorrect error for type method with same name as field", "2026-03-26T17:35:52Z"
The following code fails to compile, when I think it should
record R {
var x: int = 17;
}
proc type R.x param do return 1;
var r = new R();
writeln(r.x); // 17
writeln(R.x); // 1
This fails with parenless proc redeclares the field 'x'. The spec says "It is a redeclaration error to define a method without parentheses with the same name as a field.", but I would argue that a "type method" is different from a "method". This seems to be fallout from https://github.com/chapel-lang/chapel/pull/22917/, which adjusted how we determine shadowing, especially with parenless procs
A naive fix is the following patch
diff --git a/frontend/lib/resolution/resolution-queries.cpp b/frontend/lib/resolution/resolution-queries.cpp
index 3ca837608f8..c6e8570769a 100644
--- a/frontend/lib/resolution/resolution-queries.cpp
+++ b/frontend/lib/resolution/resolution-queries.cpp
@@ -770,7 +770,8 @@ static void
checkForParenlessMethodFieldRedefinition(Resolver& rv, const Function* fn) {
Context* context = rv.context;
- if (fn->isMethod() && fn->isParenless()) {
+ if (fn->isMethod() && fn->isParenless() &&
+ fn->thisFormal()->intent() != Formal::Intent::TYPE) {
bool allowNonLocal = false;
if (auto receiverInfo = rv.closestMethodReceiverInfo(allowNonLocal)) {
auto compositeId = std::get<0>(*receiverInfo);
However, this then exposes a different compiler issue
// chpl bug.chpl --no-devel --explain-call x
bug.chpl:7: note: call: R.x
bug.chpl:4: note: visible functions are: type R.x
bug.chpl:7: note: no candidates found
bug.chpl:7: error: unresolved call 'R.x'
bug.chpl:4: note: this candidate did not match: type R.x
bug.chpl:7: note: because non-type method call receiver
bug.chpl:4: note: is passed to formal 'this: R'
bug.chpl:7: note: call: R.x
bug.chpl:4: note: visible functions are: type R.x
bug.chpl:7: note: no candidates found
This fails to resolve both r.x (the field access) and R.x (the parenless type method call).
Note the following similar program does work
record R {
}
proc R.x {
return 17;
}
proc type R.x param do return 1;
var r = new R();
writeln(r.x); // 17
writeln(R.x); // 1
This works exactly as expected, r.x (parenless method call) and R.x (parenless type method call)