unionOfDisjoint: use builtins.intersectAttrs
This brings two benefits: 1. The complete list of collisions is printed in the whenever any colliding attribute is accessed. 2. The sets are intersected using a C++ primitive, which runs in O(n) time (intersecting pre-sorted lists) with small constants rather than interpreted Nix code. Thanks to @toonn for prompting this improvement.
This commit is contained in:
parent
99da193877
commit
037cf2fad1
@ -627,11 +627,14 @@ rec {
|
||||
`y`, and all values `assert` with an error message. This
|
||||
operator is commutative, unlike (//). */
|
||||
unionOfDisjoint = x: y:
|
||||
x // (mapAttrs
|
||||
(name: val:
|
||||
if hasAttr name x
|
||||
then builtins.throw "attribute collision: ${name}"
|
||||
else val) 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 ***/
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user