summary refs log tree commit diff
path: root/lib/modules.nix
diff options
context:
space:
mode:
Diffstat (limited to 'lib/modules.nix')
-rw-r--r--lib/modules.nix17
1 files changed, 13 insertions, 4 deletions
diff --git a/lib/modules.nix b/lib/modules.nix
index d515ee24d16..04b65d791b5 100644
--- a/lib/modules.nix
+++ b/lib/modules.nix
@@ -515,11 +515,20 @@ rec {
       # yield a value computed from the definitions
       value = if opt ? apply then opt.apply res.mergedValue else res.mergedValue;
 
-      warnDeprecation =
-        warnIf (opt.type.deprecationMessage != null)
-          "The type `types.${opt.type.name}' of option `${showOption loc}' defined in ${showFiles opt.declarations} is deprecated. ${opt.type.deprecationMessage}";
+      # Issue deprecation warnings recursively over all nested types of the
+      # given type. But don't recurse if a type with the same name was already
+      # visited before in order to prevent infinite recursion. So this only
+      # warns once per type name.
+      # Returns the new set of visited type names
+      recursiveWarn = visited: type:
+        let
+          maybeWarn = warnIf (type.deprecationMessage != null)
+            "The type `types.${type.name}' of option `${showOption loc}' defined in ${showFiles opt.declarations} is deprecated. ${type.deprecationMessage}";
+        in
+          if visited ? ${type.name} then visited
+          else lib.foldl' recursiveWarn (maybeWarn visited // { ${type.name} = null; }) (lib.attrValues type.nestedTypes);
 
-    in warnDeprecation opt //
+    in builtins.seq (recursiveWarn {} opt.type) opt //
       { value = builtins.addErrorContext "while evaluating the option `${showOption loc}':" value;
         inherit (res.defsFinal') highestPrio;
         definitions = map (def: def.value) res.defsFinal;