From 45ecf43c516fb899d639be0b73c85b013be0ba9c Mon Sep 17 00:00:00 2001 From: Ben Siraphob Date: Fri, 3 Jul 2026 14:09:30 -0700 Subject: [PATCH] lib.meta-types: add binary either/both combinators Every in-tree union/intersection use has exactly two members, and the binary form verifies without allocating a closure or calling the any/all primop per check. check-meta.nix switches to either/both; union and intersection are kept for potential future use. Assisted-by: Claude Code (Claude Fable 5) --- lib/meta-types.nix | 26 ++++++++++++++++++++++++ pkgs/stdenv/generic/check-meta.nix | 32 +++++++----------------------- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/lib/meta-types.nix b/lib/meta-types.nix index 1d67f5f063e8..264c921eb54e 100644 --- a/lib/meta-types.nix +++ b/lib/meta-types.nix @@ -160,6 +160,32 @@ lib.fix (self: { verify = v: all (func: func v) funcs; }; + either = + t1: t2: + assert isTypeDef t1 && isTypeDef t2; + let + # Store the functions directly so we don't have to pay the cost of attrset lookups at runtime. + v1 = t1.verify; + v2 = t2.verify; + in + { + name = "either<${t1.name},${t2.name}>"; + verify = v: v1 v || v2 v; + }; + + both = + t1: t2: + assert isTypeDef t1 && isTypeDef t2; + let + # Store the functions directly so we don't have to pay the cost of attrset lookups at runtime. + v1 = t1.verify; + v2 = t2.verify; + in + { + name = "both<${t1.name},${t2.name}>"; + verify = v: v1 v && v2 v; + }; + not = t: assert isTypeDef t; diff --git a/pkgs/stdenv/generic/check-meta.nix b/pkgs/stdenv/generic/check-meta.nix index 049be19b4e6a..f834ebcb37c6 100644 --- a/pkgs/stdenv/generic/check-meta.nix +++ b/pkgs/stdenv/generic/check-meta.nix @@ -304,21 +304,18 @@ let types = import ../../../lib/meta-types.nix { inherit lib; }; inherit (types) str - union + either int attrs any listOf bool record - intersection + both not derivation ; - platforms = listOf (union [ - str - attrs - ]); # see lib.meta.platformMatch + platforms = listOf (either str attrs); # see lib.meta.platformMatch in record { # These keys are documented @@ -326,31 +323,16 @@ let mainProgram = str; longDescription = str; branch = str; - homepage = union [ - (listOf str) - str - ]; + homepage = either str (listOf str); donationPage = str; downloadPage = str; - changelog = union [ - (listOf str) - str - ]; + changelog = either str (listOf str); license = let # TODO disallow `str` licenses, use a module - licenseType = union [ - (intersection [ - attrs - (not derivation) - ]) - str - ]; + licenseType = either (both attrs (not derivation)) str; in - union [ - (listOf licenseType) - licenseType - ]; + either licenseType (listOf licenseType); sourceProvenance = listOf attrs; maintainers = listOf attrs; # TODO use the maintainer type from lib/tests/maintainer-module.nix nonTeamMaintainers = listOf attrs; # TODO use the maintainer type from lib/tests/maintainer-module.nix