| 1777 | } |
| 1778 | |
| 1779 | void EvalState::autoCallFunction(const Bindings & args, Value & fun, Value & res) |
| 1780 | { |
| 1781 | auto pos = fun.determinePos(noPos); |
| 1782 | |
| 1783 | forceValue(fun, pos); |
| 1784 | |
| 1785 | if (fun.type() == nAttrs) { |
| 1786 | auto found = fun.attrs()->get(s.functor); |
| 1787 | if (found) { |
| 1788 | Value * v = allocValue(); |
| 1789 | callFunction(*found->value, fun, *v, pos); |
| 1790 | forceValue(*v, pos); |
| 1791 | return autoCallFunction(args, *v, res); |
| 1792 | } |
| 1793 | } |
| 1794 | |
| 1795 | if (!fun.isLambda() || !fun.lambda().fun->getFormals()) { |
| 1796 | res = fun; |
| 1797 | return; |
| 1798 | } |
| 1799 | auto formals = fun.lambda().fun->getFormals(); |
| 1800 | |
| 1801 | auto attrs = buildBindings(std::max(static_cast<uint32_t>(formals->formals.size()), args.size())); |
| 1802 | |
| 1803 | if (formals->ellipsis) { |
| 1804 | // If the formals have an ellipsis (eg the function accepts extra args) pass |
| 1805 | // all available automatic arguments (which includes arguments specified on |
| 1806 | // the command line via --arg/--argstr) |
| 1807 | for (auto & v : args) |
| 1808 | attrs.insert(v); |
| 1809 | } else { |
| 1810 | // Otherwise, only pass the arguments that the function accepts |
| 1811 | for (auto & i : formals->formals) { |
| 1812 | auto j = args.get(i.name); |
| 1813 | if (j) { |
| 1814 | attrs.insert(*j); |
| 1815 | } else if (!i.def) { |
| 1816 | error<MissingArgumentError>( |
| 1817 | R"(cannot evaluate a function that has an argument without a value ('%1%') |
| 1818 | Nix attempted to evaluate a function as a top level expression; in |
| 1819 | this case it must have its arguments supplied either by default |
| 1820 | values, or passed explicitly with '--arg' or '--argstr'. See |
| 1821 | https://nix.dev/manual/nix/stable/language/syntax.html#functions.)", |
| 1822 | symbols[i.name]) |
| 1823 | .atPos(i.pos) |
| 1824 | .withFrame(*fun.lambda().env, *fun.lambda().fun) |
| 1825 | .debugThrow(); |
| 1826 | } |
| 1827 | } |
| 1828 | } |
| 1829 | |
| 1830 | callFunction(fun, allocValue()->mkAttrs(attrs), res, pos); |
| 1831 | } |
| 1832 | |
| 1833 | void ExprWith::eval(EvalState & state, Env & env, Value & v) |
| 1834 | { |
no test coverage detected