From 4b54aedee5e05aaf2838f6d951508b83e33d2baa Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Wed, 30 Sep 2020 01:12:30 +0200 Subject: lib/modules: Issue type deprecation warnings recursively Previously, an option of type attrsOf string wouldn't throw a deprecation warning, even though the string type is deprecated. This was because the deprecation warning trigger only looked at the type of the option itself, not any of its subtypes. This commit fixes this, causing each of the types deprecationMessages to trigger for the option. This relies on the subtypes mkOptionType attribute introduced in 26607a5a2e06653fec453c83d063cdfc4b59185f --- lib/modules.nix | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'lib/modules.nix') 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; -- cgit 1.4.1