From 626200713bb3cc844a9feb6af583c9b6b42c6dbc Mon Sep 17 00:00:00 2001 From: Griffin Smith Date: Thu, 27 Aug 2020 12:28:12 -0400 Subject: [PATCH] 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. Fixes #598 --- src/libexpr/eval.cc | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 0123070d1..00191bce0 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1299,12 +1299,23 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res) Value * actualArgs = allocValue(); mkAttrs(*actualArgs, fun.lambda.fun->formals->formals.size()); - for (auto & i : fun.lambda.fun->formals->formals) { - Bindings::iterator j = args.find(i.name); - if (j != args.end()) - actualArgs->attrs->push_back(*j); - else if (!i.def) - throwTypeError("cannot auto-call a function that has an argument without a default value ('%1%')", i.name); + if (fun.lambda.fun->formals->ellipsis) { + // If the formals have an ellipsis (eg the function accepts extra args) pass + // all available automatic arguments (which includes arguments specified on + // the command line via --arg/--argstr) + for (auto& v : args) { + actualArgs->attrs->push_back(v); + } + } else { + // 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); + } else if (!i.def) { + throwTypeError("cannot auto-call a function that has an argument without a default value ('%1%')", i.name); + } + } } actualArgs->attrs->sort();