summaryrefslogtreecommitdiffstats
path: root/src/libexpr/eval.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2020-06-17 10:26:52 +0200
committerEelco Dolstra <edolstra@gmail.com>2020-06-17 10:26:52 +0200
commit1524752c17ee8753467f068c23fbe1d994aa8f75 (patch)
treec802ca482e2461765dcbdcef5cc6fa38c9d1c42b /src/libexpr/eval.cc
parent7db879e65e83b1c65206b490d36a69e97c5a877a (diff)
parent29542865cee37ab22efe1bd142900b69f6c59f0d (diff)
Merge remote-tracking branch 'origin/master' into flakes
Diffstat (limited to 'src/libexpr/eval.cc')
-rw-r--r--src/libexpr/eval.cc106
1 files changed, 65 insertions, 41 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 266ddff75..6a7106cc3 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -538,52 +538,74 @@ Value & EvalState::getBuiltin(const string & name)
LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2))
{
- throw EvalError(format(s) % s2);
+ throw EvalError(s, s2);
}
-LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const Pos & pos))
+LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2))
{
- throw EvalError(format(s) % s2 % pos);
+ throw EvalError({
+ .hint = hintfmt(s, s2),
+ .nixCode = NixCode { .errPos = pos }
+ });
}
LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3))
{
- throw EvalError(format(s) % s2 % s3);
+ throw EvalError(s, s2, s3);
}
-LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3, const Pos & pos))
+LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, const string & s3))
{
- throw EvalError(format(s) % s2 % s3 % pos);
+ throw EvalError({
+ .hint = hintfmt(s, s2, s3),
+ .nixCode = NixCode { .errPos = pos }
+ });
}
-LocalNoInlineNoReturn(void throwEvalError(const char * s, const Symbol & sym, const Pos & p1, const Pos & p2))
+LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const Symbol & sym, const Pos & p2))
{
- throw EvalError(format(s) % sym % p1 % p2);
+ // p1 is where the error occurred; p2 is a position mentioned in the message.
+ throw EvalError({
+ .hint = hintfmt(s, sym, p2),
+ .nixCode = NixCode { .errPos = p1 }
+ });
}
-LocalNoInlineNoReturn(void throwTypeError(const char * s, const Pos & pos))
+LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s))
{
- throw TypeError(format(s) % pos);
+ throw TypeError({
+ .hint = hintfmt(s),
+ .nixCode = NixCode { .errPos = pos }
+ });
}
LocalNoInlineNoReturn(void throwTypeError(const char * s, const string & s1))
{
- throw TypeError(format(s) % s1);
+ throw TypeError(s, s1);
}
-LocalNoInlineNoReturn(void throwTypeError(const char * s, const ExprLambda & fun, const Symbol & s2, const Pos & pos))
+LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2))
{
- throw TypeError(format(s) % fun.showNamePos() % s2 % pos);
+ throw TypeError({
+ .hint = hintfmt(s, fun.showNamePos(), s2),
+ .nixCode = NixCode { .errPos = pos }
+ });
}
-LocalNoInlineNoReturn(void throwAssertionError(const char * s, const string & s1, const Pos & pos))
+LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, const string & s1))
{
- throw AssertionError(format(s) % s1 % pos);
+ throw AssertionError({
+ .hint = hintfmt(s, s1),
+ .nixCode = NixCode { .errPos = pos }
+ });
}
-LocalNoInlineNoReturn(void throwUndefinedVarError(const char * s, const string & s1, const Pos & pos))
+LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * s, const string & s1))
{
- throw UndefinedVarError(format(s) % s1 % pos);
+ throw UndefinedVarError({
+ .hint = hintfmt(s, s1),
+ .nixCode = NixCode { .errPos = pos }
+ });
}
LocalNoInline(void addErrorPrefix(Error & e, const char * s, const string & s2))
@@ -651,7 +673,7 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval)
return j->value;
}
if (!env->prevWith)
- throwUndefinedVarError("undefined variable '%1%' at %2%", var.name, var.pos);
+ throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name);
for (size_t l = env->prevWith; l; --l, env = env->up) ;
}
}
@@ -854,7 +876,7 @@ inline bool EvalState::evalBool(Env & env, Expr * e, const Pos & pos)
Value v;
e->eval(*this, env, v);
if (v.type != tBool)
- throwTypeError("value is %1% while a Boolean was expected, at %2%", v, pos);
+ throwTypeError(pos, "value is %1% while a Boolean was expected", v);
return v.boolean;
}
@@ -968,7 +990,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
Symbol nameSym = state.symbols.create(nameVal.string.s);
Bindings::iterator j = v.attrs->find(nameSym);
if (j != v.attrs->end())
- throwEvalError("dynamic attribute '%1%' at %2% already defined at %3%", nameSym, i.pos, *j->pos);
+ throwEvalError(i.pos, "dynamic attribute '%1%' already defined at %2%", nameSym, *j->pos);
i.valueExpr->setName(nameSym);
/* Keep sorted order so find can catch duplicates */
@@ -1056,7 +1078,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
} else {
state.forceAttrs(*vAttrs, pos);
if ((j = vAttrs->attrs->find(name)) == vAttrs->attrs->end())
- throwEvalError("attribute '%1%' missing, at %2%", name, pos);
+ throwEvalError(pos, "attribute '%1%' missing", name);
}
vAttrs = j->value;
pos2 = j->pos;
@@ -1182,7 +1204,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po
}
if (fun.type != tLambda)
- throwTypeError("attempt to call something which is not a function but %1%, at %2%", fun, pos);
+ throwTypeError(pos, "attempt to call something which is not a function but %1%", fun);
ExprLambda & lambda(*fun.lambda.fun);
@@ -1210,8 +1232,8 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po
for (auto & i : lambda.formals->formals) {
Bindings::iterator j = arg.attrs->find(i.name);
if (j == arg.attrs->end()) {
- if (!i.def) throwTypeError("%1% called without required argument '%2%', at %3%",
- lambda, i.name, pos);
+ if (!i.def) throwTypeError(pos, "%1% called without required argument '%2%'",
+ lambda, i.name);
env2.values[displ++] = i.def->maybeThunk(*this, env2);
} else {
attrsUsed++;
@@ -1226,7 +1248,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po
user. */
for (auto & i : *arg.attrs)
if (lambda.formals->argNames.find(i.name) == lambda.formals->argNames.end())
- throwTypeError("%1% called with unexpected argument '%2%', at %3%", lambda, i.name, pos);
+ throwTypeError(pos, "%1% called with unexpected argument '%2%'", lambda, i.name);
abort(); // can't happen
}
}
@@ -1315,7 +1337,7 @@ void ExprAssert::eval(EvalState & state, Env & env, Value & v)
if (!state.evalBool(env, cond, pos)) {
std::ostringstream out;
cond->show(out);
- throwAssertionError("assertion '%1%' failed at %2%", out.str(), pos);
+ throwAssertionError(pos, "assertion '%1%' failed at %2%", out.str());
}
body->eval(state, env, v);
}
@@ -1467,14 +1489,14 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
nf = n;
nf += vTmp.fpoint;
} else
- throwEvalError("cannot add %1% to an integer, at %2%", showType(vTmp), pos);
+ throwEvalError(pos, "cannot add %1% to an integer", showType(vTmp));
} else if (firstType == tFloat) {
if (vTmp.type == tInt) {
nf += vTmp.integer;
} else if (vTmp.type == tFloat) {
nf += vTmp.fpoint;
} else
- throwEvalError("cannot add %1% to a float, at %2%", showType(vTmp), pos);
+ throwEvalError(pos, "cannot add %1% to a float", showType(vTmp));
} else
s << state.coerceToString(pos, vTmp, context, false, firstType == tString);
}
@@ -1485,7 +1507,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
mkFloat(v, nf);
else if (firstType == tPath) {
if (!context.empty())
- throwEvalError("a string that refers to a store path cannot be appended to a path, at %1%", pos);
+ throwEvalError(pos, "a string that refers to a store path cannot be appended to a path");
auto path = canonPath(s.str());
mkPath(v, path.c_str());
} else
@@ -1534,7 +1556,7 @@ NixInt EvalState::forceInt(Value & v, const Pos & pos)
{
forceValue(v, pos);
if (v.type != tInt)
- throwTypeError("value is %1% while an integer was expected, at %2%", v, pos);
+ throwTypeError(pos, "value is %1% while an integer was expected", v);
return v.integer;
}
@@ -1545,7 +1567,7 @@ NixFloat EvalState::forceFloat(Value & v, const Pos & pos)
if (v.type == tInt)
return v.integer;
else if (v.type != tFloat)
- throwTypeError("value is %1% while a float was expected, at %2%", v, pos);
+ throwTypeError(pos, "value is %1% while a float was expected", v);
return v.fpoint;
}
@@ -1554,7 +1576,7 @@ bool EvalState::forceBool(Value & v, const Pos & pos)
{
forceValue(v, pos);
if (v.type != tBool)
- throwTypeError("value is %1% while a Boolean was expected, at %2%", v, pos);
+ throwTypeError(pos, "value is %1% while a Boolean was expected", v);
return v.boolean;
}
@@ -1569,7 +1591,7 @@ void EvalState::forceFunction(Value & v, const Pos & pos)
{
forceValue(v, pos);
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(pos, "value is %1% while a function was expected", v);
}
@@ -1578,7 +1600,7 @@ string EvalState::forceString(Value & v, const Pos & pos)
forceValue(v, pos);
if (v.type != tString) {
if (pos)
- throwTypeError("value is %1% while a string was expected, at %2%", v, pos);
+ throwTypeError(pos, "value is %1% while a string was expected", v);
else
throwTypeError("value is %1% while a string was expected", v);
}
@@ -1607,8 +1629,8 @@ string EvalState::forceStringNoCtx(Value & v, const Pos & pos)
string s = forceString(v, pos);
if (v.string.context) {
if (pos)
- throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%'), at %3%",
- v.string.s, v.string.context[0], pos);
+ throwEvalError(pos, "the string '%1%' is not allowed to refer to a store path (such as '%2%')",
+ v.string.s, v.string.context[0]);
else
throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')",
v.string.s, v.string.context[0]);
@@ -1664,7 +1686,7 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context,
return *maybeString;
}
auto i = v.attrs->find(sOutPath);
- if (i == v.attrs->end()) throwTypeError("cannot coerce a set to a string, at %1%", pos);
+ if (i == v.attrs->end()) throwTypeError(pos, "cannot coerce a set to a string");
return coerceToString(pos, *i->value, context, coerceMore, copyToStore);
}
@@ -1695,7 +1717,7 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context,
}
}
- throwTypeError("cannot coerce %1% to a string, at %2%", v, pos);
+ throwTypeError(pos, "cannot coerce %1% to a string", v);
}
@@ -1726,7 +1748,7 @@ Path EvalState::coerceToPath(const Pos & pos, Value & v, PathSet & context)
{
string path = coerceToString(pos, v, context, false, false);
if (path == "" || path[0] != '/')
- throwEvalError("string '%1%' doesn't represent an absolute path, at %2%", path, pos);
+ throwEvalError(pos, "string '%1%' doesn't represent an absolute path", path);
return path;
}
@@ -1933,8 +1955,10 @@ void EvalState::printStats()
string ExternalValueBase::coerceToString(const Pos & pos, PathSet & context, bool copyMore, bool copyToStore) const
{
- throw TypeError(format("cannot coerce %1% to a string, at %2%") %
- showType() % pos);
+ throw TypeError({
+ .hint = hintfmt("cannot coerce %1% to a string", showType()),
+ .nixCode = NixCode { .errPos = pos }
+ });
}