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.
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))
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.
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