Excessive strictness involving //
and fixpoints causing infrec
#363
Opened by raitobezarius at
MWE:
{ pkgs ? import <nixpkgs> {}, lib ? pkgs.lib }: let packages = self: let builtins_ = lib.mapAttrs self.build { }; in { build = pname: deps: derivation { name = "mwe-${pname}"; inherit deps; builder = "/bin/sh"; system = "x86_64-linux"; }; builtins_ = builtins_; } // builtins_; in pkgs.lib.fix' packages
This will work in Nix, but not in Tvix, causes an infrec.
Root cause:
// builtins_
seemingly? Is it related to partial attrset construction observation?raitobezarius at 2023-12-30T02·02+00
Nope, this is a bug in
builtins.mapAttrs
, namely it forcingf
too early. This can be seen when replacinglib.mapAttrs
(== builtins.mapAttrs
) with a hand rolled version:{ pkgs ? import <nixpkgs> {}, lib ? pkgs.lib }: let mapAttrs = f: attrs: let names = builtins.attrNames attrs; name = builtins.head names; in if builtins.length names == 0 then { } else { ${name} = f name attrs.${name}; } // mapAttrs f (builtins.removeAttrs attrs [ name ]); packages = self: let builtins_ = mapAttrs self.build { }; in { build = pname: deps: derivation { name = "mwe-${pname}"; inherit deps; builder = "/bin/sh"; system = "x86_64-linux"; }; builtins_ = builtins_; } // builtins_; in lib.fix' packages
sterni at 2023-12-30T10·22+00
Ah I see, that makes sense, thank you for finding about it!
raitobezarius at 2023-12-31T01·34+00