lib.modules: avoid filtering option decls in most cases

This commit is contained in:
Eman Resu
2026-06-03 13:49:00 -04:00
committed by Eman Resu
parent d03c2169d2
commit 830dd996ea

View File

@@ -881,13 +881,12 @@ let
loc = prefix ++ [ name ];
defns = pushedDownDefinitionsByName.${name} or [ ];
defns' = rawDefinitionsByName.${name} or [ ];
optionDecls = filter (
isOptionDecl =
m:
m.options ? _type
&& (m.options._type == "option" || throwDeclarationTypeError loc m.options._type m._file)
) decls;
&& (m.options._type == "option" || throwDeclarationTypeError loc m.options._type m._file);
in
if length optionDecls == length decls then
if all isOptionDecl decls then
let
opt = fixupOptionType loc (mergeOptionDecls loc decls);
in
@@ -895,7 +894,35 @@ let
matchedOptions = evalOptionValue loc opt defns';
unmatchedDefns = [ ];
}
else if optionDecls != [ ] then
# this may look like duplicate computations are performed, but testing
# with a minimal NixOS config (defined below):
#
# 1. in 87% of cases, the above `all isOptionDecl decls` passes and we
# short-circuit
# 2. In 12% of cases, there's only one decl and we short-circuit
# 3. in another 1% of cases, we loop again and short-circuit when
# `any isOptionDecl decls` fails
# 4. In the final case, we pass the `any` and have to refilter. This
# only triggers in 1 of the 48000 calls to this function.
#
# The minimal config was defined with this expression:
#
# let nixos = import ./nixos/lib/eval-config.nix {
# modules = [
# ./nixos/modules/profiles/minimal.nix
# {
# fileSystems."/" = {
# device = "/dev/sda1";
# fsType = "ext4";
# };
# boot.loader.grub.devices = [ "/dev/sda" ];
# }
# ];
# }; in nixos.config.system.build.toplevel
else if length decls != 1 && any isOptionDecl decls then
let
optionDecls = filter isOptionDecl decls;
in
if
all (x: x.options.type.name or null == "submodule") optionDecls
# Raw options can only be merged into submodules. Merging into