about summary refs log tree commit diff
path: root/src/libexpr
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2014-04-04T17·05+0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2014-04-04T17·05+0200
commit96b695ccab4a4c8c4ef7f14ac261df43dcc00743 (patch)
tree3511cba77ca830dbe598ed207b79ce21afc74870 /src/libexpr
parentb62d36963c45ccaebb328fceaf0bb40f9c02a14b (diff)
forceList: Show position info
Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/eval-inline.hh15
-rw-r--r--src/libexpr/eval.cc9
-rw-r--r--src/libexpr/eval.hh3
-rw-r--r--src/libexpr/get-drvs.cc2
-rw-r--r--src/libexpr/primops.cc30
5 files changed, 35 insertions, 24 deletions
diff --git a/src/libexpr/eval-inline.hh b/src/libexpr/eval-inline.hh
index ffe8fa59cda0..c34e24d3da39 100644
--- a/src/libexpr/eval-inline.hh
+++ b/src/libexpr/eval-inline.hh
@@ -18,6 +18,12 @@ LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v))
 }
 
 
+LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v, const Pos & pos))
+{
+    throw TypeError(format(s) % showType(v) % pos);
+}
+
+
 void EvalState::forceValue(Value & v)
 {
     if (v.type == tThunk) {
@@ -56,4 +62,13 @@ inline void EvalState::forceList(Value & v)
         throwTypeError("value is %1% while a list was expected", v);
 }
 
+
+inline void EvalState::forceList(Value & v, const Pos & pos)
+{
+    forceValue(v);
+    if (v.type != tList)
+        throwTypeError("value is %1% while a list was expected, at %2%", v, pos);
+}
+
+
 }
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 0be1e73491e9..b74170ecb158 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -294,11 +294,6 @@ LocalNoInlineNoReturn(void throwTypeError(const char * s, const string & s1))
     throw TypeError(format(s) % s1);
 }
 
-LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v, const Pos & pos))
-{
-    throw TypeError(format(s) % showType(v) % pos);
-}
-
 LocalNoInlineNoReturn(void throwTypeError(const char * s, const string & s1, const string & s2))
 {
     throw TypeError(format(s) % s1 % s2);
@@ -1169,11 +1164,11 @@ bool EvalState::forceBool(Value & v)
 }
 
 
-void EvalState::forceFunction(Value & v)
+void EvalState::forceFunction(Value & v, const Pos & pos)
 {
     forceValue(v);
     if (v.type != tLambda && v.type != tPrimOp && v.type != tPrimOpApp)
-        throwTypeError("value is %1% while a function was expected", v);
+        throwTypeError("value is %1% while a function was expected, at %2%", v, pos);
 }
 
 
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 0a424ddb9423..decca9e40674 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -162,7 +162,8 @@ public:
     bool forceBool(Value & v);
     inline void forceAttrs(Value & v);
     inline void forceList(Value & v);
-    void forceFunction(Value & v); // either lambda or primop
+    inline void forceList(Value & v, const Pos & pos);
+    void forceFunction(Value & v, const Pos & pos); // either lambda or primop
     string forceString(Value & v);
     string forceString(Value & v, PathSet & context);
     string forceStringNoCtx(Value & v);
diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc
index 0ed644e9bc5b..96298556d851 100644
--- a/src/libexpr/get-drvs.cc
+++ b/src/libexpr/get-drvs.cc
@@ -36,7 +36,7 @@ DrvInfo::Outputs DrvInfo::queryOutputs()
         /* Get the ‘outputs’ list. */
         Bindings::iterator i;
         if (attrs && (i = attrs->find(state->sOutputs)) != attrs->end()) {
-            state->forceList(*i->value);
+            state->forceList(*i->value, *i->pos);
 
             /* For each output... */
             for (unsigned int j = 0; j < i->value->list.length; ++j) {
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index b33b76bca121..7028ddc907b9 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -84,7 +84,7 @@ static void prim_import(EvalState & state, const Pos & pos, Value * * args, Valu
         w.attrs->sort();
         Value fun;
         state.evalFile(state.findFile("nix/imported-drv-to-derivation.nix"), fun);
-        state.forceFunction(fun);
+        state.forceFunction(fun, pos);
         mkApp(v, fun, w);
         state.forceAttrs(v);
     } else {
@@ -195,7 +195,7 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar
         args[0]->attrs->find(state.symbols.create("startSet"));
     if (startSet == args[0]->attrs->end())
         throw EvalError(format("attribute `startSet' required, at %1%") % pos);
-    state.forceList(*startSet->value);
+    state.forceList(*startSet->value, pos);
 
     ValueList workSet;
     for (unsigned int n = 0; n < startSet->value->list.length; ++n)
@@ -234,7 +234,7 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar
         /* Call the `operator' function with `e' as argument. */
         Value call;
         mkApp(call, *op->value, *e);
-        state.forceList(call);
+        state.forceList(call, pos);
 
         /* Add the values returned by the operator to the work set. */
         for (unsigned int n = 0; n < call.list.length; ++n) {
@@ -381,7 +381,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
             /* The `args' attribute is special: it supplies the
                command-line arguments to the builder. */
             if (key == "args") {
-                state.forceList(*i->value);
+                state.forceList(*i->value, pos);
                 for (unsigned int n = 0; n < i->value->list.length; ++n) {
                     string s = state.coerceToString(*i->value->list.elems[n], context, true);
                     drv.args.push_back(s);
@@ -821,7 +821,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.forceList(*args[1]);
+    state.forceList(*args[1], pos);
 
     /* Get the attribute names to be removed. */
     std::set<Symbol> names;
@@ -848,7 +848,7 @@ static void prim_removeAttrs(EvalState & state, const Pos & pos, Value * * args,
    name, the first takes precedence. */
 static void prim_listToAttrs(EvalState & state, const Pos & pos, Value * * args, Value & v)
 {
-    state.forceList(*args[0]);
+    state.forceList(*args[0], pos);
 
     state.mkAttrs(v, args[0]->list.length);
 
@@ -943,7 +943,7 @@ static void prim_isList(EvalState & state, const Pos & pos, Value * * args, Valu
 
 static void elemAt(EvalState & state, const Pos & pos, Value & list, int n, Value & v)
 {
-    state.forceList(list);
+    state.forceList(list, pos);
     if (n < 0 || n >= list.list.length)
         throw Error(format("list index %1% is out of bounds, at %2%") % n % pos);
     state.forceValue(*list.list.elems[n]);
@@ -970,7 +970,7 @@ static void prim_head(EvalState & state, const Pos & pos, Value * * args, Value
    don't want to use it!  */
 static void prim_tail(EvalState & state, const Pos & pos, Value * * args, Value & v)
 {
-    state.forceList(*args[0]);
+    state.forceList(*args[0], pos);
     if (args[0]->list.length == 0)
         throw Error(format("`tail' called on an empty list, at %1%") % pos);
     state.mkList(v, args[0]->list.length - 1);
@@ -982,8 +982,8 @@ static void prim_tail(EvalState & state, const Pos & pos, Value * * args, Value
 /* Apply a function to every element of a list. */
 static void prim_map(EvalState & state, const Pos & pos, Value * * args, Value & v)
 {
-    state.forceFunction(*args[0]);
-    state.forceList(*args[1]);
+    state.forceFunction(*args[0], pos);
+    state.forceList(*args[1], pos);
 
     state.mkList(v, args[1]->list.length);
 
@@ -998,8 +998,8 @@ static void prim_map(EvalState & state, const Pos & pos, Value * * args, Value &
    returns true. */
 static void prim_filter(EvalState & state, const Pos & pos, Value * * args, Value & v)
 {
-    state.forceFunction(*args[0]);
-    state.forceList(*args[1]);
+    state.forceFunction(*args[0], pos);
+    state.forceList(*args[1], pos);
 
     // FIXME: putting this on the stack is risky.
     Value * vs[args[1]->list.length];
@@ -1028,7 +1028,7 @@ static void prim_filter(EvalState & state, const Pos & pos, Value * * args, Valu
 static void prim_elem(EvalState & state, const Pos & pos, Value * * args, Value & v)
 {
     bool res = false;
-    state.forceList(*args[1]);
+    state.forceList(*args[1], pos);
     for (unsigned int n = 0; n < args[1]->list.length; ++n)
         if (state.eqValues(*args[0], *args[1]->list.elems[n])) {
             res = true;
@@ -1041,7 +1041,7 @@ static void prim_elem(EvalState & state, const Pos & pos, Value * * args, Value
 /* Concatenate a list of lists. */
 static void prim_concatLists(EvalState & state, const Pos & pos, Value * * args, Value & v)
 {
-    state.forceList(*args[0]);
+    state.forceList(*args[0], pos);
     state.concatLists(v, args[0]->list.length, args[0]->list.elems);
 }
 
@@ -1049,7 +1049,7 @@ static void prim_concatLists(EvalState & state, const Pos & pos, Value * * args,
 /* Return the length of a list.  This is an O(1) time operation. */
 static void prim_length(EvalState & state, const Pos & pos, Value * * args, Value & v)
 {
-    state.forceList(*args[0]);
+    state.forceList(*args[0], pos);
     mkInt(v, args[0]->list.length);
 }