Consider the following example:
let
nixpkgs = import <nixpkgs> {};
main = nixpkgs.lib;
res = main.extend ext-1;
# Works:
ext-1 = _: super: main.id {result = "123";};
# Recursion error:
# ext-1 = _: super: super.id {result = "123";};
in
res.result
The first ext-1
definition works just fine, but the second one fails with
error: infinite recursion encountered
at /nix/store/9mxzi6ckgb2wwghqq1xcbddf7q8kacbp-nixos-22.05.2320.3c8a5fa9a69/nixos/lib/default.nix:67:14:
66| stringLength sub substring tail trace;
67| inherit (self.trivial) id const pipe concat or and bitAnd bitOr bitXor
| ^
68| bitNot boolToString mergeAttrs flip mapNullable inNixShell isFloat min max
(use '--show-trace' to show detailed location information)
I understand, that you can easily get infinite recursion, if you access self
(aka final
) because of fixed point evaluation, but I am using super
(aka prev
), not self
here, so I don’t understand, where does the infinite recursion come from.
Looking at this image from the Overlays wiki page, I would expect the main
object and the super
argument that is passed to ext-1
to be the same exact object, so I don’t understand, why are these two lines different.
Can somebody explain, what have I missed (and how to avoid this problem)?