# New Issue: \[Bug\]: Incorrect error for type method with same name as field

**URL:** <https://chapel.discourse.group/t/new-issue-bug-incorrect-error-for-type-method-with-same-name-as-field/48643>\
**Category:** Issues\
**Created:** [March 26, 2026, 5:36pm UTC](https://chapel.discourse.group/t/new-issue-bug-incorrect-error-for-type-method-with-same-name-as-field/48643 "2026-03-26T17:36:29Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![jabraham17](https://avatars.discourse-cdn.com/v4/letter/j/ecb155/32.png) [@jabraham17](https://chapel.discourse.group/u/jabraham17)\
**Post date:** [March 26, 2026, 5:36pm UTC](https://chapel.discourse.group/t/new-issue-bug-incorrect-error-for-type-method-with-same-name-as-field/48643/1 "2026-03-26T17:36:29Z")

</div>

28599, "jabraham17", "[Bug]: Incorrect error for type method with same name as field", "2026-03-26T17:35:52Z"

> <https://github.com/chapel-lang/chapel/issues/28599>
>
> The following code fails to compile, when I think it should
> 
> \`\`\`chapel
> 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
> \`\`\`chapel
> // 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
> \`\`\` chapel
> 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)

The following code fails to compile, when I think it should

```chapel
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/](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

```Chapel
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

```chapel
// 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

```chapel
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)
