diff options
Diffstat (limited to 'nixpkgs/lib/modules.nix')
-rw-r--r-- | nixpkgs/lib/modules.nix | 37 |
1 files changed, 21 insertions, 16 deletions
diff --git a/nixpkgs/lib/modules.nix b/nixpkgs/lib/modules.nix index 38d6ac8cd916..e2315290ff0d 100644 --- a/nixpkgs/lib/modules.nix +++ b/nixpkgs/lib/modules.nix @@ -41,7 +41,13 @@ rec { options = { _module.args = mkOption { - type = types.attrsOf types.unspecified; + # Because things like `mkIf` are entirely useless for + # `_module.args` (because there's no way modules can check which + # arguments were passed), we'll use `lazyAttrsOf` which drops + # support for that, in turn it's lazy in its values. This means e.g. + # a `_module.args.pkgs = import (fetchTarball { ... }) {}` won't + # start a download when `pkgs` wasn't evaluated. + type = types.lazyAttrsOf types.unspecified; internal = true; description = "Arguments passed to each module."; }; @@ -151,8 +157,8 @@ rec { filterModules = modulesPath: { disabled, modules }: let moduleKey = m: if isString m then toString modulesPath + "/" + m else toString m; - disabledKeys = listToAttrs (map (k: nameValuePair (moduleKey k) null) disabled); - keyFilter = filter (attrs: ! disabledKeys ? ${attrs.key}); + disabledKeys = map moduleKey disabled; + keyFilter = filter (attrs: ! elem attrs.key disabledKeys); in map (attrs: attrs.module) (builtins.genericClosure { startSet = keyFilter modules; operator = attrs: keyFilter attrs.modules; @@ -365,16 +371,9 @@ rec { else mergeDefinitions loc opt.type defs'; - - # The value with a check that it is defined - valueDefined = if res.isDefined then res.mergedValue else - # (nixos-option detects this specific error message and gives it special - # handling. If changed here, please change it there too.) - throw "The option `${showOption loc}' is used but not defined."; - # Apply the 'apply' function to the merged value. This allows options to # yield a value computed from the definitions - value = if opt ? apply then opt.apply valueDefined else valueDefined; + value = if opt ? apply then opt.apply res.mergedValue else res.mergedValue; in opt // { value = builtins.addErrorContext "while evaluating the option `${showOption loc}':" value; @@ -408,11 +407,17 @@ rec { }; defsFinal = defsFinal'.values; - # Type-check the remaining definitions, and merge them. - mergedValue = foldl' (res: def: - if type.check def.value then res - else throw "The option value `${showOption loc}' in `${def.file}' is not of type `${type.description}'.") - (type.merge loc defsFinal) defsFinal; + # Type-check the remaining definitions, and merge them. Or throw if no definitions. + mergedValue = + if isDefined then + foldl' (res: def: + if type.check def.value then res + else throw "The option value `${showOption loc}' in `${def.file}' is not of type `${type.description}'." + ) (type.merge loc defsFinal) defsFinal + else + # (nixos-option detects this specific error message and gives it special + # handling. If changed here, please change it there too.) + throw "The option `${showOption loc}' is used but not defined."; isDefined = defsFinal != []; |