20521, "stonea", "Improving error messages --- infinite recursion in record construction", "2022-08-26T04:18:15Z"
This arguably isn't a bug but I do feel there's an opportunity for usability improvement here ---
Creating a datatype that constructs itself in an infinitely recursive fashion is a silly thing to do but is something that users might, nevertheless, accidentally do. What's a little surprising is how we error (and how useful the error message is) varies based on how we introduce the recursion ---
record MyRecord {
var D : domain(1);
var children : [D] MyRecord;
proc init() {
this.D = {0..0};
}
}
const x = new MyRecord();
// Has a runtime error (at least on my mac) with: zsh: bus error ./foo
record MyRecord {
var children;
proc init() { this.children = [new MyRecord()]; }
}
const x = new MyRecord();
// Has a compile time error:
// foo.chpl:4: internal error: RES-FUN-ION-2618 chpl version 1.28.0 pre-release (9655811de5)
// Note: This source location is a guess.
record MyRecord {
var children : [0..0] MyRecord;
}
const x = new MyRecord();
// Has a compile time error:
// $CHPL_HOME/modules/internal/ChapelArray.chpl:2841: error: unable to resolve return type of function 'chpl__coerceCopy'
// foo.chpl:1: error: called recursively at this point
-
The first example doesn't have a great error (though really it's no worse than what you would get if you tried the same thing in C or C++). It would be nicer if we reported we were out of memory or something and showed where the last allocation occurred (at least if we're not compiling with
--fast). -
The second example is nicer in that it errors out at compile time and gives a correct filename/linenumber to the line I'd have to fix. Still "internal error" is something users should never see.
-
The third example is even better in that it errors out at compile time and mentions recursion. The fact that it mentions an internal function
chpl__coerceCopyis somewhat confusing from the users perspective though.