tvix/eval: incorrect infinite recursion when evaluating pkgs.idris.outPath

#386
Opened by sterni at 2024-03-14T16·12+00

> tvix -E 'with (import <nixpkgs> {}); idris.outPath'
note: while evaluating this Nix code
     --> [code]:1:1
      |
1     | with (import <nixpkgs> {}); idris.outPath
      | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: while evaluating this Nix code
     --> [code]:1:29
      |
1     | with (import <nixpkgs> {}); idris.outPath
      |                             ^^^^^^^^^^^^^
note: while evaluating this as native code (force)
     --> [code]:1:29
      |
1     | with (import <nixpkgs> {}); idris.outPath
      |                             ^^^^^
note: while evaluating this Nix code
     --> /nix/var/nix/profiles/per-user/root/channels/vuizvui/nixpkgs/pkgs/top-level/all-packages.nix:16270:11
      |
16270 |   idris = idrisPackages.with-packages [ idrisPackages.base ] ;
      |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: while evaluating this as native code (force)
     --> /nix/var/nix/profiles/per-user/root/channels/vuizvui/nixpkgs/pkgs/top-level/all-packages.nix:16270:11
      |
16270 |   idris = idrisPackages.with-packages [ idrisPackages.base ] ;
      |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: while evaluating this as native code (force)
     --> /nix/var/nix/profiles/per-user/root/channels/vuizvui/nixpkgs/pkgs/top-level/all-packages.nix:16270:11
      |
16270 |   idris = idrisPackages.with-packages [ idrisPackages.base ] ;
      |           ^^^^^^^^^^^^^
note: while evaluating this Nix code
     --> /nix/var/nix/profiles/per-user/root/channels/vuizvui/nixpkgs/lib/attrsets.nix:1184:5
      |
1184  |     attrs // { recurseForDerivations = false; };
      |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: while evaluating this as native code (force)
     --> /nix/var/nix/profiles/per-user/root/channels/vuizvui/nixpkgs/lib/attrsets.nix:1184:5
      |
1184  |     attrs // { recurseForDerivations = false; };
      |     ^^^^^
note: while evaluating this Nix code
     --> /nix/var/nix/profiles/per-user/root/channels/vuizvui/nixpkgs/lib/customisation.nix:108:7
      |
108   | /       if isAttrs result then
109   | |         result // {
110   | |           override = overrideArgs;
111   | |           overrideDerivation = fdrv: overrideResult (x: overrideDerivation x fdrv);
...     |
119   | |         }
120   | |       else result);
      | |_________________^
note: while evaluating this as native code (force)
     --> /nix/var/nix/profiles/per-user/root/channels/vuizvui/nixpkgs/lib/customisation.nix:108:10
      |
108   |       if isAttrs result then
      |          ^^^^^^^^^^^^^^
note: while evaluating this Nix code
     --> /nix/var/nix/profiles/per-user/root/channels/vuizvui/nixpkgs/lib/fixed-points.nix:84:21
      |
84    |   fix' = f: let x = f x // { __unfix__ = f; }; in x;
      |                     ^^^^^^^^^^^^^^^^^^^^^^^^^
note: while evaluating this as native code (force)
     --> /nix/var/nix/profiles/per-user/root/channels/vuizvui/nixpkgs/lib/fixed-points.nix:84:21
      |
84    |   fix' = f: let x = f x // { __unfix__ = f; }; in x;
      |                     ^^^
note: while evaluating this Nix code
     --> /nix/var/nix/profiles/per-user/root/channels/vuizvui/nixpkgs/lib/fixed-points.nix:252:7
      |
252   |       prev // overlay final prev
      |       ^^^^^^^^^^^^^^^^^^^^^^^^^^
note: while evaluating this as native code (force)
     --> /nix/var/nix/profiles/per-user/root/channels/vuizvui/nixpkgs/lib/fixed-points.nix:252:7
      |
252   |       prev // overlay final prev
      |       ^^^^
note: while evaluating this Nix code
     --> /nix/var/nix/profiles/per-user/root/channels/vuizvui/nixpkgs/pkgs/development/idris-modules/default.nix:29:5
      |
29    | /     {
30    | |     inherit idris-no-deps callPackage;
31    | |
32    | |     # Idris wrapper with specified compiler and library paths, used to build packages
...     |
210   | |     protobuf = throw "idrisPackages.protobuf has been removed: abandoned by upstream"; # Added 2022-02-06
211   | |   };
      | |___^
note: while evaluating this as native code (force)
     --> /nix/var/nix/profiles/per-user/root/channels/vuizvui/nixpkgs/pkgs/development/idris-modules/default.nix:208:8
      |
208   |     } // builtins_ // pkgs.lib.optionalAttrs config.allowAliases {
      |  ________^
209   | |     # removed packages
210   | |     protobuf = throw "idrisPackages.protobuf has been removed: abandoned by upstream"; # Added 2022-02-06
211   | |   };
      | |___^
note: while evaluating this as native code (force)
     --> /nix/var/nix/profiles/per-user/root/channels/vuizvui/nixpkgs/pkgs/development/idris-modules/default.nix:208:8
      |
208   |   } // builtins_ // pkgs.lib.optionalAttrs config.allowAliases {
      |        ^^^^^^^^^
note: while evaluating this as native code (mapAttrs)
     --> /nix/var/nix/profiles/per-user/root/channels/vuizvui/nixpkgs/pkgs/development/idris-modules/default.nix:16:17
      |
16    |       builtins_ = pkgs.lib.mapAttrs self.build-builtin-package {
      |  _________________^
17    | |       prelude = [];
18    | |
19    | |       base = [ self.prelude ];
...     |
25    | |       pruviloj = [ self.prelude self.base ];
26    | |     };
      | |_____^
note: while evaluating this Nix code
     --> /nix/var/nix/profiles/per-user/root/channels/vuizvui/nixpkgs/pkgs/development/idris-modules/default.nix:16:35
      |
16    |     builtins_ = pkgs.lib.mapAttrs self.build-builtin-package {
      |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E014]: infinite recursion encountered
     --> /nix/var/nix/profiles/per-user/root/channels/vuizvui/nixpkgs/pkgs/development/idris-modules/default.nix:16:35
      |
16    |     builtins_ = pkgs.lib.mapAttrs self.build-builtin-package {
      |                                   ^^^^ but then requested again here during its own evaluation
      | 
     ::: /nix/var/nix/profiles/per-user/root/channels/vuizvui/nixpkgs/lib/customisation.nix
      |
108   |       if isAttrs result then
      |          -------------- was first requested to be evaluated here
      | 
     ::: /nix/var/nix/profiles/per-user/root/channels/vuizvui/nixpkgs/lib/fixed-points.nix
      |
84    |   fix' = f: let x = f x // { __unfix__ = f; }; in x;
      |                     -------------------------
      |                     |
      |                     this lazily-evaluated code
      |                     which was instantiated here

r/7687, nixpkgs 3030f185ba6a.

  1. This seems to be a very serious overeager evaluation bug. Reduced reproducer:

    let
      fix = f:
        let
          x = f x;
        in x;
    in
    
    fix (self:
      let
        set = builtins.mapAttrs self.f { a = 1; b = 2; };
      in
      {
        f = _: x: x;
      } // set)
    

    sterni at 2024-03-15T12·49+00

  2. We can inline the fix:

    let self = let set = builtins.mapAttrs self.f { a = 1; b = 2; }; in { f = _: x: x; } // set; in self
    

    sterni at 2024-03-15T12·57+00

  3. The issue is that the function application in builtins.mapAttrs is to strict, presumably in the sense that it forces the function. By comparison, a Nix implementation of mapAttrs works fine:

    let
      mapAttrs = f: set: builtins.listToAttrs (builtins.map (name: {
        inherit name; value = f name set.${name};
      }) (builtins.attrNames set));
      self = let set = mapAttrs self.f { a = 1; b = 2; }; in { f = _: x: x; } // set;
    in self
    

    sterni at 2024-03-15T13·00+00

  4. It seems related to b/272, but it seems that this is not a regression from cl/8651. I checked out that and the problem still exists.

    sterni at 2024-03-15T13·25+00

  5. cl/11153

    sterni at 2024-03-15T20·46+00

  6. sterni closed this issue at 2024-03-19T14·41+00