From 3d92f38fbd9d0aed8eee617f1b8730c5727a2b50 Mon Sep 17 00:00:00 2001 From: Johannes Kirschbauer Date: Mon, 6 Jan 2025 15:24:48 +0100 Subject: [PATCH 1/3] lib/types: refactor elemTypeFunctor for types.attrsWith --- lib/types.nix | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) 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; From 8523f61f935486217e2ba4ec5bdd9c11abaf21ee Mon Sep 17 00:00:00 2001 From: Johannes Kirschbauer Date: Mon, 6 Jan 2025 15:50:55 +0100 Subject: [PATCH 2/3] release-notes: add deprecation note: funtor.wrapped for lib.types.attrsWith --- doc/redirects.json | 3 +++ doc/release-notes/rl-2505.section.md | 6 ++++++ nixos/doc/manual/redirects.json | 3 +++ 3 files changed, 12 insertions(+) diff --git a/doc/redirects.json b/doc/redirects.json index 330c25effc14..d5360283e461 100644 --- a/doc/redirects.json +++ b/doc/redirects.json @@ -71,6 +71,9 @@ "sec-nixpkgs-release-25.05-lib-breaking": [ "release-notes.html#sec-nixpkgs-release-25.05-lib-breaking" ], + "sec-nixpkgs-release-25.05-lib-deprecations": [ + "release-notes.html#sec-nixpkgs-release-25.05-lib-deprecations" + ], "sec-overlays-install": [ "index.html#sec-overlays-install" ], diff --git a/doc/release-notes/rl-2505.section.md b/doc/release-notes/rl-2505.section.md index 9fa72cc1f484..c06b1af63aa4 100644 --- a/doc/release-notes/rl-2505.section.md +++ b/doc/release-notes/rl-2505.section.md @@ -17,3 +17,9 @@ - Structure of the `functor` of some types has changed. `functor` is an implementation detail and should not be relied upon. If you did rely on it let us know in this [PR](https://github.com/NixOS/nixpkgs/pull/363565). - [`lib.types.enum`](https://nixos.org/manual/nixos/unstable/#sec-option-types-basic): Previously the `functor.payload` was the list of enum values directly. Now it is an attribute set containing the values in the `values` attribute. - [`lib.types.separatedString`](https://nixos.org/manual/nixos/unstable/#sec-option-types-string): Previously the `functor.payload` was the seperator directly. Now it is an attribute set containing the seperator in the `sep` attribute. + +### Deprecations {#sec-nixpkgs-release-25.05-lib-deprecations} + +`functor` is an implementation detail and should not be relied upon, but since its status wasn't clear and it has had some use cases without alternatives, changes are being handled as gracefully as possible. Deprecations within functor: +- `functor.wrapped` is now deprecated for some types and using it will give a warning with migration instructions. It is deprecated for these types: + - `lib.types.attrsWith` diff --git a/nixos/doc/manual/redirects.json b/nixos/doc/manual/redirects.json index 106148d1dd04..b404fa35052f 100644 --- a/nixos/doc/manual/redirects.json +++ b/nixos/doc/manual/redirects.json @@ -1904,6 +1904,9 @@ "sec-nixpkgs-release-25.05-lib-breaking": [ "release-notes.html#sec-nixpkgs-release-25.05-lib-breaking" ], + "sec-nixpkgs-release-25.05-lib-deprecations": [ + "release-notes.html#sec-nixpkgs-release-25.05-lib-deprecations" + ], "sec-release-24.11": [ "release-notes.html#sec-release-24.11" ], From 5782ef8dc37f8451339dea316a1ef40d5d68540b Mon Sep 17 00:00:00 2001 From: Johannes Kirschbauer Date: Mon, 6 Jan 2025 15:25:08 +0100 Subject: [PATCH 3/3] lib/types: deprecate functor.wrapped in types.listOf --- doc/release-notes/rl-2505.section.md | 1 + lib/types.nix | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/release-notes/rl-2505.section.md b/doc/release-notes/rl-2505.section.md index c06b1af63aa4..901124b91c7c 100644 --- a/doc/release-notes/rl-2505.section.md +++ b/doc/release-notes/rl-2505.section.md @@ -23,3 +23,4 @@ `functor` is an implementation detail and should not be relied upon, but since its status wasn't clear and it has had some use cases without alternatives, changes are being handled as gracefully as possible. Deprecations within functor: - `functor.wrapped` is now deprecated for some types and using it will give a warning with migration instructions. It is deprecated for these types: - `lib.types.attrsWith` + - `lib.types.listOf` diff --git a/lib/types.nix b/lib/types.nix index b988ff1a89a9..e74775d0a27a 100644 --- a/lib/types.nix +++ b/lib/types.nix @@ -600,7 +600,9 @@ rec { getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["*"]); getSubModules = elemType.getSubModules; substSubModules = m: listOf (elemType.substSubModules m); - functor = (defaultFunctor name) // { wrapped = elemType; }; + functor = (elemTypeFunctor name { inherit elemType; }) // { + type = payload: types.listOf payload.elemType; + }; nestedTypes.elemType = elemType; };