Merge pull request #266886 from Artturin/testimpactofinherit

stdenv: Test the perf impact of inheriting from lib

authored by Artturi and committed by GitHub d9b120b3 fc5560f9

+119 -82
+119 -82
pkgs/stdenv/generic/make-derivation.nix
··· 3 3 stdenv: 4 4 5 5 let 6 + # Lib attributes are inherited to the lexical scope for performance reasons. 7 + inherit (lib) 8 + any 9 + assertMsg 10 + attrNames 11 + boolToString 12 + chooseDevOutputs 13 + concatLists 14 + concatMap 15 + concatMapStrings 16 + concatStringsSep 17 + elem 18 + elemAt 19 + extendDerivation 20 + filter 21 + findFirst 22 + flip 23 + head 24 + imap1 25 + isAttrs 26 + isBool 27 + isDerivation 28 + isInt 29 + isList 30 + isString 31 + mapAttrs 32 + mapNullable 33 + optional 34 + optionalAttrs 35 + optionalString 36 + optionals 37 + remove 38 + splitString 39 + subtractLists 40 + unique 41 + ; 42 + 6 43 checkMeta = import ./check-meta.nix { 7 44 inherit lib config; 8 45 # Nix itself uses the `system` field of a derivation to decide where ··· 115 152 # Including it then would cause needless mass rebuilds. 116 153 # 117 154 # TODO(@Ericson2314): Make [ "build" "host" ] always the default / resolve #87909 118 - configurePlatforms ? lib.optionals 155 + configurePlatforms ? optionals 119 156 (stdenv.hostPlatform != stdenv.buildPlatform || config.configurePlatformsByDefault) 120 157 [ "build" "host" ] 121 158 ··· 168 205 # Policy on acceptable hash types in nixpkgs 169 206 assert attrs ? outputHash -> ( 170 207 let algo = 171 - attrs.outputHashAlgo or (lib.head (lib.splitString "-" attrs.outputHash)); 208 + attrs.outputHashAlgo or (head (splitString "-" attrs.outputHash)); 172 209 in 173 210 if algo == "md5" then 174 211 throw "Rejected insecure ${algo} hash '${attrs.outputHash}'" ··· 183 220 doInstallCheck' = doInstallCheck && stdenv.buildPlatform.canExecute stdenv.hostPlatform; 184 221 185 222 separateDebugInfo' = separateDebugInfo && stdenv.hostPlatform.isLinux; 186 - outputs' = outputs ++ lib.optional separateDebugInfo' "debug"; 223 + outputs' = outputs ++ optional separateDebugInfo' "debug"; 187 224 188 225 # Turn a derivation into its outPath without a string context attached. 189 226 # See the comment at the usage site. 190 227 unsafeDerivationToUntrackedOutpath = drv: 191 - if lib.isDerivation drv 228 + if isDerivation drv 192 229 then builtins.unsafeDiscardStringContext drv.outPath 193 230 else drv; 194 231 ··· 198 235 ++ depsTargetTarget ++ depsTargetTargetPropagated) == 0; 199 236 dontAddHostSuffix = attrs ? outputHash && !noNonNativeDeps || !stdenv.hasCC; 200 237 201 - hardeningDisable' = if lib.any (x: x == "fortify") hardeningDisable 238 + hardeningDisable' = if any (x: x == "fortify") hardeningDisable 202 239 # disabling fortify implies fortify3 should also be disabled 203 - then lib.unique (hardeningDisable ++ [ "fortify3" ]) 240 + then unique (hardeningDisable ++ [ "fortify3" ]) 204 241 else hardeningDisable; 205 242 supportedHardeningFlags = [ "fortify" "fortify3" "stackprotector" "pie" "pic" "strictoverflow" "format" "relro" "bindnow" ]; 206 243 # Musl-based platforms will keep "pie", other platforms will not. ··· 212 249 # - static armv7l, where compilation fails. 213 250 !(stdenv.hostPlatform.isAarch && stdenv.hostPlatform.isStatic) 214 251 then supportedHardeningFlags 215 - else lib.remove "pie" supportedHardeningFlags; 252 + else remove "pie" supportedHardeningFlags; 216 253 enabledHardeningOptions = 217 254 if builtins.elem "all" hardeningDisable' 218 255 then [] 219 - else lib.subtractLists hardeningDisable' (defaultHardeningFlags ++ hardeningEnable); 256 + else subtractLists hardeningDisable' (defaultHardeningFlags ++ hardeningEnable); 220 257 # hardeningDisable additionally supports "all". 221 - erroneousHardeningFlags = lib.subtractLists supportedHardeningFlags (hardeningEnable ++ lib.remove "all" hardeningDisable); 258 + erroneousHardeningFlags = subtractLists supportedHardeningFlags (hardeningEnable ++ remove "all" hardeningDisable); 222 259 223 260 checkDependencyList = checkDependencyList' []; 224 - checkDependencyList' = positions: name: deps: lib.flip lib.imap1 deps (index: dep: 225 - if lib.isDerivation dep || dep == null || builtins.isString dep || builtins.isPath dep then dep 226 - else if lib.isList dep then checkDependencyList' ([index] ++ positions) name dep 227 - else throw "Dependency is not of a valid type: ${lib.concatMapStrings (ix: "element ${toString ix} of ") ([index] ++ positions)}${name} for ${attrs.name or attrs.pname}"); 261 + checkDependencyList' = positions: name: deps: flip imap1 deps (index: dep: 262 + if isDerivation dep || dep == null || builtins.isString dep || builtins.isPath dep then dep 263 + else if isList dep then checkDependencyList' ([index] ++ positions) name dep 264 + else throw "Dependency is not of a valid type: ${concatMapStrings (ix: "element ${toString ix} of ") ([index] ++ positions)}${name} for ${attrs.name or attrs.pname}"); 228 265 in if builtins.length erroneousHardeningFlags != 0 229 266 then abort ("mkDerivation was called with unsupported hardening flags: " + lib.generators.toPretty {} { 230 267 inherit erroneousHardeningFlags hardeningDisable hardeningEnable supportedHardeningFlags; ··· 233 270 doCheck = doCheck'; 234 271 doInstallCheck = doInstallCheck'; 235 272 buildInputs' = buildInputs 236 - ++ lib.optionals doCheck checkInputs 237 - ++ lib.optionals doInstallCheck installCheckInputs; 273 + ++ optionals doCheck checkInputs 274 + ++ optionals doInstallCheck installCheckInputs; 238 275 nativeBuildInputs' = nativeBuildInputs 239 - ++ lib.optional separateDebugInfo' ../../build-support/setup-hooks/separate-debug-info.sh 240 - ++ lib.optional stdenv.hostPlatform.isWindows ../../build-support/setup-hooks/win-dll-link.sh 241 - ++ lib.optionals doCheck nativeCheckInputs 242 - ++ lib.optionals doInstallCheck nativeInstallCheckInputs; 276 + ++ optional separateDebugInfo' ../../build-support/setup-hooks/separate-debug-info.sh 277 + ++ optional stdenv.hostPlatform.isWindows ../../build-support/setup-hooks/win-dll-link.sh 278 + ++ optionals doCheck nativeCheckInputs 279 + ++ optionals doInstallCheck nativeInstallCheckInputs; 243 280 244 281 outputs = outputs'; 245 282 246 283 references = nativeBuildInputs ++ buildInputs 247 284 ++ propagatedNativeBuildInputs ++ propagatedBuildInputs; 248 285 249 - dependencies = map (map lib.chooseDevOutputs) [ 286 + dependencies = map (map chooseDevOutputs) [ 250 287 [ 251 288 (map (drv: drv.__spliced.buildBuild or drv) (checkDependencyList "depsBuildBuild" depsBuildBuild)) 252 289 (map (drv: drv.__spliced.buildHost or drv) (checkDependencyList "nativeBuildInputs" nativeBuildInputs')) ··· 260 297 (map (drv: drv.__spliced.targetTarget or drv) (checkDependencyList "depsTargetTarget" depsTargetTarget)) 261 298 ] 262 299 ]; 263 - propagatedDependencies = map (map lib.chooseDevOutputs) [ 300 + propagatedDependencies = map (map chooseDevOutputs) [ 264 301 [ 265 302 (map (drv: drv.__spliced.buildBuild or drv) (checkDependencyList "depsBuildBuildPropagated" depsBuildBuildPropagated)) 266 303 (map (drv: drv.__spliced.buildHost or drv) (checkDependencyList "propagatedNativeBuildInputs" propagatedNativeBuildInputs)) ··· 276 313 ]; 277 314 278 315 computedSandboxProfile = 279 - lib.concatMap (input: input.__propagatedSandboxProfile or []) 316 + concatMap (input: input.__propagatedSandboxProfile or []) 280 317 (stdenv.extraNativeBuildInputs 281 318 ++ stdenv.extraBuildInputs 282 - ++ lib.concatLists dependencies); 319 + ++ concatLists dependencies); 283 320 284 321 computedPropagatedSandboxProfile = 285 - lib.concatMap (input: input.__propagatedSandboxProfile or []) 286 - (lib.concatLists propagatedDependencies); 322 + concatMap (input: input.__propagatedSandboxProfile or []) 323 + (concatLists propagatedDependencies); 287 324 288 325 computedImpureHostDeps = 289 - lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or []) 326 + unique (concatMap (input: input.__propagatedImpureHostDeps or []) 290 327 (stdenv.extraNativeBuildInputs 291 328 ++ stdenv.extraBuildInputs 292 - ++ lib.concatLists dependencies)); 329 + ++ concatLists dependencies)); 293 330 294 331 computedPropagatedImpureHostDeps = 295 - lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or []) 296 - (lib.concatLists propagatedDependencies)); 332 + unique (concatMap (input: input.__propagatedImpureHostDeps or []) 333 + (concatLists propagatedDependencies)); 297 334 298 - envIsExportable = lib.isAttrs env && !lib.isDerivation env; 335 + envIsExportable = isAttrs env && !isDerivation env; 299 336 300 337 derivationArg = 301 338 (removeAttrs attrs ··· 306 343 "__darwinAllowLocalNetworking" 307 344 "__impureHostDeps" "__propagatedImpureHostDeps" 308 345 "sandboxProfile" "propagatedSandboxProfile"] 309 - ++ lib.optional (__structuredAttrs || envIsExportable) "env")) 310 - // (lib.optionalAttrs (attrs ? name || (attrs ? pname && attrs ? version)) { 346 + ++ optional (__structuredAttrs || envIsExportable) "env")) 347 + // (optionalAttrs (attrs ? name || (attrs ? pname && attrs ? version)) { 311 348 name = 312 349 let 313 350 # Indicate the host platform of the derivation if cross compiling. ··· 315 352 # suffix. But we have some weird ones with run-time deps that are 316 353 # just used for their side-affects. Those might as well since the 317 354 # hash can't be the same. See #32986. 318 - hostSuffix = lib.optionalString 355 + hostSuffix = optionalString 319 356 (stdenv.hostPlatform != stdenv.buildPlatform && !dontAddHostSuffix) 320 357 "-${stdenv.hostPlatform.config}"; 321 358 ··· 324 361 # nix and nixStatic. This should be also achieved by moving the 325 362 # hostSuffix before the version, so we could contemplate removing 326 363 # it again. 327 - staticMarker = lib.optionalString stdenv.hostPlatform.isStatic "-static"; 364 + staticMarker = optionalString stdenv.hostPlatform.isStatic "-static"; 328 365 in 329 366 lib.strings.sanitizeDerivationName ( 330 367 if attrs ? name 331 368 then attrs.name + hostSuffix 332 369 else 333 370 # we cannot coerce null to a string below 334 - assert lib.assertMsg (attrs ? version && attrs.version != null) "The ‘version’ attribute cannot be null."; 371 + assert assertMsg (attrs ? version && attrs.version != null) "The ‘version’ attribute cannot be null."; 335 372 "${attrs.pname}${staticMarker}${hostSuffix}-${attrs.version}" 336 373 ); 337 - }) // lib.optionalAttrs __structuredAttrs { env = checkedEnv; } // { 374 + }) // optionalAttrs __structuredAttrs { env = checkedEnv; } // { 338 375 builder = attrs.realBuilder or stdenv.shell; 339 376 args = attrs.args or ["-e" (attrs.builder or ./default-builder.sh)]; 340 377 inherit stdenv; ··· 351 388 __ignoreNulls = true; 352 389 inherit __structuredAttrs strictDeps; 353 390 354 - depsBuildBuild = lib.elemAt (lib.elemAt dependencies 0) 0; 355 - nativeBuildInputs = lib.elemAt (lib.elemAt dependencies 0) 1; 356 - depsBuildTarget = lib.elemAt (lib.elemAt dependencies 0) 2; 357 - depsHostHost = lib.elemAt (lib.elemAt dependencies 1) 0; 358 - buildInputs = lib.elemAt (lib.elemAt dependencies 1) 1; 359 - depsTargetTarget = lib.elemAt (lib.elemAt dependencies 2) 0; 391 + depsBuildBuild = elemAt (elemAt dependencies 0) 0; 392 + nativeBuildInputs = elemAt (elemAt dependencies 0) 1; 393 + depsBuildTarget = elemAt (elemAt dependencies 0) 2; 394 + depsHostHost = elemAt (elemAt dependencies 1) 0; 395 + buildInputs = elemAt (elemAt dependencies 1) 1; 396 + depsTargetTarget = elemAt (elemAt dependencies 2) 0; 360 397 361 - depsBuildBuildPropagated = lib.elemAt (lib.elemAt propagatedDependencies 0) 0; 362 - propagatedNativeBuildInputs = lib.elemAt (lib.elemAt propagatedDependencies 0) 1; 363 - depsBuildTargetPropagated = lib.elemAt (lib.elemAt propagatedDependencies 0) 2; 364 - depsHostHostPropagated = lib.elemAt (lib.elemAt propagatedDependencies 1) 0; 365 - propagatedBuildInputs = lib.elemAt (lib.elemAt propagatedDependencies 1) 1; 366 - depsTargetTargetPropagated = lib.elemAt (lib.elemAt propagatedDependencies 2) 0; 398 + depsBuildBuildPropagated = elemAt (elemAt propagatedDependencies 0) 0; 399 + propagatedNativeBuildInputs = elemAt (elemAt propagatedDependencies 0) 1; 400 + depsBuildTargetPropagated = elemAt (elemAt propagatedDependencies 0) 2; 401 + depsHostHostPropagated = elemAt (elemAt propagatedDependencies 1) 0; 402 + propagatedBuildInputs = elemAt (elemAt propagatedDependencies 1) 1; 403 + depsTargetTargetPropagated = elemAt (elemAt propagatedDependencies 2) 0; 367 404 368 405 # This parameter is sometimes a string, sometimes null, and sometimes a list, yuck 369 - configureFlags = let inherit (lib) optional elem; in 406 + configureFlags = 370 407 configureFlags 371 408 ++ optional (elem "build" configurePlatforms) "--build=${stdenv.buildPlatform.config}" 372 409 ++ optional (elem "host" configurePlatforms) "--host=${stdenv.hostPlatform.config}" ··· 374 411 375 412 cmakeFlags = 376 413 cmakeFlags 377 - ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) ([ 378 - "-DCMAKE_SYSTEM_NAME=${lib.findFirst lib.isString "Generic" (lib.optional (!stdenv.hostPlatform.isRedox) stdenv.hostPlatform.uname.system)}" 379 - ] ++ lib.optionals (stdenv.hostPlatform.uname.processor != null) [ 414 + ++ optionals (stdenv.hostPlatform != stdenv.buildPlatform) ([ 415 + "-DCMAKE_SYSTEM_NAME=${findFirst isString "Generic" (optional (!stdenv.hostPlatform.isRedox) stdenv.hostPlatform.uname.system)}" 416 + ] ++ optionals (stdenv.hostPlatform.uname.processor != null) [ 380 417 "-DCMAKE_SYSTEM_PROCESSOR=${stdenv.hostPlatform.uname.processor}" 381 - ] ++ lib.optionals (stdenv.hostPlatform.uname.release != null) [ 418 + ] ++ optionals (stdenv.hostPlatform.uname.release != null) [ 382 419 "-DCMAKE_SYSTEM_VERSION=${stdenv.hostPlatform.uname.release}" 383 - ] ++ lib.optionals (stdenv.hostPlatform.isDarwin) [ 420 + ] ++ optionals (stdenv.hostPlatform.isDarwin) [ 384 421 "-DCMAKE_OSX_ARCHITECTURES=${stdenv.hostPlatform.darwinArch}" 385 - ] ++ lib.optionals (stdenv.buildPlatform.uname.system != null) [ 422 + ] ++ optionals (stdenv.buildPlatform.uname.system != null) [ 386 423 "-DCMAKE_HOST_SYSTEM_NAME=${stdenv.buildPlatform.uname.system}" 387 - ] ++ lib.optionals (stdenv.buildPlatform.uname.processor != null) [ 424 + ] ++ optionals (stdenv.buildPlatform.uname.processor != null) [ 388 425 "-DCMAKE_HOST_SYSTEM_PROCESSOR=${stdenv.buildPlatform.uname.processor}" 389 - ] ++ lib.optionals (stdenv.buildPlatform.uname.release != null) [ 426 + ] ++ optionals (stdenv.buildPlatform.uname.release != null) [ 390 427 "-DCMAKE_HOST_SYSTEM_VERSION=${stdenv.buildPlatform.uname.release}" 391 - ] ++ lib.optionals (stdenv.buildPlatform.canExecute stdenv.hostPlatform) [ 428 + ] ++ optionals (stdenv.buildPlatform.canExecute stdenv.hostPlatform) [ 392 429 "-DCMAKE_CROSSCOMPILING_EMULATOR=env" 393 430 ]); 394 431 ··· 402 439 403 440 crossFile = builtins.toFile "cross-file.conf" '' 404 441 [properties] 405 - needs_exe_wrapper = ${lib.boolToString (!stdenv.buildPlatform.canExecute stdenv.hostPlatform)} 442 + needs_exe_wrapper = ${boolToString (!stdenv.buildPlatform.canExecute stdenv.hostPlatform)} 406 443 407 444 [host_machine] 408 445 system = '${stdenv.targetPlatform.parsed.kernel.name}' ··· 413 450 [binaries] 414 451 llvm-config = 'llvm-config-native' 415 452 ''; 416 - crossFlags = lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ "--cross-file=${crossFile}" ]; 453 + crossFlags = optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ "--cross-file=${crossFile}" ]; 417 454 in crossFlags ++ mesonFlags; 418 455 419 456 inherit patches; ··· 421 458 inherit doCheck doInstallCheck; 422 459 423 460 inherit outputs; 424 - } // lib.optionalAttrs (__contentAddressed) { 461 + } // optionalAttrs (__contentAddressed) { 425 462 inherit __contentAddressed; 426 463 # Provide default values for outputHashMode and outputHashAlgo because 427 464 # most people won't care about these anyways 428 465 outputHashAlgo = attrs.outputHashAlgo or "sha256"; 429 466 outputHashMode = attrs.outputHashMode or "recursive"; 430 - } // lib.optionalAttrs (enableParallelBuilding) { 467 + } // optionalAttrs (enableParallelBuilding) { 431 468 inherit enableParallelBuilding; 432 469 enableParallelChecking = attrs.enableParallelChecking or true; 433 470 enableParallelInstalling = attrs.enableParallelInstalling or true; 434 - } // lib.optionalAttrs (hardeningDisable != [] || hardeningEnable != [] || stdenv.hostPlatform.isMusl) { 471 + } // optionalAttrs (hardeningDisable != [] || hardeningEnable != [] || stdenv.hostPlatform.isMusl) { 435 472 NIX_HARDENING_ENABLE = enabledHardeningOptions; 436 - } // lib.optionalAttrs (stdenv.hostPlatform.isx86_64 && stdenv.hostPlatform ? gcc.arch) { 473 + } // optionalAttrs (stdenv.hostPlatform.isx86_64 && stdenv.hostPlatform ? gcc.arch) { 437 474 requiredSystemFeatures = attrs.requiredSystemFeatures or [] ++ [ "gccarch-${stdenv.hostPlatform.gcc.arch}" ]; 438 - } // lib.optionalAttrs (stdenv.buildPlatform.isDarwin) { 475 + } // optionalAttrs (stdenv.buildPlatform.isDarwin) { 439 476 inherit __darwinAllowLocalNetworking; 440 - # TODO: remove lib.unique once nix has a list canonicalization primitive 477 + # TODO: remove `unique` once nix has a list canonicalization primitive 441 478 __sandboxProfile = 442 479 let profiles = [ stdenv.extraSandboxProfile ] ++ computedSandboxProfile ++ computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile sandboxProfile ]; 443 - final = lib.concatStringsSep "\n" (lib.filter (x: x != "") (lib.unique profiles)); 480 + final = concatStringsSep "\n" (filter (x: x != "") (unique profiles)); 444 481 in final; 445 - __propagatedSandboxProfile = lib.unique (computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile ]); 482 + __propagatedSandboxProfile = unique (computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile ]); 446 483 __impureHostDeps = computedImpureHostDeps ++ computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps ++ __impureHostDeps ++ stdenv.__extraImpureHostDeps ++ [ 447 484 "/dev/zero" 448 485 "/dev/random" ··· 469 506 # to be built eventually, we would still like to get the error early and without 470 507 # having to wait while nix builds a derivation that might not be used. 471 508 # See also https://github.com/NixOS/nix/issues/4629 472 - lib.optionalAttrs (attrs ? disallowedReferences) { 509 + optionalAttrs (attrs ? disallowedReferences) { 473 510 disallowedReferences = 474 511 map unsafeDerivationToUntrackedOutpath attrs.disallowedReferences; 475 512 } // 476 - lib.optionalAttrs (attrs ? disallowedRequisites) { 513 + optionalAttrs (attrs ? disallowedRequisites) { 477 514 disallowedRequisites = 478 515 map unsafeDerivationToUntrackedOutpath attrs.disallowedRequisites; 479 516 } // 480 - lib.optionalAttrs (attrs ? allowedReferences) { 517 + optionalAttrs (attrs ? allowedReferences) { 481 518 allowedReferences = 482 - lib.mapNullable unsafeDerivationToUntrackedOutpath attrs.allowedReferences; 519 + mapNullable unsafeDerivationToUntrackedOutpath attrs.allowedReferences; 483 520 } // 484 - lib.optionalAttrs (attrs ? allowedRequisites) { 521 + optionalAttrs (attrs ? allowedRequisites) { 485 522 allowedRequisites = 486 - lib.mapNullable unsafeDerivationToUntrackedOutpath attrs.allowedRequisites; 523 + mapNullable unsafeDerivationToUntrackedOutpath attrs.allowedRequisites; 487 524 }; 488 525 489 526 meta = checkMeta.commonMeta { inherit validity attrs pos references; }; ··· 491 528 492 529 checkedEnv = 493 530 let 494 - overlappingNames = lib.attrNames (builtins.intersectAttrs env derivationArg); 531 + overlappingNames = attrNames (builtins.intersectAttrs env derivationArg); 495 532 in 496 - assert lib.assertMsg envIsExportable 533 + assert assertMsg envIsExportable 497 534 "When using structured attributes, `env` must be an attribute set of environment variables."; 498 - assert lib.assertMsg (overlappingNames == [ ]) 499 - "The ‘env’ attribute set cannot contain any attributes passed to derivation. The following attributes are overlapping: ${lib.concatStringsSep ", " overlappingNames}"; 500 - lib.mapAttrs 501 - (n: v: assert lib.assertMsg (lib.isString v || lib.isBool v || lib.isInt v || lib.isDerivation v) 535 + assert assertMsg (overlappingNames == [ ]) 536 + "The ‘env’ attribute set cannot contain any attributes passed to derivation. The following attributes are overlapping: ${concatStringsSep ", " overlappingNames}"; 537 + mapAttrs 538 + (n: v: assert assertMsg (isString v || isBool v || isInt v || isDerivation v) 502 539 "The ‘env’ attribute set can only contain derivation, string, boolean or integer attributes. The ‘${n}’ attribute is of type ${builtins.typeOf v}."; v) 503 540 env; 504 541 505 542 in 506 543 507 - lib.extendDerivation 544 + extendDerivation 508 545 validity.handled 509 546 ({ 510 547 # A derivation that always builds successfully and whose runtime ··· 553 590 # should be made available to Nix expressions using the 554 591 # derivation (e.g., in assertions). 555 592 passthru) 556 - (derivation (derivationArg // lib.optionalAttrs envIsExportable checkedEnv)); 593 + (derivation (derivationArg // optionalAttrs envIsExportable checkedEnv)); 557 594 558 595 in 559 596 fnOrAttrs: