diff options
-rw-r--r-- | src/libexpr/eval-inline.hh | 8 | ||||
-rw-r--r-- | src/libexpr/eval.cc | 2 | ||||
-rw-r--r-- | src/libexpr/eval.hh | 1 | ||||
-rw-r--r-- | src/libexpr/get-drvs.cc | 2 | ||||
-rw-r--r-- | src/libexpr/primops.cc | 24 |
5 files changed, 23 insertions, 14 deletions
diff --git a/src/libexpr/eval-inline.hh b/src/libexpr/eval-inline.hh index c34e24d3da39..c275f7ba83e8 100644 --- a/src/libexpr/eval-inline.hh +++ b/src/libexpr/eval-inline.hh @@ -55,6 +55,14 @@ inline void EvalState::forceAttrs(Value & v) } +inline void EvalState::forceAttrs(Value & v, const Pos & pos) +{ + forceValue(v); + if (v.type != tAttrs) + throwTypeError("value is %1% while a set was expected, at %2%", v, pos); +} + + inline void EvalState::forceList(Value & v) { forceValue(v); diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index b74170ecb158..5c88a34a92ca 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -850,7 +850,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po env2.values[displ++] = &arg; else { - forceAttrs(arg); + forceAttrs(arg, pos); if (!lambda.arg.empty()) env2.values[displ++] = &arg; diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index decca9e40674..248805004c6b 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -161,6 +161,7 @@ public: NixInt forceInt(Value & v, const Pos & pos); bool forceBool(Value & v); inline void forceAttrs(Value & v); + inline void forceAttrs(Value & v, const Pos & pos); inline void forceList(Value & v); inline void forceList(Value & v, const Pos & pos); void forceFunction(Value & v, const Pos & pos); // either lambda or primop diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc index 96298556d851..4e7690063a0b 100644 --- a/src/libexpr/get-drvs.cc +++ b/src/libexpr/get-drvs.cc @@ -75,7 +75,7 @@ Bindings * DrvInfo::getMeta() if (!attrs) return 0; Bindings::iterator a = attrs->find(state->sMeta); if (a == attrs->end()) return 0; - state->forceAttrs(*a->value); + state->forceAttrs(*a->value, *a->pos); meta = a->value->attrs; return meta; } diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 7028ddc907b9..2aa45525e6d5 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -86,7 +86,7 @@ static void prim_import(EvalState & state, const Pos & pos, Value * * args, Valu state.evalFile(state.findFile("nix/imported-drv-to-derivation.nix"), fun); state.forceFunction(fun, pos); mkApp(v, fun, w); - state.forceAttrs(v); + state.forceAttrs(v, pos); } else { state.evalFile(path, v); } @@ -188,7 +188,7 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar { startNest(nest, lvlDebug, "finding dependencies"); - state.forceAttrs(*args[0]); + state.forceAttrs(*args[0], pos); /* Get the start set. */ Bindings::iterator startSet = @@ -219,7 +219,7 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar Value * e = *(workSet.begin()); workSet.pop_front(); - state.forceAttrs(*e); + state.forceAttrs(*e, pos); Bindings::iterator key = e->attrs->find(state.symbols.create("key")); @@ -334,7 +334,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * { startNest(nest, lvlVomit, "evaluating derivation"); - state.forceAttrs(*args[0]); + state.forceAttrs(*args[0], pos); /* Figure out the name first (for stack backtraces). */ Bindings::iterator attr = args[0]->attrs->find(state.sName); @@ -758,7 +758,7 @@ static void prim_filterSource(EvalState & state, const Pos & pos, Value * * args strings. */ static void prim_attrNames(EvalState & state, const Pos & pos, Value * * args, Value & v) { - state.forceAttrs(*args[0]); + state.forceAttrs(*args[0], pos); state.mkList(v, args[0]->attrs->size()); @@ -776,7 +776,7 @@ static void prim_attrNames(EvalState & state, const Pos & pos, Value * * args, V void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v) { string attr = state.forceStringNoCtx(*args[0]); - state.forceAttrs(*args[1]); + state.forceAttrs(*args[1], pos); // !!! Should we create a symbol here or just do a lookup? Bindings::iterator i = args[1]->attrs->find(state.symbols.create(attr)); if (i == args[1]->attrs->end()) @@ -792,7 +792,7 @@ void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v) void prim_unsafeGetAttrPos(EvalState & state, const Pos & pos, Value * * args, Value & v) { string attr = state.forceStringNoCtx(*args[0]); - state.forceAttrs(*args[1]); + state.forceAttrs(*args[1], pos); Bindings::iterator i = args[1]->attrs->find(state.symbols.create(attr)); if (i == args[1]->attrs->end()) mkNull(v); @@ -805,7 +805,7 @@ void prim_unsafeGetAttrPos(EvalState & state, const Pos & pos, Value * * args, V static void prim_hasAttr(EvalState & state, const Pos & pos, Value * * args, Value & v) { string attr = state.forceStringNoCtx(*args[0]); - state.forceAttrs(*args[1]); + state.forceAttrs(*args[1], pos); mkBool(v, args[1]->attrs->find(state.symbols.create(attr)) != args[1]->attrs->end()); } @@ -820,7 +820,7 @@ static void prim_isAttrs(EvalState & state, const Pos & pos, Value * * args, Val static void prim_removeAttrs(EvalState & state, const Pos & pos, Value * * args, Value & v) { - state.forceAttrs(*args[0]); + state.forceAttrs(*args[0], pos); state.forceList(*args[1], pos); /* Get the attribute names to be removed. */ @@ -856,7 +856,7 @@ static void prim_listToAttrs(EvalState & state, const Pos & pos, Value * * args, for (unsigned int i = 0; i < args[0]->list.length; ++i) { Value & v2(*args[0]->list.elems[i]); - state.forceAttrs(v2); + state.forceAttrs(v2, pos); Bindings::iterator j = v2.attrs->find(state.sName); if (j == v2.attrs->end()) @@ -883,8 +883,8 @@ static void prim_listToAttrs(EvalState & state, const Pos & pos, Value * * args, member of as1. */ static void prim_intersectAttrs(EvalState & state, const Pos & pos, Value * * args, Value & v) { - state.forceAttrs(*args[0]); - state.forceAttrs(*args[1]); + state.forceAttrs(*args[0], pos); + state.forceAttrs(*args[1], pos); state.mkAttrs(v, std::min(args[0]->attrs->size(), args[1]->attrs->size())); |