From f0f6923fd8fb5f6cfe1a74705d24bacc1e13f045 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Thu, 30 Oct 2025 12:14:48 -0500 Subject: [PATCH] lib/types-dag: implement v2 merge protocol for dagOf type This commit properly implements the v2 merge protocol for dagOf by: - Making `check` a functor with `isV2MergeCoherent = true` that delegates to the underlying attrsOf type's check function - Making `merge` a functor with a `v2` attribute that properly delegates to the underlying type's v2 merge implementation This ensures compatibility with the v2 merge mechanism while maintaining all existing dagOf functionality. Fixes evaluation errors like: error: The option '...' has a type `DAG of X' that uses an ad-hoc `type // { check = ...; }' override, which is incompatible with the v2 merge mechanism. Signed-off-by: Austin Horstman --- modules/lib/types-dag.nix | 43 +++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/modules/lib/types-dag.nix b/modules/lib/types-dag.nix index 9f17dc6ac..feba7739a 100644 --- a/modules/lib/types-dag.nix +++ b/modules/lib/types-dag.nix @@ -37,15 +37,21 @@ let mkOptionType { name = "dagEntryOf"; description = "DAG entry of ${elemType.description}"; - # leave the checking to the submodule type - merge = - loc: defs: - submoduleType.merge loc ( - map (def: { - inherit (def) file; - value = maybeConvert def; - }) defs - ); + merge = { + __functor = + self: loc: defs: + (self.v2 { inherit loc defs; }).value; + v2 = + { loc, defs }: + # Delegate to submodule's v2 merge to propagate any errors + submoduleType.merge.v2 { + inherit loc; + defs = map (def: { + inherit (def) file; + value = maybeConvert def; + }) defs; + }; + }; }; in @@ -65,9 +71,24 @@ rec { mkOptionType rec { name = "dagOf"; description = "DAG of ${elemType.description}"; - inherit (attrEquivalent) check merge emptyValue; + check = { + __functor = _self: attrEquivalent.check; + isV2MergeCoherent = true; + }; + merge = { + __functor = + self: loc: defs: + (self.v2 { inherit loc defs; }).value; + v2 = + { loc, defs }: + # Directly delegate to attrsOf's v2 merge + attrEquivalent.merge.v2 { + inherit loc defs; + }; + }; + inherit (attrEquivalent) emptyValue; + inherit (elemType) getSubModules; getSubOptions = prefix: elemType.getSubOptions (prefix ++ [ "" ]); - getSubModules = elemType.getSubModules; substSubModules = m: dagOf (elemType.substSubModules m); functor = (defaultFunctor name) // { wrapped = elemType;