summary refs log tree commit diff
path: root/pkgs/stdenv
diff options
context:
space:
mode:
authorTuomas Tynkkynen <tuomas@tuxera.com>2017-04-24 15:04:43 +0300
committerTuomas Tynkkynen <tuomas@tuxera.com>2017-04-24 15:04:43 +0300
commit84982c28de5c00d5f67aa0f742a7e1e2dcd37db6 (patch)
treef0f154f18ae0d3c351b7f100bc5edade7b3b03a6 /pkgs/stdenv
parent4fc9b1852a7707d5531355b588c3d2edc769b0cb (diff)
parentcc4649ddb4db91d35c773aca0670f23000b8ccfc (diff)
downloadnixlib-84982c28de5c00d5f67aa0f742a7e1e2dcd37db6.tar
nixlib-84982c28de5c00d5f67aa0f742a7e1e2dcd37db6.tar.gz
nixlib-84982c28de5c00d5f67aa0f742a7e1e2dcd37db6.tar.bz2
nixlib-84982c28de5c00d5f67aa0f742a7e1e2dcd37db6.tar.lz
nixlib-84982c28de5c00d5f67aa0f742a7e1e2dcd37db6.tar.xz
nixlib-84982c28de5c00d5f67aa0f742a7e1e2dcd37db6.tar.zst
nixlib-84982c28de5c00d5f67aa0f742a7e1e2dcd37db6.zip
Merge remote-tracking branch 'upstream/master' into staging
Diffstat (limited to 'pkgs/stdenv')
-rw-r--r--pkgs/stdenv/booter.nix41
1 files changed, 36 insertions, 5 deletions
diff --git a/pkgs/stdenv/booter.nix b/pkgs/stdenv/booter.nix
index 2c82d12da95d..d459deb6ab54 100644
--- a/pkgs/stdenv/booter.nix
+++ b/pkgs/stdenv/booter.nix
@@ -41,6 +41,35 @@
 # other words, this does a foldr not foldl.
 stageFuns: let
 
+  /* "dfold" a ternary function `op' between successive elements of `list' as if
+     it was a doubly-linked list with `lnul' and `rnul` base cases at either
+     end. In precise terms, `fold op lnul rnul [x_0 x_1 x_2 ... x_n-1]` is the
+     same as
+
+       let
+         f_-1  = lnul;
+         f_0   = op f_-1   x_0  f_1;
+         f_1   = op f_0    x_1  f_2;
+         f_2   = op f_1    x_2  f_3;
+         ...
+         f_n   = op f_n-1  x_n  f_n+1;
+         f_n+1 = rnul;
+       in
+         f_0
+  */
+  dfold = op: lnul: rnul: list:
+    let
+      len = builtins.length list;
+      go = pred: n:
+        if n == len
+        then rnul
+        else let
+          # Note the cycle -- call-by-need ensures finite fold.
+          cur  = op pred (builtins.elemAt list n) succ;
+          succ = go cur (n + 1);
+        in cur;
+    in go lnul 0;
+
   # Take the list and disallow custom overrides in all but the final stage,
   # and allow it in the final flag. Only defaults this boolean field if it
   # isn't already set.
@@ -55,19 +84,21 @@ stageFuns: let
 
   # Adds the stdenv to the arguments, and sticks in it the previous stage for
   # debugging purposes.
-  folder = stageFun: finalSoFar: let
-    args = stageFun finalSoFar;
+  folder = nextStage: stageFun: prevStage: let
+    args = stageFun prevStage;
     args' = args // {
       stdenv = args.stdenv // {
         # For debugging
-        __bootPackages = finalSoFar;
+        __bootPackages = prevStage;
+        __hatPackages = nextStage;
       };
     };
   in
     if args.__raw or false
     then args'
     else allPackages ((builtins.removeAttrs args' ["selfBuild"]) // {
-      buildPackages = if args.selfBuild or true then null else finalSoFar;
+      buildPackages = if args.selfBuild or true then null else prevStage;
+      __targetPackages = if args.selfBuild or true then null else nextStage;
     });
 
-in lib.lists.fold folder {} withAllowCustomOverrides
+in dfold folder {} {} withAllowCustomOverrides