diff --git a/lib/types.nix b/lib/types.nix index 43ace4a3f6a5..b988ff1a89a9 100644 --- a/lib/types.nix +++ b/lib/types.nix @@ -71,6 +71,26 @@ let let pos = builtins.unsafeGetAttrPos name v; in if pos == null then "" else " at ${pos.file}:${toString pos.line}:${toString pos.column}"; + # Internal functor to help for migrating functor.wrapped to functor.payload.elemType + # Note that individual attributes can be overriden if needed. + elemTypeFunctor = name: { elemType, ... }@payload: { + inherit name payload; + type = outer_types.types.${name}; + binOp = a: b: + let + merged = a.elemType.typeMerge b.elemType.functor; + in + if merged == null + then + null + else + { elemType = merged; }; + wrappedDeprecationMessage = { loc }: lib.warn '' + The deprecated `type.functor.wrapped` attribute of the option `${showOption loc}` is accessed, use `type.nestedTypes.elemType` instead. + '' payload.elemType; + }; + + outer_types = rec { isType = type: x: (x._type or "") == type; @@ -664,14 +684,10 @@ rec { getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<${placeholder}>"]); getSubModules = elemType.getSubModules; substSubModules = m: attrsWith { elemType = elemType.substSubModules m; inherit lazy placeholder; }; - functor = defaultFunctor "attrsWith" // { - wrappedDeprecationMessage = { loc }: lib.warn '' - The deprecated `type.functor.wrapped` attribute of the option `${showOption loc}` is accessed, use `type.nestedTypes.elemType` instead. - '' elemType; - payload = { - # Important!: Add new function attributes here in case of future changes + functor = (elemTypeFunctor "attrsWith" { inherit elemType lazy placeholder; - }; + }) // { + # Custom type merging required because of the "placeholder" attribute inherit binOp; }; nestedTypes.elemType = elemType;