chapel-lang / chapel

a Productive Parallel Programming Language
https://chapel-lang.org
Other
1.79k stars 420 forks source link

[Bug]: cannot explicitly specify a generic range return type #26114

Open jabraham17 opened 1 week ago

jabraham17 commented 1 week ago

Summary of Problem

Description:

Attempting to specify a generic return type for a range with a non-default type results in an error. However, fully specifying the return type does work. And just removing the explicit return type also works.

I believe this is a quirk of range being generic with defaults, such that range(?) gives you the defaults. I would have expected that range says "the return type is a range with the type defaults" and range(?) says "the return type is a range with unknown type"

Steps to Reproduce

Source Code:

proc foo(): range(?) { // error: initializing a range with strideKind.one from a range with strideKind.positive
  return 1..10 by 2;
}
writeln(foo());

proc foo() { // this is fine and is a workaround
  return 1..10 by 2;
}

proc foo(): range(int, boundKind.both, strideKind.positive) { // this is also fine, being full explicit
  return 1..10 by 2;
}

Compile command: chpl foo.chpl

Configuration Information

bradcray commented 1 week ago

I believe this is a quirk of range being generic with defaults, such that range(?) gives you the defaults.

I'd also expect that range(?) should not get you the defaults. In other cases, I believe that's the case, such as:

var r: range(?) = 1..10 by -2;
writeln(r);

proc foo(r: range(?)) {
  writeln(r);
}

foo(r);

which works as expected.

Your issue also seems to be consistent for other fully-defaulted generics:

record R {
  param n = 1;
}

proc foo(): R(?) {
  return new R(n=2);
}
writeln(foo());  // similar error

But interestingly, not for partially-defaulted generics:

record R {
  param n = 1;
  param k;
}

proc foo(): R(?) {
  return new R(n=2, k=33);
}
writeln(foo());  // works

[edited to update comments, which I'd copied without updating]