Bug #6271
closedIn 4.0, reduced-arity coercion fails when target function has optional parameters
0%
Description
See QT3 test case FunctionCall-417
declare function local:f($x as xs:string, $y as xs:string, $z as xs:string := '1900-01-01') as xs:string {
concat($x, '-', $y, ' on ', $z)
};
declare function local:g($x as xs:string, $z as function(xs:string, xs:string, xs:integer) as xs:string) {
$z($x, $x, 22)
};
local:g("ABC", local:f#2)
The function local:f#2 should be equivalent to fn($x, $y){concat($x, '-', $y, ' on ', '1900-01-01')
; the call on $z should accept this arity-2 function by virtue of reduced-arity coercion, and the third argument (22) should be ignored. In fact we get a run-time type error because local:f expects a string, not an integer, as its third argument.
The effect is more noticeable when we supply something like deep-equal#2 as an argument to for-each-pair. Now that for-each-pair accepts an arity-3 callback, with the third argument being an integer position, we get a spurious failure because deep-equal has an arity-3 variant that expects a string as the third argument. (But this manifestation is not present in 12.4, because that does not yet implement the arity-3 callback on for-each-pair).
Updated by Michael Kay 5 months ago
- Status changed from New to In Progress
To get this example working I made the following changes:
-
In UserFunction, add a method to get the function item type for a specific arity within the function's arity range. The current
getFunctionItemType()
method gets the maximum-arity type. -
In UserFunctionReference, if the target function is a user function, call the new method in (1) in
getFunctionItemType()
-
Change CoercedFunction.getArity() to get the arity of the function after coercion, rather than the arity of the target function.
-
Change UserFunctionReference.copy() to call the two-argument constructor, needed to avoid changing the arity.
So far so good but I'm not sure item (2) is enough for the general case; it only handles the case where the target is a UserFunction. (The class UserFunctionReference
is misnamed; it can also be used where the target is a context-dependent system function reference).
Updated by Michael Kay 5 months ago
As suspected, a further fix was needed to handle references to system functions: change SystemFunction.getFunctionItemType()
to return only as many argument types as appropriate for the value of getArity()
.
Updated by Michael Kay 5 months ago
- Category set to Features new in 4.0
- Status changed from In Progress to Resolved
- Applies to branch 12, trunk added
- Fix Committed on Branch 12, trunk added
- Platforms .NET, Java added
Please register to edit this issue