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
This commit is contained in:
Silvan Mosberger 2020-09-30 01:12:30 +02:00
parent ce5e3113c3
commit 4b54aedee5

View File

@ -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;