diff --git a/lib/systems/inspect.nix b/lib/systems/inspect.nix index d60a8fc70f87..146e9a9f4389 100644 --- a/lib/systems/inspect.nix +++ b/lib/systems/inspect.nix @@ -518,14 +518,40 @@ rec { ) pat2 ) pat1; - matchAnyAttrs = - patterns: - if isList patterns then - attrs: any (pattern: matchAttrsUnchecked pattern attrs) patterns - else - matchAttrsUnchecked patterns; + matchAnyPattern = + let + # same as matchAttrsUnchecked definition at the top of the file, but: + # - pattern names are cached and reused for multiple attrset calls + # - avoid running isAttrs since all patterns are nested attrsets + matchPattern = + pattern: + let + names = attrNames pattern; + in + attrs: + all ( + attr: + attrs ? ${attr} + && ( + let + lhs = pattern.${attr}; + rhs = attrs.${attr}; + in + lhs == rhs || matchAttrsUnchecked lhs rhs + ) + ) names; - predicates = mapAttrs (_: matchAnyAttrs) patterns; + in + pattern: + if isList pattern then + let + cachedPatterns = map matchPattern pattern; + in + attrs: any (pattern: pattern attrs) cachedPatterns + else + matchPattern pattern; + + predicates = mapAttrs (_: matchAnyPattern) patterns; # these patterns are to be matched against the entire # {host,build,target}Platform structure; they include a `parsed={}` marker so