diff options
-rw-r--r-- | corepkgs/channels/unpack.sh.in | 2 | ||||
-rw-r--r-- | src/libexpr/eval.cc | 2 | ||||
-rw-r--r-- | src/libexpr/primops.cc | 13 |
3 files changed, 15 insertions, 2 deletions
diff --git a/corepkgs/channels/unpack.sh.in b/corepkgs/channels/unpack.sh.in index 03c6e5b2f894..1f2886a6ab4f 100644 --- a/corepkgs/channels/unpack.sh.in +++ b/corepkgs/channels/unpack.sh.in @@ -24,7 +24,7 @@ for ((n = 0; n < ${#inputs[*]}; n += 2)); do @coreutils@/mv * ../$dirName # !!! hacky attrName=$(echo $dirName | @tr@ -- '- ' '__') - echo "$attrName = import ./$dirName {};" >> $expr + echo "$attrName = let e = import ./$dirName; in if builtins.isFunction e then e {} else e;" >> $expr done echo '} // {_combineChannels = true;}' >> $expr diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 552b586250b1..a8a22e2f2c78 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -478,7 +478,7 @@ LocalNoInline(Expr evalCall(EvalState & state, Expr fun, Expr arg)) } else throwTypeError( - "the left-hand side of the function call is neither a function nor a primop (built-in operation) but %1%", + "attempt to call something which is neither a function nor a primop (built-in operation) but %1%", showType(fun)); } diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index c7fbca0bb59e..95440c9bf655 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -114,6 +114,18 @@ static Expr prim_isNull(EvalState & state, const ATermVector & args) } +/* Determine whether the argument is a function. */ +static Expr prim_isFunction(EvalState & state, const ATermVector & args) +{ + Expr e = evalExpr(state, args[0]); + ATermList formals; + ATerm name, body, pos; + return makeBool( + matchFunction(e, formals, body, pos) || + matchFunction1(e, name, body, pos)); +} + + static Path findDependency(Path dir, string dep) { if (dep[0] == '/') throw EvalError( @@ -884,6 +896,7 @@ void EvalState::addPrimOps() // Miscellaneous addPrimOp("import", 1, prim_import); addPrimOp("isNull", 1, prim_isNull); + addPrimOp("__isFunction", 1, prim_isFunction); addPrimOp("dependencyClosure", 1, prim_dependencyClosure); addPrimOp("abort", 1, prim_abort); addPrimOp("throw", 1, prim_throw); |