This code was more careful before
<dd435697b3>
(it didn't assume that `unsafeGetAttrPos` always returns a non-null
location). Unfortunately, `unsafeGetAttrPos` *does* return `null` when
dealing with `nix repl`:
```
nix-repl> f = {foo}: foo
nix-repl> builtins.unsafeGetAttrPos "foo" (builtins.functionArgs f)
null
```
Here's how to reproduce the issue.
*Before* this fix:
```
nix-repl> f = {foo}: foo
nix-repl> myCallPackage = lib.callPackageWith {}
nix-repl> myCallPackage f {}
error:
… while calling the 'abort' builtin
at /home/jeremy/src/github.com/NixOS/nixpkgs/lib/customisation.nix:323:7:
322| else
323| abort "lib.customisation.callPackageWith: ${error}";
| ^
324|
… while selecting an attribute
at /home/jeremy/src/github.com/NixOS/nixpkgs/lib/customisation.nix:310:14:
309| "Function called without required argument \"${arg}\" at "
310| + "${loc.file}:${toString loc.line}${prettySuggestions (getSuggestions arg)}";
| ^
311|
error: expected a set but found null: null
```
*After*:
```
nix-repl> f = {foo}: foo
nix-repl> myCallPackage = lib.callPackageWith {}
nix-repl> myCallPackage f {}
error:
… while calling the 'abort' builtin
at /home/jeremy/src/github.com/NixOS/nixpkgs/lib/customisation.nix:332:7:
331| # Inputs
332|
| ^
333| `autoArgs`
error: evaluation aborted with the following error message: 'lib.customisation.callPackageWith: Function called without required argument "foo" at <unknown location>'
```
A Cross Index, short for Cross Platform Pair Index, is the essential
shape of a splice, without the invoking the more mind bending concept
of adding variations of for these 6 pairings to an existing thing so
that it can be switched out for something else.
So the purpose of a Cross Index is to contain the result of `f`\
(which may be reified in code, or just an abstract concept):
- f "build" "build"
- f "build" "host"
- ...
Splicing on the other hand refers not just to these six variants, but
to the idea of tacking them onto one of the variants. (hostTarget,
I believe)
Cross Indexes are a necessity for making cross compilation work, but
splicing is more than necessary.
Tested with:
1. Replace the callPackageWith call by `null`, to simulate an ancient Nix
2. Run the following commands in a terminal in nixpkgs:
$ mkdir test/
$ echo '{ asdfasdfasdf }: null' >test/default.nix
$ nix repl -f .
nix-repl> callPackage ./test { }
error:
… while calling the 'abort' builtin
at /home/user/src/nixpkgs/lib/customisation.nix:312:7:
311| else
312| abort "lib.customisation.callPackageWith: ${error}";
| ^
313|
error: evaluation aborted with the following error message: 'lib.customisation.callPackageWith: Function called without required argument "asdfasdfasdf" at /home/user/src/nixpkgs/test/default.nix'
makeOverridable is very careful to ensure the arguments to the
overridden function are the same as the input function. As a result,
the arguments of hello.override are exactly the same as the original
arguments of the hello function that produced the derivation.
However, callPackagesWith calls makeOverridable with a lambda that
does not propagate the arguments. The override function for a package
instantiated with callPackagesWith will not have the original
arguments.
For example:
nix-repl> lib.functionArgs hello.override
{ callPackage = false; fetchurl = false; hello = false; lib = false; nixos = false; stdenv = false; testers = false; }
nix-repl> lib.functionArgs openssl.override
{ }
By copying the arguments onto the inner lambda before passing it to
makeOverridable, we can make callPackage and callPackages behave the
same.
nix-repl> lib.functionArgs openssl.override
{ buildPackages = false; coreutils = false; cryptodev = false; enableSSL2 = true; enableSSL3 = true; fetchurl = false; lib = false; perl = false; removeReferencesTo = false; static = true; stdenv = false; withCryptodev = true; withPerl = true; }
Add the "Type:" blocks.
Move the examples below the descriptions whenever possibles
Add "Example:" tags before the examples moved below the descriptions.
Right now converting `makeScope` to `makeScopeWithSplicing` is not
transparent to users and requires adding a warning for `overrideScope'`
in the set itself.
Warning and `overrideScope'` were added in 2018 b9dce11712 and there should be no users left after 5 years.
Deeply-curried functions are pretty error-prone in untyped languages
like Nix. This is a particularly bad case because
`top-level/splice.nix` *also* declares a makeScopeWithSplicing, but
it takes *two fewer arguments*.
Let's add a version that uses attrset-passing form, to provide some
minimal level of sanity-checking.
This also provides defaults for keep and extra (these are often
unneeded by the user).
Deeply-curried functions are pretty error-prone in untyped languages
like Nix. This is a particularly bad case because
`top-level/splice.nix` *also* declares a makeScopeWithSplicing, but
it takes *two fewer arguments*.
Let's switch to attrset-passing form, to provide some minimal level
of sanity-checking.
ofborg relies on the behavior that existed prior to
1c00bf3948, where evaluation would
immediately abort due to a missing argument (whether it be an aliased
package when `allowAliases = false;` or a typo'd or otherwise
nonexistent package).
If `callPackageWith` `throw`s instead of `abort`s, the following
`nix-env` invocation does not fail fast but instead silently skips the
attribute (assuming there is a package that has an aliased package in
its `autoArgs`):
$ nix-env -qa --json --file . --arg config '{ allowAliases = false; }' &>/dev/null
$ echo $?
0
This does change the error output when there is a missing package (for
any of the reasons mentioned above), though. Before this change, the
errors looked like this:
$ nix-build -A hello --arg config '{ allowAliases = false; }'
error:
… while calling the 'throw' builtin
at /home/vin/workspace/vcs/nixpkgs/master/lib/customisation.nix:179:65:
178|
179| in if missingArgs == [] then makeOverridable f allArgs else throw error;
| ^
180|
error: Function called without required argument "bash_5" at /home/vin/workspace/vcs/nixpkgs/master/pkgs/applications/misc/hello/default.nix:8, did you mean "bash" or "bashdb"?
And the errors now look like this:
$ nix-build -A hello --arg config '{ allowAliases = false; }'
error:
… while calling the 'abort' builtin
at /home/vin/workspace/vcs/nixpkgs/master/lib/customisation.nix:179:65:
178|
179| in if missingArgs == [] then makeOverridable f allArgs else abort error;
| ^
180|
error: evaluation aborted with the following error message: 'Function called without required argument "bash_5" at /home/vin/workspace/vcs/nixpkgs/master/pkgs/applications/misc/hello/default.nix:8, did you mean "bash" or "bashdb"?'
By allowing null, we allow code to avoid filterAttrs, improving
laziness in real world use cases.
Specifically, this strategy prevents infinite recursion errors,
performance issues and possibly other errors that are unrelated to
the user's code.