diff options
author | volth <volth@volth.com> | 2018-07-06T21·49+0000 |
---|---|---|
committer | volth <volth@volth.com> | 2018-07-06T21·52+0000 |
commit | 627e28ba332f21109d7eace8ba0a7932e4d98b2e (patch) | |
tree | 4ecbeffdf7a7d5cb86b106b9b9ab78b5ea06bf69 /src/libexpr | |
parent | aa64e95bc82b3a57f3a645a746aacf4d2479266e (diff) |
prim_mapAttrs: `f' must be evaluated lazily to avoid infinite recursion
Diffstat (limited to 'src/libexpr')
-rw-r--r-- | src/libexpr/eval.cc | 6 | ||||
-rw-r--r-- | src/libexpr/primops.cc | 3 |
2 files changed, 3 insertions, 6 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index e09297546c95..30dbb17fb67a 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1076,6 +1076,8 @@ void EvalState::callPrimOp(Value & fun, Value & arg, Value & v, const Pos & pos) void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & pos) { + forceValue(fun, pos); + if (fun.type == tPrimOp || fun.type == tPrimOpApp) { callPrimOp(fun, arg, v, pos); return; @@ -1091,10 +1093,8 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po auto & fun2 = *allocValue(); fun2 = fun; /* !!! Should we use the attr pos here? */ - forceValue(*found->value, pos); Value v2; callFunction(*found->value, fun2, v2, pos); - forceValue(v2, pos); return callFunction(v2, arg, v, pos); } } @@ -1181,7 +1181,6 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res) if (fun.type == tAttrs) { auto found = fun.attrs->find(sFunctor); if (found != fun.attrs->end()) { - forceValue(*found->value); Value * v = allocValue(); callFunction(*found->value, fun, *v, noPos); forceValue(*v); @@ -1565,7 +1564,6 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, if (v.type == tAttrs) { auto i = v.attrs->find(sToString); if (i != v.attrs->end()) { - forceValue(*i->value, pos); Value v1; callFunction(*i->value, v, v1, pos); return coerceToString(pos, v1, context, coerceMore, copyToStore); diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index e71e3a6d46cb..e7b319fea642 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -1359,7 +1359,6 @@ static void prim_functionArgs(EvalState & state, const Pos & pos, Value * * args /* Apply a function to every element of an attribute set. */ static void prim_mapAttrs(EvalState & state, const Pos & pos, Value * * args, Value & v) { - state.forceFunction(*args[0], pos); state.forceAttrs(*args[1], pos); state.mkAttrs(v, args[1]->attrs->size()); @@ -1368,7 +1367,7 @@ static void prim_mapAttrs(EvalState & state, const Pos & pos, Value * * args, Va Value * vName = state.allocValue(); Value * vFun2 = state.allocValue(); mkString(*vName, i.name); - state.callFunction(*args[0], *vName, *vFun2, pos); + mkApp(*vFun2, *args[0], *vName); mkApp(*state.allocAttr(v, i.name), *vFun2, *i.value); } } |