Those who have monitored the Pike 7.7 CVS the last week or so, may have noticed a few new type checking related functions. These are intended to replace the current style of type checking where a function type for the current call is created and then compared in one pass against the declared type. This has led to somewhat cryptic error messages. eg:
`+((["":14]), "", 14);
Compiler Error: 1:Bad argument 2 to `+. Compiler Error: 1:Expected: !function(!(object | mixed) ... : mixed) & function | function(int, int ... : int) | !function(!float ... : mixed) & function(int | float, int | float ... : float) | !function(!string ... : mixed) & function(string | int | float, string | int | float ... : string) | function((0=array), (1=array) ... : 0 | 1) | function((0=mapping), (1=mapping) ... : 0 | 1) | function((0=multiset), (1=multiset) ... : 0 | 1) Compiler Error: 1:Got : function(mapping(string(0):int(14..14)), string(0), int(14..14) : void | mixed)
The new code is instead based on checking the arguments one at a time, but this means that the error in the above case is first detected when the last argument is checked:
Compiler Error: 1:Bad argument 3 to `+, got int(14..14), expected object.
This problem can be reduced by also adding warnings about prior arguments in case of the above error:
Compiler Warning: 1:Potentially bad argument 2 to `+, got string(0), expected mapping | object.
The question is what text the warning should have.
Hm, that's a lot more readable. Question, could the type be reduced further,
Compiler Error: 1:Bad argument 3 to `+, got int, expected object.
Compiler Warning: 1:Potentially bad argument 2 to `+, got string, expected mapping | object.
since the basic type is wrong, there is no need to display the subtype.
I think the warning text looks ok, but it should probably only display if there *is* a following error.
I personally wonder if it would be possible to do a lookup from object(27839) to the name of the class for that type.
Great improvement. Wouldn't it be an improvement to short all those int(X..X) to just int(X)? Not when manually typing, but in the debug output.
Not exactly hard to fix:
Pike v7.7 release 30 running Hilfe v3.5 (Incremental Pike Frontend)
_typeof(master());
(1) Result: object(is master)
typeof(Stdio.File());
(2) Result: object(is Stdio.File)
typeof(Stdio.File);
(3) Result: function(void | string | int, string | void, int | void : object(is Stdio.File))
Now actually implemented:
`+((["":14]), "", 14);
Compiler Error: 1:Too few arguments to `+ (got 3). Compiler Error: 1:Expected: object
One interesting problem along the way was the splice operator, but it now creates a proper closure. I've also made it continue with the argument checking after the first failure:
$ cat plice_test.pike string foo(int a, int b, int c, float f, string s) { return s; }
array(int) a = ({ 1, 2, 3 });
int main(int argc, array(string) argv) { werror("Test: %O\n", typeof(foo(1, @a, "bar", this))); }
$ pike.old splice_test.pike splice_test.pike:7:Bad argument 4 to foo. splice_test.pike:7:Expected: function(int, int, int, float, string : string) splice_test.pike:7:Got : function(int(1..1), int | object(implements 65619) | string | void ... : void | mixed) Pike: Failed to compile script: Compilation failed. ... $ pike splice_test.pike splice_test.pike:7: Warning: The splice operator argument has a max length of 2. splice_test.pike:7:Bad argument 3 to foo. splice_test.pike:7:Expected: int | float splice_test.pike:7:Got : string(8) splice_test.pike:7:Bad argument 4 to foo. splice_test.pike:7:Expected: float | string | int splice_test.pike:7:Got : object(implements program(/home/grubba/src/Pike/7.7/build/dmalloc/splice_test.pike)) Pike: Failed to compile script: Compilation failed. ...
Enabling the new argument checker is currently done by enabling the #define NEW_ARG_CHECK in las.c.
Enjoy.
pike-devel@lists.lysator.liu.se