summary refs log tree commit diff
path: root/lib
diff options
context:
space:
mode:
authortoonn <toonn@toonn.io>2022-09-25 14:45:17 +0200
committertoonn <toonn@toonn.io>2022-09-25 14:45:17 +0200
commitbf9ff0c6873e8c828617e72b66eeeec3026b9201 (patch)
tree3dda6afbae4304579b8d5dfd1ed57eb86e47ce12 /lib
parent8209024c5a4ecb6474a49c215d1dfae1869c84ec (diff)
parent037cf2fad190766319c6c40b931b49c075ce5e78 (diff)
Merge branch 'amjoseph-nixpkgs-pr/resume182058' into staging
Diffstat (limited to 'lib')
-rw-r--r--lib/attrsets.nix14
1 files changed, 14 insertions, 0 deletions
diff --git a/lib/attrsets.nix b/lib/attrsets.nix
index 5575e9577029a..de88763854d69 100644
--- a/lib/attrsets.nix
+++ b/lib/attrsets.nix
@@ -622,6 +622,20 @@ rec {
   dontRecurseIntoAttrs =
     attrs: attrs // { recurseForDerivations = false; };
 
+  /* `unionOfDisjoint x y` is equal to `x // y // z` where the
+     attrnames in `z` are the intersection of the attrnames in `x` and
+     `y`, and all values `assert` with an error message.  This
+      operator is commutative, unlike (//). */
+  unionOfDisjoint = x: y:
+    let
+      intersection = builtins.intersectAttrs x y;
+      collisions = lib.concatStringsSep " " (builtins.attrNames intersection);
+      mask = builtins.mapAttrs (name: value: builtins.throw
+        "unionOfDisjoint: collision on ${name}; complete list: ${collisions}")
+        intersection;
+    in
+      (x // y) // mask;
+
   /*** deprecated stuff ***/
 
   zipWithNames = zipAttrsWithNames;