pass Pos to forceValue to improve infinite recursion error
This commit is contained in:
parent
2f9789c2e6
commit
b865b5b40c
|
@ -57,7 +57,7 @@ inline void EvalState::forceAttrs(Value & v)
|
||||||
|
|
||||||
inline void EvalState::forceAttrs(Value & v, const Pos & pos)
|
inline void EvalState::forceAttrs(Value & v, const Pos & pos)
|
||||||
{
|
{
|
||||||
forceValue(v);
|
forceValue(v, pos);
|
||||||
if (v.type != tAttrs)
|
if (v.type != tAttrs)
|
||||||
throwTypeError("value is %1% while a set was expected, at %2%", v, pos);
|
throwTypeError("value is %1% while a set was expected, at %2%", v, pos);
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ inline void EvalState::forceList(Value & v)
|
||||||
|
|
||||||
inline void EvalState::forceList(Value & v, const Pos & pos)
|
inline void EvalState::forceList(Value & v, const Pos & pos)
|
||||||
{
|
{
|
||||||
forceValue(v);
|
forceValue(v, pos);
|
||||||
if (!v.isList())
|
if (!v.isList())
|
||||||
throwTypeError("value is %1% while a list was expected, at %2%", v, pos);
|
throwTypeError("value is %1% while a list was expected, at %2%", v, pos);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1502,7 +1502,7 @@ NixFloat EvalState::forceFloat(Value & v, const Pos & pos)
|
||||||
|
|
||||||
bool EvalState::forceBool(Value & v, const Pos & pos)
|
bool EvalState::forceBool(Value & v, const Pos & pos)
|
||||||
{
|
{
|
||||||
forceValue(v);
|
forceValue(v, pos);
|
||||||
if (v.type != tBool)
|
if (v.type != tBool)
|
||||||
throwTypeError("value is %1% while a Boolean was expected, at %2%", v, pos);
|
throwTypeError("value is %1% while a Boolean was expected, at %2%", v, pos);
|
||||||
return v.boolean;
|
return v.boolean;
|
||||||
|
@ -1517,7 +1517,7 @@ bool EvalState::isFunctor(Value & fun)
|
||||||
|
|
||||||
void EvalState::forceFunction(Value & v, const Pos & pos)
|
void EvalState::forceFunction(Value & v, const Pos & pos)
|
||||||
{
|
{
|
||||||
forceValue(v);
|
forceValue(v, pos);
|
||||||
if (v.type != tLambda && v.type != tPrimOp && v.type != tPrimOpApp && !isFunctor(v))
|
if (v.type != tLambda && v.type != tPrimOp && v.type != tPrimOpApp && !isFunctor(v))
|
||||||
throwTypeError("value is %1% while a function was expected, at %2%", v, pos);
|
throwTypeError("value is %1% while a function was expected, at %2%", v, pos);
|
||||||
}
|
}
|
||||||
|
@ -1594,7 +1594,7 @@ std::optional<string> EvalState::tryAttrsToString(const Pos & pos, Value & v,
|
||||||
string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context,
|
string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context,
|
||||||
bool coerceMore, bool copyToStore)
|
bool coerceMore, bool copyToStore)
|
||||||
{
|
{
|
||||||
forceValue(v);
|
forceValue(v, pos);
|
||||||
|
|
||||||
string s;
|
string s;
|
||||||
|
|
||||||
|
|
|
@ -241,7 +241,7 @@ void prim_exec(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
/* Return a string representing the type of the expression. */
|
/* Return a string representing the type of the expression. */
|
||||||
static void prim_typeOf(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_typeOf(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0], pos);
|
||||||
string t;
|
string t;
|
||||||
switch (args[0]->type) {
|
switch (args[0]->type) {
|
||||||
case tInt: t = "int"; break;
|
case tInt: t = "int"; break;
|
||||||
|
@ -269,7 +269,7 @@ static void prim_typeOf(EvalState & state, const Pos & pos, Value * * args, Valu
|
||||||
/* Determine whether the argument is the null value. */
|
/* Determine whether the argument is the null value. */
|
||||||
static void prim_isNull(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_isNull(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0], pos);
|
||||||
mkBool(v, args[0]->type == tNull);
|
mkBool(v, args[0]->type == tNull);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,7 +277,7 @@ static void prim_isNull(EvalState & state, const Pos & pos, Value * * args, Valu
|
||||||
/* Determine whether the argument is a function. */
|
/* Determine whether the argument is a function. */
|
||||||
static void prim_isFunction(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_isFunction(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0], pos);
|
||||||
bool res;
|
bool res;
|
||||||
switch (args[0]->type) {
|
switch (args[0]->type) {
|
||||||
case tLambda:
|
case tLambda:
|
||||||
|
@ -296,21 +296,21 @@ static void prim_isFunction(EvalState & state, const Pos & pos, Value * * args,
|
||||||
/* Determine whether the argument is an integer. */
|
/* Determine whether the argument is an integer. */
|
||||||
static void prim_isInt(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_isInt(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0], pos);
|
||||||
mkBool(v, args[0]->type == tInt);
|
mkBool(v, args[0]->type == tInt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine whether the argument is a float. */
|
/* Determine whether the argument is a float. */
|
||||||
static void prim_isFloat(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_isFloat(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0], pos);
|
||||||
mkBool(v, args[0]->type == tFloat);
|
mkBool(v, args[0]->type == tFloat);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine whether the argument is a string. */
|
/* Determine whether the argument is a string. */
|
||||||
static void prim_isString(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_isString(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0], pos);
|
||||||
mkBool(v, args[0]->type == tString);
|
mkBool(v, args[0]->type == tString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,14 +318,14 @@ static void prim_isString(EvalState & state, const Pos & pos, Value * * args, Va
|
||||||
/* Determine whether the argument is a Boolean. */
|
/* Determine whether the argument is a Boolean. */
|
||||||
static void prim_isBool(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_isBool(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0], pos);
|
||||||
mkBool(v, args[0]->type == tBool);
|
mkBool(v, args[0]->type == tBool);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine whether the argument is a path. */
|
/* Determine whether the argument is a path. */
|
||||||
static void prim_isPath(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_isPath(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0], pos);
|
||||||
mkBool(v, args[0]->type == tPath);
|
mkBool(v, args[0]->type == tPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,7 +382,7 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar
|
||||||
args[0]->attrs->find(state.symbols.create("operator"));
|
args[0]->attrs->find(state.symbols.create("operator"));
|
||||||
if (op == args[0]->attrs->end())
|
if (op == args[0]->attrs->end())
|
||||||
throw EvalError(format("attribute 'operator' required, at %1%") % pos);
|
throw EvalError(format("attribute 'operator' required, at %1%") % pos);
|
||||||
state.forceValue(*op->value);
|
state.forceValue(*op->value, pos);
|
||||||
|
|
||||||
/* Construct the closure by applying the operator to element of
|
/* Construct the closure by applying the operator to element of
|
||||||
`workSet', adding the result to `workSet', continuing until
|
`workSet', adding the result to `workSet', continuing until
|
||||||
|
@ -401,7 +401,7 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar
|
||||||
e->attrs->find(state.symbols.create("key"));
|
e->attrs->find(state.symbols.create("key"));
|
||||||
if (key == e->attrs->end())
|
if (key == e->attrs->end())
|
||||||
throw EvalError(format("attribute 'key' required, at %1%") % pos);
|
throw EvalError(format("attribute 'key' required, at %1%") % pos);
|
||||||
state.forceValue(*key->value);
|
state.forceValue(*key->value, pos);
|
||||||
|
|
||||||
if (!doneKeys.insert(key->value).second) continue;
|
if (!doneKeys.insert(key->value).second) continue;
|
||||||
res.push_back(e);
|
res.push_back(e);
|
||||||
|
@ -413,7 +413,7 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar
|
||||||
|
|
||||||
/* Add the values returned by the operator to the work set. */
|
/* Add the values returned by the operator to the work set. */
|
||||||
for (unsigned int n = 0; n < call.listSize(); ++n) {
|
for (unsigned int n = 0; n < call.listSize(); ++n) {
|
||||||
state.forceValue(*call.listElems()[n]);
|
state.forceValue(*call.listElems()[n], pos);
|
||||||
workSet.push_back(call.listElems()[n]);
|
workSet.push_back(call.listElems()[n]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -445,7 +445,7 @@ static void prim_throw(EvalState & state, const Pos & pos, Value * * args, Value
|
||||||
static void prim_addErrorContext(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_addErrorContext(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
state.forceValue(*args[1]);
|
state.forceValue(*args[1], pos);
|
||||||
v = *args[1];
|
v = *args[1];
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
PathSet context;
|
PathSet context;
|
||||||
|
@ -461,7 +461,7 @@ static void prim_tryEval(EvalState & state, const Pos & pos, Value * * args, Val
|
||||||
{
|
{
|
||||||
state.mkAttrs(v, 2);
|
state.mkAttrs(v, 2);
|
||||||
try {
|
try {
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0], pos);
|
||||||
v.attrs->push_back(Attr(state.sValue, args[0]));
|
v.attrs->push_back(Attr(state.sValue, args[0]));
|
||||||
mkBool(*state.allocAttr(v, state.symbols.create("success")), true);
|
mkBool(*state.allocAttr(v, state.symbols.create("success")), true);
|
||||||
} catch (AssertionError & e) {
|
} catch (AssertionError & e) {
|
||||||
|
@ -483,8 +483,8 @@ static void prim_getEnv(EvalState & state, const Pos & pos, Value * * args, Valu
|
||||||
/* Evaluate the first argument, then return the second argument. */
|
/* Evaluate the first argument, then return the second argument. */
|
||||||
static void prim_seq(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_seq(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0], pos);
|
||||||
state.forceValue(*args[1]);
|
state.forceValue(*args[1], pos);
|
||||||
v = *args[1];
|
v = *args[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,7 +494,7 @@ static void prim_seq(EvalState & state, const Pos & pos, Value * * args, Value &
|
||||||
static void prim_deepSeq(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_deepSeq(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValueDeep(*args[0]);
|
state.forceValueDeep(*args[0]);
|
||||||
state.forceValue(*args[1]);
|
state.forceValue(*args[1], pos);
|
||||||
v = *args[1];
|
v = *args[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -503,12 +503,12 @@ static void prim_deepSeq(EvalState & state, const Pos & pos, Value * * args, Val
|
||||||
return the second expression. Useful for debugging. */
|
return the second expression. Useful for debugging. */
|
||||||
static void prim_trace(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_trace(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0], pos);
|
||||||
if (args[0]->type == tString)
|
if (args[0]->type == tString)
|
||||||
printError(format("trace: %1%") % args[0]->string.s);
|
printError(format("trace: %1%") % args[0]->string.s);
|
||||||
else
|
else
|
||||||
printError(format("trace: %1%") % *args[0]);
|
printError(format("trace: %1%") % *args[0]);
|
||||||
state.forceValue(*args[1]);
|
state.forceValue(*args[1], pos);
|
||||||
v = *args[1];
|
v = *args[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -599,7 +599,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if (ignoreNulls) {
|
if (ignoreNulls) {
|
||||||
state.forceValue(*i->value);
|
state.forceValue(*i->value, pos);
|
||||||
if (i->value->type == tNull) continue;
|
if (i->value->type == tNull) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1092,7 +1092,7 @@ static void prim_filterSource(EvalState & state, const Pos & pos, Value * * args
|
||||||
if (!context.empty())
|
if (!context.empty())
|
||||||
throw EvalError(format("string '%1%' cannot refer to other paths, at %2%") % path % pos);
|
throw EvalError(format("string '%1%' cannot refer to other paths, at %2%") % path % pos);
|
||||||
|
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0], pos);
|
||||||
if (args[0]->type != tLambda)
|
if (args[0]->type != tLambda)
|
||||||
throw TypeError(format("first argument in call to 'filterSource' is not a function but %1%, at %2%") % showType(*args[0]) % pos);
|
throw TypeError(format("first argument in call to 'filterSource' is not a function but %1%, at %2%") % showType(*args[0]) % pos);
|
||||||
|
|
||||||
|
@ -1118,7 +1118,7 @@ static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value
|
||||||
} else if (attr.name == state.sName)
|
} else if (attr.name == state.sName)
|
||||||
name = state.forceStringNoCtx(*attr.value, *attr.pos);
|
name = state.forceStringNoCtx(*attr.value, *attr.pos);
|
||||||
else if (n == "filter") {
|
else if (n == "filter") {
|
||||||
state.forceValue(*attr.value);
|
state.forceValue(*attr.value, pos);
|
||||||
filterFun = attr.value;
|
filterFun = attr.value;
|
||||||
} else if (n == "recursive")
|
} else if (n == "recursive")
|
||||||
recursive = state.forceBool(*attr.value, *attr.pos);
|
recursive = state.forceBool(*attr.value, *attr.pos);
|
||||||
|
@ -1189,7 +1189,7 @@ void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
throw EvalError(format("attribute '%1%' missing, at %2%") % attr % pos);
|
throw EvalError(format("attribute '%1%' missing, at %2%") % attr % pos);
|
||||||
// !!! add to stack trace?
|
// !!! add to stack trace?
|
||||||
if (state.countCalls && i->pos) state.attrSelects[*i->pos]++;
|
if (state.countCalls && i->pos) state.attrSelects[*i->pos]++;
|
||||||
state.forceValue(*i->value);
|
state.forceValue(*i->value, pos);
|
||||||
v = *i->value;
|
v = *i->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1219,7 +1219,7 @@ static void prim_hasAttr(EvalState & state, const Pos & pos, Value * * args, Val
|
||||||
/* Determine whether the argument is a set. */
|
/* Determine whether the argument is a set. */
|
||||||
static void prim_isAttrs(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_isAttrs(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0], pos);
|
||||||
mkBool(v, args[0]->type == tAttrs);
|
mkBool(v, args[0]->type == tAttrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1345,7 +1345,7 @@ static void prim_catAttrs(EvalState & state, const Pos & pos, Value * * args, Va
|
||||||
*/
|
*/
|
||||||
static void prim_functionArgs(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_functionArgs(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0], pos);
|
||||||
if (args[0]->type != tLambda)
|
if (args[0]->type != tLambda)
|
||||||
throw TypeError(format("'functionArgs' requires a function, at %1%") % pos);
|
throw TypeError(format("'functionArgs' requires a function, at %1%") % pos);
|
||||||
|
|
||||||
|
@ -1391,7 +1391,7 @@ static void prim_mapAttrs(EvalState & state, const Pos & pos, Value * * args, Va
|
||||||
/* Determine whether the argument is a list. */
|
/* Determine whether the argument is a list. */
|
||||||
static void prim_isList(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_isList(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0], pos);
|
||||||
mkBool(v, args[0]->isList());
|
mkBool(v, args[0]->isList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1401,7 +1401,7 @@ static void elemAt(EvalState & state, const Pos & pos, Value & list, int n, Valu
|
||||||
state.forceList(list, pos);
|
state.forceList(list, pos);
|
||||||
if (n < 0 || (unsigned int) n >= list.listSize())
|
if (n < 0 || (unsigned int) n >= list.listSize())
|
||||||
throw Error(format("list index %1% is out of bounds, at %2%") % n % pos);
|
throw Error(format("list index %1% is out of bounds, at %2%") % n % pos);
|
||||||
state.forceValue(*list.listElems()[n]);
|
state.forceValue(*list.listElems()[n], pos);
|
||||||
v = *list.listElems()[n];
|
v = *list.listElems()[n];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1524,9 +1524,9 @@ static void prim_foldlStrict(EvalState & state, const Pos & pos, Value * * args,
|
||||||
vCur = n == args[2]->listSize() - 1 ? &v : state.allocValue();
|
vCur = n == args[2]->listSize() - 1 ? &v : state.allocValue();
|
||||||
state.callFunction(vTmp, *args[2]->listElems()[n], *vCur, pos);
|
state.callFunction(vTmp, *args[2]->listElems()[n], *vCur, pos);
|
||||||
}
|
}
|
||||||
state.forceValue(v);
|
state.forceValue(v, pos);
|
||||||
} else {
|
} else {
|
||||||
state.forceValue(*args[1]);
|
state.forceValue(*args[1], pos);
|
||||||
v = *args[1];
|
v = *args[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1591,7 +1591,7 @@ static void prim_sort(EvalState & state, const Pos & pos, Value * * args, Value
|
||||||
auto len = args[1]->listSize();
|
auto len = args[1]->listSize();
|
||||||
state.mkList(v, len);
|
state.mkList(v, len);
|
||||||
for (unsigned int n = 0; n < len; ++n) {
|
for (unsigned int n = 0; n < len; ++n) {
|
||||||
state.forceValue(*args[1]->listElems()[n]);
|
state.forceValue(*args[1]->listElems()[n], pos);
|
||||||
v.listElems()[n] = args[1]->listElems()[n];
|
v.listElems()[n] = args[1]->listElems()[n];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1626,7 +1626,7 @@ static void prim_partition(EvalState & state, const Pos & pos, Value * * args, V
|
||||||
|
|
||||||
for (unsigned int n = 0; n < len; ++n) {
|
for (unsigned int n = 0; n < len; ++n) {
|
||||||
auto vElem = args[1]->listElems()[n];
|
auto vElem = args[1]->listElems()[n];
|
||||||
state.forceValue(*vElem);
|
state.forceValue(*vElem, pos);
|
||||||
Value res;
|
Value res;
|
||||||
state.callFunction(*args[0], *vElem, res, pos);
|
state.callFunction(*args[0], *vElem, res, pos);
|
||||||
if (state.forceBool(res, pos))
|
if (state.forceBool(res, pos))
|
||||||
|
@ -1757,8 +1757,8 @@ static void prim_bitXor(EvalState & state, const Pos & pos, Value * * args, Valu
|
||||||
|
|
||||||
static void prim_lessThan(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_lessThan(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0], pos);
|
||||||
state.forceValue(*args[1]);
|
state.forceValue(*args[1], pos);
|
||||||
CompareValues comp;
|
CompareValues comp;
|
||||||
mkBool(v, comp(args[0], args[1]));
|
mkBool(v, comp(args[0], args[1]));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue