mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-10-30 16:10:36 +00:00
lib.functionArgs: fix correctness for nested functors
Restore the correct behaviour prior to commit bb71feaec1
("lib.functionArgs: save a function call on every lookup")
while preserving its performance gain with best efforts.
This commit is contained in:
@@ -57,6 +57,7 @@ let
|
||||
foldlAttrs
|
||||
foldr
|
||||
functionArgs
|
||||
genAttrs
|
||||
generators
|
||||
genList
|
||||
getExe
|
||||
@@ -930,6 +931,54 @@ runTests {
|
||||
expected = "1.2.3";
|
||||
};
|
||||
|
||||
testFunctionArgsNestedFunctors =
|
||||
let
|
||||
faOrig = {
|
||||
x = false;
|
||||
};
|
||||
faAlt = {
|
||||
x = false;
|
||||
y = true;
|
||||
};
|
||||
f0 = { x, ... }: x;
|
||||
in
|
||||
{
|
||||
expr = {
|
||||
a = functionArgs {
|
||||
__functor = self: {
|
||||
__functor = self: f0;
|
||||
__functionArgs = faAlt;
|
||||
};
|
||||
};
|
||||
b = functionArgs { __functor = self: { __functor = self: f0; }; };
|
||||
c = functionArgs {
|
||||
__functor = {
|
||||
__functor = self: outer: f0;
|
||||
};
|
||||
};
|
||||
d = functionArgs {
|
||||
__functor = {
|
||||
__functor = self: outer: {
|
||||
__functor = self: f0;
|
||||
__functionArgs = faAlt;
|
||||
};
|
||||
};
|
||||
};
|
||||
e = functionArgs {
|
||||
__functor = {
|
||||
__functor = self: outer: { __functor = self: f0; };
|
||||
};
|
||||
};
|
||||
};
|
||||
expected = {
|
||||
a = faAlt;
|
||||
b = faOrig;
|
||||
c = faOrig;
|
||||
d = faAlt;
|
||||
e = faOrig;
|
||||
};
|
||||
};
|
||||
|
||||
testIsFunctionStr = {
|
||||
expr = isFunction "a";
|
||||
expected = false;
|
||||
|
||||
@@ -1104,9 +1104,22 @@ in
|
||||
*/
|
||||
functionArgs =
|
||||
let
|
||||
functionArgs = builtins.functionArgs;
|
||||
functionArgsLambda = builtins.functionArgs;
|
||||
in
|
||||
f: if f ? __functor then f.__functionArgs or (functionArgs (f.__functor f)) else functionArgs f;
|
||||
f:
|
||||
if f ? __functor then
|
||||
f.__functionArgs or (
|
||||
let
|
||||
fInner = f.__functor f;
|
||||
in
|
||||
# Peel one recursion to avoid calling functionArgs
|
||||
if fInner ? __functor then
|
||||
fInner.__functionArgs or (functionArgs fInner)
|
||||
else
|
||||
functionArgsLambda fInner
|
||||
)
|
||||
else
|
||||
functionArgsLambda f;
|
||||
|
||||
/**
|
||||
Check whether something is a function or something
|
||||
|
||||
Reference in New Issue
Block a user