fix(tvix): Pass all args when auto-calling a function with an ellipsis
The command line options --arg and --argstr that are used by a bunch of CLI commands to pass arguments to top-level functions in files go through the same code-path as auto-calling top-level functions with their default arguments - this, however, was only passing the arguments that were *explicitly* mentioned in the formals of the function - in the case of an as-pattern with an ellipsis (eg args @ { ... }) extra passed arguments would get omitted. This fixes that to instead pass *all* specified auto args in the case that our function has an ellipsis. Submitted upstream at https://github.com/NixOS/nix/pull/3965 Fixes: #46 Change-Id: I32b7ee0e5bacf75b2bc43a3f0796f533f4bd5959 Reviewed-on: https://cl.tvl.fyi/c/depot/+/1863 Reviewed-by: tazjin <mail@tazj.in> Tested-by: BuildkiteCI
This commit is contained in:
parent
3bada1d41e
commit
fb0528c5da
2 changed files with 21 additions and 9 deletions
29
third_party/nix/src/libexpr/eval.cc
vendored
29
third_party/nix/src/libexpr/eval.cc
vendored
|
@ -1117,15 +1117,26 @@ void EvalState::autoCallFunction(Bindings* args, Value& fun, Value& res) {
|
||||||
Value* actualArgs = allocValue();
|
Value* actualArgs = allocValue();
|
||||||
mkAttrs(*actualArgs, fun.lambda.fun->formals->formals.size());
|
mkAttrs(*actualArgs, fun.lambda.fun->formals->formals.size());
|
||||||
|
|
||||||
for (auto& i : fun.lambda.fun->formals->formals) {
|
if (fun.lambda.fun->formals->ellipsis) {
|
||||||
Bindings::iterator j = args->find(i.name);
|
// If the formals have an ellipsis (eg the function accepts extra args) pass
|
||||||
if (j != args->end()) {
|
// all available automatic arguments (which includes arguments specified on
|
||||||
actualArgs->attrs->push_back(j->second);
|
// the command line via --arg/--argstr)
|
||||||
} else if (i.def == nullptr) {
|
for (auto& [_, v] : *args) {
|
||||||
throwTypeError(
|
actualArgs->attrs->push_back(v);
|
||||||
"cannot auto-call a function that has an argument without a default "
|
}
|
||||||
"value ('%1%')",
|
} else {
|
||||||
i.name);
|
// Otherwise, only pass the arguments that the function accepts
|
||||||
|
for (auto& i : fun.lambda.fun->formals->formals) {
|
||||||
|
Bindings::iterator j = args->find(i.name);
|
||||||
|
if (j != args->end()) {
|
||||||
|
actualArgs->attrs->push_back(j->second);
|
||||||
|
} else if (i.def == nullptr) {
|
||||||
|
throwTypeError(
|
||||||
|
"cannot auto-call a function that has an argument without a "
|
||||||
|
"default "
|
||||||
|
"value ('%1%')",
|
||||||
|
i.name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
1
third_party/nix/src/nix-build/nix-build.cc
vendored
1
third_party/nix/src/nix-build/nix-build.cc
vendored
|
@ -270,6 +270,7 @@ static void _main(int argc, char** argv) {
|
||||||
|
|
||||||
if (packages) {
|
if (packages) {
|
||||||
std::ostringstream joined;
|
std::ostringstream joined;
|
||||||
|
// TODO(grfn): Generate a syntax tree here, not a string
|
||||||
joined << "with import <nixpkgs> { }; (pkgs.runCommandCC or "
|
joined << "with import <nixpkgs> { }; (pkgs.runCommandCC or "
|
||||||
"pkgs.runCommand) \"shell\" { buildInputs = [ ";
|
"pkgs.runCommand) \"shell\" { buildInputs = [ ";
|
||||||
for (const auto& i : left) {
|
for (const auto& i : left) {
|
||||||
|
|
Loading…
Reference in a new issue