aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/eval-inline.hh12
-rw-r--r--src/libexpr/eval.cc18
-rw-r--r--src/libexpr/nixexpr.hh1
3 files changed, 17 insertions, 14 deletions
diff --git a/src/libexpr/eval-inline.hh b/src/libexpr/eval-inline.hh
index a988fa40c..c37b1d62b 100644
--- a/src/libexpr/eval-inline.hh
+++ b/src/libexpr/eval-inline.hh
@@ -103,8 +103,10 @@ void EvalState::forceValue(Value & v, Callable getPos)
throw;
}
}
- else if (v.isApp())
- callFunction(*v.app.left, *v.app.right, v, noPos);
+ else if (v.isApp()) {
+ PosIdx pos = getPos();
+ callFunction(*v.app.left, *v.app.right, v, pos);
+ }
else if (v.isBlackhole())
error("infinite recursion encountered").atPos(getPos()).template debugThrow<EvalError>();
}
@@ -121,9 +123,9 @@ template <typename Callable>
[[gnu::always_inline]]
inline void EvalState::forceAttrs(Value & v, Callable getPos, std::string_view errorCtx)
{
- forceValue(v, noPos);
+ PosIdx pos = getPos();
+ forceValue(v, pos);
if (v.type() != nAttrs) {
- PosIdx pos = getPos();
error("value is %1% while a set was expected", showType(v)).withTrace(pos, errorCtx).debugThrow<TypeError>();
}
}
@@ -132,7 +134,7 @@ inline void EvalState::forceAttrs(Value & v, Callable getPos, std::string_view e
[[gnu::always_inline]]
inline void EvalState::forceList(Value & v, const PosIdx pos, std::string_view errorCtx)
{
- forceValue(v, noPos);
+ forceValue(v, pos);
if (!v.isList()) {
error("value is %1% while a list was expected", showType(v)).withTrace(pos, errorCtx).debugThrow<TypeError>();
}
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index d414db79b..1817ebf55 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -341,7 +341,7 @@ static Symbol getName(const AttrName & name, EvalState & state, Env & env)
} else {
Value nameValue;
name.expr->eval(state, env, nameValue);
- state.forceStringNoCtx(nameValue, noPos, "while evaluating an attribute name");
+ state.forceStringNoCtx(nameValue, name.expr->getPos(), "while evaluating an attribute name");
return state.symbols.create(nameValue.string.s);
}
}
@@ -1503,7 +1503,7 @@ void ExprOpHasAttr::eval(EvalState & state, Env & env, Value & v)
e->eval(state, env, vTmp);
for (auto & i : attrPath) {
- state.forceValue(*vAttrs, noPos);
+ state.forceValue(*vAttrs, getPos());
Bindings::iterator j;
auto name = getName(i, state, env);
if (vAttrs->type() != nAttrs ||
@@ -1672,7 +1672,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
if (countCalls) primOpCalls[name]++;
try {
- vCur.primOp->fun(*this, noPos, args, vCur);
+ vCur.primOp->fun(*this, vCur.determinePos(noPos), args, vCur);
} catch (Error & e) {
addErrorTrace(e, pos, "while calling the '%1%' builtin", name);
throw;
@@ -1720,7 +1720,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
// 1. Unify this and above code. Heavily redundant.
// 2. Create a fake env (arg1, arg2, etc.) and a fake expr (arg1: arg2: etc: builtins.name arg1 arg2 etc)
// so the debugger allows to inspect the wrong parameters passed to the builtin.
- primOp->primOp->fun(*this, noPos, vArgs, vCur);
+ primOp->primOp->fun(*this, vCur.determinePos(noPos), vArgs, vCur);
} catch (Error & e) {
addErrorTrace(e, pos, "while calling the '%1%' builtin", name);
throw;
@@ -1828,7 +1828,7 @@ https://nixos.org/manual/nix/stable/language/constructs.html#functions.)", symbo
}
}
- callFunction(fun, allocValue()->mkAttrs(attrs), res, noPos);
+ callFunction(fun, allocValue()->mkAttrs(attrs), res, pos);
}
@@ -1864,7 +1864,7 @@ void ExprAssert::eval(EvalState & state, Env & env, Value & v)
void ExprOpNot::eval(EvalState & state, Env & env, Value & v)
{
- v.mkBool(!state.evalBool(env, e, noPos, "in the argument of the not operator")); // XXX: FIXME: !
+ v.mkBool(!state.evalBool(env, e, getPos(), "in the argument of the not operator")); // XXX: FIXME: !
}
@@ -2305,7 +2305,7 @@ BackedStringView EvalState::coerceToString(
std::string result;
for (auto [n, v2] : enumerate(v.listItems())) {
try {
- result += *coerceToString(noPos, *v2, context,
+ result += *coerceToString(pos, *v2, context,
"while evaluating one element of the list",
coerceMore, copyToStore, canonicalizePath);
} catch (Error & e) {
@@ -2428,8 +2428,8 @@ SingleDerivedPath EvalState::coerceToSingleDerivedPath(const PosIdx pos, Value &
bool EvalState::eqValues(Value & v1, Value & v2, const PosIdx pos, std::string_view errorCtx)
{
- forceValue(v1, noPos);
- forceValue(v2, noPos);
+ forceValue(v1, pos);
+ forceValue(v2, pos);
/* !!! Hack to support some old broken code that relies on pointer
equality tests between sets. (Specifically, builderDefs calls
diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh
index 944977e50..120de7d97 100644
--- a/src/libexpr/nixexpr.hh
+++ b/src/libexpr/nixexpr.hh
@@ -400,6 +400,7 @@ struct ExprOpNot : Expr
{
Expr * e;
ExprOpNot(Expr * e) : e(e) { };
+ PosIdx getPos() const override { return e->getPos(); }
COMMON_METHODS
};