lib.types.functionTo: preserve functionArgs

Previously if function in defs had set pattern in argument,
this information would be lost.

This keeps functionArgs in set pattern,
by using functor and `__functionArgs`
that is later used by `lib.functionArgs`.
This commit is contained in:
Wroclaw 2025-03-01 18:16:38 +01:00
parent 2d1fce7ff9
commit 0de1d18795
2 changed files with 22 additions and 2 deletions

View file

@ -2521,6 +2521,21 @@ runTests {
expr = (with types; either int (listOf (either bool str))).description;
expected = "signed integer or list of (boolean or string)";
};
testTypeFunctionToPropagateFunctionArgs = {
expr = lib.functionArgs ((types.functionTo types.null).merge [] [
{
value = {a, b ? false, ... }: null;
}
{
value = {b, c ? false, ... }: null;
}
]);
expected = {
a = false;
b = false;
c = true;
};
};
# Meta
testGetExe'Output = {

View file

@ -873,8 +873,13 @@ rec {
description = "function that evaluates to a(n) ${optionDescriptionPhrase (class: class == "noun" || class == "composite") elemType}";
descriptionClass = "composite";
check = isFunction;
merge = loc: defs:
fnArgs: (mergeDefinitions (loc ++ [ "<function body>" ]) elemType (map (fn: { inherit (fn) file; value = fn.value fnArgs; }) defs)).mergedValue;
merge = loc: defs: {
# An argument attribute has a default when it has a default in all definitions
__functionArgs = lib.zipAttrsWith (_: lib.all (x: x)) (
lib.map (fn: lib.functionArgs fn.value) defs
);
__functor = _: callerArgs: (mergeDefinitions (loc ++ [ "<function body>" ]) elemType (map (fn: { inherit (fn) file; value = fn.value callerArgs; }) defs)).mergedValue;
};
getSubOptions = prefix: elemType.getSubOptions (prefix ++ [ "<function body>" ]);
getSubModules = elemType.getSubModules;
substSubModules = m: functionTo (elemType.substSubModules m);