Blatant return error confuses compiler

The following (wrong!) code

var ax: [1..10] real = 1.0;
var yc = wrong(ax);
proc wrong(
   const in ax: [] real
   ): real
   where (ax.rank == 1): real {
   return 0.0;
}

has a blatant error: there should not be a " : real" after the where clause. This error causes a very cryptical error message,

nowhere.chpl:3: In function 'wrong':
nowhere.chpl:3: error: unresolved call '&(1.0, 1)'
$CHPL_HOME/modules/internal/ChapelBase.chpl:1067: note: this candidate did not match: &(a: bool, b: bool)
nowhere.chpl:3: note: because actual argument #1 with type 'real(64)'
$CHPL_HOME/modules/internal/ChapelBase.chpl:1067: note: is passed to formal 'a: bool'
nowhere.chpl:3: note: other candidates are:
$CHPL_HOME/modules/internal/ChapelBase.chpl:1069: note:   &(a: int(8), b: int(8))
$CHPL_HOME/modules/internal/ChapelBase.chpl:1070: note:   &(a: int(16), b: int(16))
note: and 36 other candidates, use --print-all-candidates to see them
  nowhere.chpl:1: called as wrong(ax: [domain(1,int(64),one)] real(64))
note: generic instantiations are underlined in the above callstack

Since my mistake might be somewhat common (where does the return type go? before or after the where ? -- In my case I did both!), maybe the compiler could catch the second " : real " and stop right there?

Cheers

Nelson

There are some cases where this is caught today. For example, if you take your code and use int instead of real, the compiler gives you a nice error.

var ax: [1..10] real = 1.0;
var yc = wrong(ax);
proc wrong(
   const in ax: [] real
   ): real
   where (ax.rank == 1): int {
   return 0.0;
}
bug.chpl:3: In function 'wrong':
bug.chpl:3: error: invalid where clause
  bug.chpl:1: called as wrong(ax: [domain(1,int(64),one)] real(64))
note: generic instantiations are underlined in the above callstack

I have not looked too hard into why this error is not being propagated properly for real. I think what happens is during normalize the compiler inserts & because the array formal is used. With int, this whole expression could be resolved and then later the invalid where check fires and gives a nice error. With real, the resolution of this expression fails and you get a weird error long before you reach the check for where clauses.

This should be a better error message.

As an aside, I will note that the moment I opened this code in my editor I got a nice error from the Chapel language server, which could save time for you and others.

-Jade

1 Like

Hi Nelson —

[I wrote this up in parallel with Jade's message, but think it says some different things so am posting it all the same]

This is definitely a terrible error message, and if you would open an issue capturing it and requesting an improvement, that would be great.

I don't think we can simply make this a parsing error (if that's what you're proposing) since : is not only used for specifying types, but also for casts. And since the where clause is intended to be a general Chapel expression, there's no reason to prevent it from using the cast operator.

That said, there is still plenty of room to improve the message, for example by complaining if the result is not a bool (or perhaps an int if we permit coercions to bool in where-clauses? I can't recall offhand and would need to check...).

Thanks for bringing this to our attention,
-Brad

PS — As a somewhat contrived example of where a cast in a where clause might make sense, I might have:

config param debug, verbose, myFlag: bool;`

proc foo() where (debug + verbose + myFlag): bool { … }

as a way of checking whether any of the three flags are true. Personally, I'd prefer to see this written as where (debug || verbose || myFlag) stylistically, but don't think we should rule out the ability to write such code.

Thanks Jade and Brad!

Jade, out of curiosity, what editor are you using, and how do you make it interact with the language server?

I opened an issue in the github page.

1 Like

The screenshot is from vim, but it also works in VSCode

The setup is easiest for VSCode, you just need the language server installed and the vscode Chapel extension (with the resolver turned on). If you have a binary release of Chapel, you should have the language server already installed. If you built from source, you also need to build it with make chpl-language-server

For vim, its a little more involved because you need to setup vim with some extra plugins. Other editors will work as well.

There are docs for all of these here: Editor Support For Chapel — Chapel Documentation 2.9. If you use an editor not listed here, the language server will mostly likely work, its just a matter of setting it up.

-Jade

thanks!

Nelson,

I have taken to letting the compiler decide on the return type. In the event that it gets confused between the values at two different return statements, I cast the value(s) as appropriate. I do not rely on the compiler doing any type promotion/coercion.

Thanks Damian! Just a thing: doesn't it leave the door open for inadvertent returns of the wrong type? Cheers Nelson

For those following this discussion, I've merged a PR to improve Chapel's error messages for unexpected where clause expressions today, so things should be better in main or in next month's 2.9 release.

Thanks to Nelson for bringing this issue to our attention,
-Brad