statix
statix copied to clipboard
Warn when inheriting attributes from a function call
It is possible to inherit attributes from another set^1. For example:
let
x = { a = 1; b = 2; }
y = { inherit (x) a b; }
in
y # evaluates to `{ a = 1; b = 2; }`
But since Nix does not have maximal laziness, inheriting from the result of a function call will evaluate the function for each inherited attribute. That is, evaluating the expression below:
let
f = x:
builtins.trace "evaluated" {
a = x + 1;
b = x + 2;
};
inherit (f 0) a b;
in
[ a b ]
will evaluate f 0 2 times (which can be checked with trace). This can be avoided with:
let
f = x:
builtins.trace "evaluated" {
a = x + 1;
b = x + 2;
};
set = f 0;
inherit (set) a b;
in
[ a b ]
In this case f 0 will be evaluated only once because the result is saved in a variable.
An exception to this is import. While the manual notes that import is a regular function, result of import <path> seems to be cached internally, so:
let
inherit (import <path>) f g; # this is OK
inherit (import <path> <some-args>) f g # this is not OK
in
aha, this is a very nice lint idea, thanks!