aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libexpr/primops.cc70
1 files changed, 44 insertions, 26 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 7f3c298ba..e03f811b8 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -556,15 +556,29 @@ static Bindings::iterator extractAttrNameFromPrimopCall(
) {
Bindings::iterator value = attrSet->find(state.symbols.create(attrName));
if (value == attrSet->end()) {
- auto e = TypeError({
- .msg = hintfmt("attribute '%s' missing for call to '%s'", attrName, funcName),
- .errPos = *attrSet->pos,
- });
+ hintformat errorMsg = hintfmt(
+ "attribute '%s' missing for call to '%s'",
+ attrName,
+ funcName
+ );
- // Adding another trace for the function name to make it clear
- // which call received wrong arguments.
- e.addTrace(pos, hintfmt("while invoking '%s'", funcName));
- throw e;
+ Pos aPos = *attrSet->pos;
+ if (aPos == noPos) {
+ throw TypeError({
+ .msg = errorMsg,
+ .errPos = pos,
+ });
+ } else {
+ auto e = TypeError({
+ .msg = errorMsg,
+ .errPos = aPos,
+ });
+
+ // Adding another trace for the function name to make it clear
+ // which call received wrong arguments.
+ e.addTrace(pos, hintfmt("while invoking '%s'", funcName));
+ throw e;
+ }
}
return value;
@@ -841,12 +855,14 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
state.forceAttrs(*args[0], pos);
/* Figure out the name first (for stack backtraces). */
- Bindings::iterator attr = args[0]->attrs->find(state.sName);
- if (attr == args[0]->attrs->end())
- throw EvalError({
- .msg = hintfmt("required attribute 'name' missing"),
- .errPos = pos
- });
+ Bindings::iterator attr = extractAttrNameFromPrimopCall(
+ state,
+ "derivationStrict",
+ state.sName,
+ args[0]->attrs,
+ pos
+ );
+
string drvName;
Pos & posDrvName(*attr->pos);
try {
@@ -1394,12 +1410,13 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va
if (i != v2.attrs->end())
prefix = state.forceStringNoCtx(*i->value, pos);
- i = v2.attrs->find(state.symbols.create("path"));
- if (i == v2.attrs->end())
- throw EvalError({
- .msg = hintfmt("attribute 'path' missing"),
- .errPos = pos
- });
+ i = extractAttrNameFromPrimopCall(
+ state,
+ "findFile",
+ "path",
+ v2.attrs,
+ pos
+ );
PathSet context;
string path = state.coerceToString(pos, *i->value, context, false, false);
@@ -2041,12 +2058,13 @@ void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v)
string attr = state.forceStringNoCtx(*args[0], pos);
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())
- throw EvalError({
- .msg = hintfmt("attribute '%1%' missing", attr),
- .errPos = pos
- });
+ Bindings::iterator i = extractAttrNameFromPrimopCall(
+ state,
+ "getAttr",
+ attr,
+ args[1]->attrs,
+ pos
+ );
// !!! add to stack trace?
if (state.countCalls && i->pos) state.attrSelects[*i->pos]++;
state.forceValue(*i->value, pos);