libexpr: associate error creation and debugging with EvalContext
Change-Id: I80beedd0c58361ebc67cebcee97d64879baed050
This commit is contained in:
parent
2f2bc90d92
commit
d30027a37a
|
@ -56,7 +56,7 @@ std::pair<Value *, PosIdx> findAlongAttrPath(EvalState & state, const std::strin
|
|||
if (!attrIndex) {
|
||||
|
||||
if (v->type() != nAttrs)
|
||||
state.errors.make<TypeError>(
|
||||
state.ctx.errors.make<TypeError>(
|
||||
"the expression selected by the selection path '%1%' should be a set but is %2%",
|
||||
attrPath,
|
||||
showType(*v)).debugThrow();
|
||||
|
@ -79,7 +79,7 @@ std::pair<Value *, PosIdx> findAlongAttrPath(EvalState & state, const std::strin
|
|||
else {
|
||||
|
||||
if (!v->isList())
|
||||
state.errors.make<TypeError>(
|
||||
state.ctx.errors.make<TypeError>(
|
||||
"the expression selected by the selection path '%1%' should be a list but is %2%",
|
||||
attrPath,
|
||||
showType(*v)).debugThrow();
|
||||
|
|
|
@ -552,14 +552,14 @@ std::string AttrCursor::getString(EvalState & state)
|
|||
debug("using cached string attribute '%s'", getAttrPathStr(state));
|
||||
return s->first;
|
||||
} else
|
||||
state.errors.make<TypeError>("'%s' is not a string", getAttrPathStr(state)).debugThrow();
|
||||
state.ctx.errors.make<TypeError>("'%s' is not a string", getAttrPathStr(state)).debugThrow();
|
||||
}
|
||||
}
|
||||
|
||||
auto & v = forceValue(state);
|
||||
|
||||
if (v.type() != nString && v.type() != nPath) {
|
||||
state.errors.make<TypeError>("'%s' is not a string but %s", getAttrPathStr(state), v.type()).debugThrow();
|
||||
state.ctx.errors.make<TypeError>("'%s' is not a string but %s", getAttrPathStr(state), v.type()).debugThrow();
|
||||
}
|
||||
|
||||
return v.type() == nString ? v.string.s : v.path().to_string();
|
||||
|
@ -595,7 +595,7 @@ string_t AttrCursor::getStringWithContext(EvalState & state)
|
|||
return *s;
|
||||
}
|
||||
} else
|
||||
state.errors.make<TypeError>("'%s' is not a string", getAttrPathStr(state)).debugThrow();
|
||||
state.ctx.errors.make<TypeError>("'%s' is not a string", getAttrPathStr(state)).debugThrow();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -608,7 +608,7 @@ string_t AttrCursor::getStringWithContext(EvalState & state)
|
|||
} else if (v.type() == nPath) {
|
||||
return {v.path().to_string(), {}};
|
||||
} else {
|
||||
state.errors.make<TypeError>("'%s' is not a string but %s", getAttrPathStr(state), v.type()).debugThrow();
|
||||
state.ctx.errors.make<TypeError>("'%s' is not a string but %s", getAttrPathStr(state), v.type()).debugThrow();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -622,14 +622,14 @@ bool AttrCursor::getBool(EvalState & state)
|
|||
debug("using cached Boolean attribute '%s'", getAttrPathStr(state));
|
||||
return *b;
|
||||
} else
|
||||
state.errors.make<TypeError>("'%s' is not a Boolean", getAttrPathStr(state)).debugThrow();
|
||||
state.ctx.errors.make<TypeError>("'%s' is not a Boolean", getAttrPathStr(state)).debugThrow();
|
||||
}
|
||||
}
|
||||
|
||||
auto & v = forceValue(state);
|
||||
|
||||
if (v.type() != nBool)
|
||||
state.errors.make<TypeError>("'%s' is not a Boolean", getAttrPathStr(state)).debugThrow();
|
||||
state.ctx.errors.make<TypeError>("'%s' is not a Boolean", getAttrPathStr(state)).debugThrow();
|
||||
|
||||
return v.boolean;
|
||||
}
|
||||
|
@ -644,14 +644,14 @@ NixInt AttrCursor::getInt(EvalState & state)
|
|||
debug("using cached integer attribute '%s'", getAttrPathStr(state));
|
||||
return i->x;
|
||||
} else
|
||||
state.errors.make<TypeError>("'%s' is not an integer", getAttrPathStr(state)).debugThrow();
|
||||
state.ctx.errors.make<TypeError>("'%s' is not an integer", getAttrPathStr(state)).debugThrow();
|
||||
}
|
||||
}
|
||||
|
||||
auto & v = forceValue(state);
|
||||
|
||||
if (v.type() != nInt)
|
||||
state.errors.make<TypeError>("'%s' is not an integer", getAttrPathStr(state)).debugThrow();
|
||||
state.ctx.errors.make<TypeError>("'%s' is not an integer", getAttrPathStr(state)).debugThrow();
|
||||
|
||||
return v.integer;
|
||||
}
|
||||
|
@ -666,7 +666,7 @@ std::vector<std::string> AttrCursor::getListOfStrings(EvalState & state)
|
|||
debug("using cached list of strings attribute '%s'", getAttrPathStr(state));
|
||||
return *l;
|
||||
} else
|
||||
state.errors.make<TypeError>("'%s' is not a list of strings", getAttrPathStr(state)).debugThrow();
|
||||
state.ctx.errors.make<TypeError>("'%s' is not a list of strings", getAttrPathStr(state)).debugThrow();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -676,7 +676,7 @@ std::vector<std::string> AttrCursor::getListOfStrings(EvalState & state)
|
|||
state.forceValue(v, noPos);
|
||||
|
||||
if (v.type() != nList)
|
||||
state.errors.make<TypeError>("'%s' is not a list", getAttrPathStr(state)).debugThrow();
|
||||
state.ctx.errors.make<TypeError>("'%s' is not a list", getAttrPathStr(state)).debugThrow();
|
||||
|
||||
std::vector<std::string> res;
|
||||
|
||||
|
@ -699,14 +699,14 @@ std::vector<std::string> AttrCursor::getAttrs(EvalState & state)
|
|||
debug("using cached attrset attribute '%s'", getAttrPathStr(state));
|
||||
return attrs->p;
|
||||
} else
|
||||
state.errors.make<TypeError>("'%s' is not an attribute set", getAttrPathStr(state)).debugThrow();
|
||||
state.ctx.errors.make<TypeError>("'%s' is not an attribute set", getAttrPathStr(state)).debugThrow();
|
||||
}
|
||||
}
|
||||
|
||||
auto & v = forceValue(state);
|
||||
|
||||
if (v.type() != nAttrs)
|
||||
state.errors.make<TypeError>("'%s' is not an attribute set", getAttrPathStr(state)).debugThrow();
|
||||
state.ctx.errors.make<TypeError>("'%s' is not an attribute set", getAttrPathStr(state)).debugThrow();
|
||||
|
||||
fullattr_t attrs;
|
||||
for (auto & attr : *getValue(state).attrs)
|
||||
|
|
|
@ -91,7 +91,7 @@ inline void EvalState::forceAttrs(Value & v, const PosIdx pos, std::string_view
|
|||
{
|
||||
forceValue(v, pos);
|
||||
if (v.type() != nAttrs) {
|
||||
errors.make<TypeError>(
|
||||
ctx.errors.make<TypeError>(
|
||||
"expected a set but found %1%: %2%",
|
||||
showType(v),
|
||||
ValuePrinter(*this, v, errorPrintOptions)
|
||||
|
@ -105,7 +105,7 @@ inline void EvalState::forceList(Value & v, const PosIdx pos, std::string_view e
|
|||
{
|
||||
forceValue(v, pos);
|
||||
if (!v.isList()) {
|
||||
errors.make<TypeError>(
|
||||
ctx.errors.make<TypeError>(
|
||||
"expected a list but found %1%: %2%",
|
||||
showType(v),
|
||||
ValuePrinter(*this, v, errorPrintOptions)
|
||||
|
|
|
@ -618,7 +618,7 @@ void printEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env &
|
|||
void printEnvBindings(const EvalState &es, const Expr & expr, const Env & env)
|
||||
{
|
||||
// just print the names for now
|
||||
auto se = es.debug->staticEnvFor(expr);
|
||||
auto se = es.ctx.debug->staticEnvFor(expr);
|
||||
if (se)
|
||||
printEnvBindings(es.ctx.symbols, *se, env, 0);
|
||||
}
|
||||
|
@ -739,15 +739,15 @@ static DebugState::TraceFrame makeDebugTraceStacker(
|
|||
std::shared_ptr<Pos> && pos,
|
||||
const Args & ... formatArgs)
|
||||
{
|
||||
auto trace = state.debug->addTrace(DebugTrace{
|
||||
auto trace = state.ctx.debug->addTrace(DebugTrace{
|
||||
.pos = std::move(pos),
|
||||
.expr = expr,
|
||||
.env = env,
|
||||
.hint = HintFmt(formatArgs...),
|
||||
.isError = false,
|
||||
});
|
||||
if (state.debug->stop && state.debug->errorCallback)
|
||||
state.debug->onEvalError(nullptr, env, expr);
|
||||
if (state.ctx.debug->stop && state.ctx.debug->errorCallback)
|
||||
state.ctx.debug->onEvalError(nullptr, env, expr);
|
||||
return trace;
|
||||
}
|
||||
|
||||
|
@ -771,7 +771,7 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval)
|
|||
return j->value;
|
||||
}
|
||||
if (!fromWith->parentWith)
|
||||
errors.make<UndefinedVarError>("undefined variable '%1%'", ctx.symbols[var.name]).atPos(var.pos).withFrame(*env, var).debugThrow();
|
||||
ctx.errors.make<UndefinedVarError>("undefined variable '%1%'", ctx.symbols[var.name]).atPos(var.pos).withFrame(*env, var).debugThrow();
|
||||
for (size_t l = fromWith->prevWith; l; --l, env = env->up) ;
|
||||
fromWith = fromWith->parentWith;
|
||||
}
|
||||
|
@ -956,7 +956,7 @@ void EvalState::evalFile(const SourcePath & path_, Value & v)
|
|||
Expr & e = parseExprFromFile(paths.checkSourcePath(resolvedPath));
|
||||
|
||||
try {
|
||||
auto dts = debug
|
||||
auto dts = ctx.debug
|
||||
? makeDebugTraceStacker(
|
||||
*this,
|
||||
e,
|
||||
|
@ -995,7 +995,7 @@ inline bool EvalState::evalBool(Env & env, Expr & e, const PosIdx pos, std::stri
|
|||
Value v;
|
||||
e.eval(*this, env, v);
|
||||
if (v.type() != nBool)
|
||||
errors.make<TypeError>(
|
||||
ctx.errors.make<TypeError>(
|
||||
"expected a Boolean but found %1%: %2%",
|
||||
showType(v),
|
||||
ValuePrinter(*this, v, errorPrintOptions)
|
||||
|
@ -1013,7 +1013,7 @@ inline void EvalState::evalAttrs(Env & env, Expr & e, Value & v, const PosIdx po
|
|||
try {
|
||||
e.eval(*this, env, v);
|
||||
if (v.type() != nAttrs)
|
||||
errors.make<TypeError>(
|
||||
ctx.errors.make<TypeError>(
|
||||
"expected a set but found %1%: %2%",
|
||||
showType(v),
|
||||
ValuePrinter(*this, v, errorPrintOptions)
|
||||
|
@ -1146,7 +1146,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
|||
auto nameSym = state.ctx.symbols.create(nameVal.string.s);
|
||||
Bindings::iterator j = v.attrs->find(nameSym);
|
||||
if (j != v.attrs->end())
|
||||
state.errors.make<EvalError>("dynamic attribute '%1%' already defined at %2%", state.ctx.symbols[nameSym], state.ctx.positions[j->pos]).atPos(i.pos).withFrame(env, *this).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("dynamic attribute '%1%' already defined at %2%", state.ctx.symbols[nameSym], state.ctx.positions[j->pos]).atPos(i.pos).withFrame(env, *this).debugThrow();
|
||||
|
||||
i.valueExpr->setName(nameSym);
|
||||
/* Keep sorted order so find can catch duplicates */
|
||||
|
@ -1177,7 +1177,7 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v)
|
|||
*i.second.chooseByKind(&env2, &env, inheritEnv));
|
||||
}
|
||||
|
||||
auto dts = state.debug
|
||||
auto dts = state.ctx.debug
|
||||
? makeDebugTraceStacker(
|
||||
state,
|
||||
*this,
|
||||
|
@ -1261,7 +1261,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
|||
}
|
||||
|
||||
try {
|
||||
auto dts = state.debug
|
||||
auto dts = state.ctx.debug
|
||||
? makeDebugTraceStacker(
|
||||
state,
|
||||
*this,
|
||||
|
@ -1321,7 +1321,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
|||
}
|
||||
|
||||
// Otherwise, we must type error.
|
||||
state.errors.make<TypeError>(
|
||||
state.ctx.errors.make<TypeError>(
|
||||
"expected a set but found %s: %s",
|
||||
showType(*vCurrent),
|
||||
ValuePrinter(state, *vCurrent, errorPrintOptions)
|
||||
|
@ -1348,7 +1348,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
|||
allAttrNames.insert(state.ctx.symbols[attr.name]);
|
||||
}
|
||||
auto suggestions = Suggestions::bestMatches(allAttrNames, state.ctx.symbols[name]);
|
||||
state.errors.make<EvalError>("attribute '%s' missing", state.ctx.symbols[name])
|
||||
state.ctx.errors.make<EvalError>("attribute '%s' missing", state.ctx.symbols[name])
|
||||
.atPos(pos)
|
||||
.withSuggestions(suggestions)
|
||||
.withFrame(env, *this)
|
||||
|
@ -1484,7 +1484,7 @@ FormalsMatch matchupFormals(EvalState & state, Env & env, Displacement & displ,
|
|||
void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & vRes, const PosIdx pos)
|
||||
{
|
||||
if (callDepth > evalSettings.maxCallDepth)
|
||||
errors.make<EvalError>("stack overflow; max-call-depth exceeded").atPos(pos).debugThrow();
|
||||
ctx.errors.make<EvalError>("stack overflow; max-call-depth exceeded").atPos(pos).debugThrow();
|
||||
CallDepth _level(callDepth);
|
||||
|
||||
auto trace = evalSettings.traceFunctionCalls
|
||||
|
@ -1546,7 +1546,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
|||
);
|
||||
for (auto const & missingArg : formalsMatch.missing) {
|
||||
auto const missing = ctx.symbols[missingArg];
|
||||
errors.make<TypeError>("function '%s' called without required argument '%s'", lambda.getName(ctx.symbols), missing)
|
||||
ctx.errors.make<TypeError>("function '%s' called without required argument '%s'", lambda.getName(ctx.symbols), missing)
|
||||
.atPos(lambda.pos)
|
||||
.withTrace(pos, "from call site")
|
||||
.withFrame(*fun.lambda.env, lambda)
|
||||
|
@ -1559,7 +1559,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
|||
formalNames.insert(ctx.symbols[formal.name]);
|
||||
}
|
||||
auto sug = Suggestions::bestMatches(formalNames, unex);
|
||||
errors.make<TypeError>("function '%s' called with unexpected argument '%s'", lambda.getName(ctx.symbols), unex)
|
||||
ctx.errors.make<TypeError>("function '%s' called with unexpected argument '%s'", lambda.getName(ctx.symbols), unex)
|
||||
.atPos(lambda.pos)
|
||||
.withTrace(pos, "from call site")
|
||||
.withSuggestions(sug)
|
||||
|
@ -1575,7 +1575,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
|||
|
||||
/* Evaluate the body. */
|
||||
try {
|
||||
auto dts = debug
|
||||
auto dts = ctx.debug
|
||||
? makeDebugTraceStacker(
|
||||
*this, *lambda.body, env2, ctx.positions[lambda.pos],
|
||||
"while calling %s",
|
||||
|
@ -1700,7 +1700,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
|||
}
|
||||
|
||||
else
|
||||
errors.make<TypeError>(
|
||||
ctx.errors.make<TypeError>(
|
||||
"attempt to call something which is not a function but %1%: %2%",
|
||||
showType(vCur),
|
||||
ValuePrinter(*this, vCur, errorPrintOptions))
|
||||
|
@ -1714,7 +1714,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
|||
|
||||
void ExprCall::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
auto dts = state.debug
|
||||
auto dts = state.ctx.debug
|
||||
? makeDebugTraceStacker(
|
||||
state,
|
||||
*this,
|
||||
|
@ -1787,7 +1787,7 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res)
|
|||
if (j != args.end()) {
|
||||
attrs.insert(*j);
|
||||
} else if (!i.def) {
|
||||
errors.make<MissingArgumentError>(R"(cannot evaluate a function that has an argument without a value ('%1%')
|
||||
ctx.errors.make<MissingArgumentError>(R"(cannot evaluate a function that has an argument without a value ('%1%')
|
||||
Nix attempted to evaluate a function as a top level expression; in
|
||||
this case it must have its arguments supplied either by default
|
||||
values, or passed explicitly with '--arg' or '--argstr'. See
|
||||
|
@ -1823,7 +1823,7 @@ void ExprAssert::eval(EvalState & state, Env & env, Value & v)
|
|||
if (!state.evalBool(env, *cond, pos, "in the condition of the assert statement")) {
|
||||
std::ostringstream out;
|
||||
cond->show(state.ctx.symbols, out);
|
||||
state.errors.make<AssertionError>("assertion '%1%' failed", out.str()).atPos(pos).withFrame(env, *this).debugThrow();
|
||||
state.ctx.errors.make<AssertionError>("assertion '%1%' failed", out.str()).atPos(pos).withFrame(env, *this).debugThrow();
|
||||
}
|
||||
body->eval(state, env, v);
|
||||
}
|
||||
|
@ -1998,7 +1998,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
|
|||
if (auto checked = newN.valueChecked(); checked.has_value()) {
|
||||
n = NixInt(*checked);
|
||||
} else {
|
||||
state.errors.make<EvalError>("integer overflow in adding %1% + %2%", n, vTmp.integer).atPos(i_pos).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("integer overflow in adding %1% + %2%", n, vTmp.integer).atPos(i_pos).debugThrow();
|
||||
}
|
||||
} else if (vTmp.type() == nFloat) {
|
||||
// Upgrade the type from int to float;
|
||||
|
@ -2006,14 +2006,14 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
|
|||
nf = n.value;
|
||||
nf += vTmp.fpoint;
|
||||
} else
|
||||
state.errors.make<EvalError>("cannot add %1% to an integer", showType(vTmp)).atPos(i_pos).withFrame(env, *this).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("cannot add %1% to an integer", showType(vTmp)).atPos(i_pos).withFrame(env, *this).debugThrow();
|
||||
} else if (firstType == nFloat) {
|
||||
if (vTmp.type() == nInt) {
|
||||
nf += vTmp.integer.value;
|
||||
} else if (vTmp.type() == nFloat) {
|
||||
nf += vTmp.fpoint;
|
||||
} else
|
||||
state.errors.make<EvalError>("cannot add %1% to a float", showType(vTmp)).atPos(i_pos).withFrame(env, *this).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("cannot add %1% to a float", showType(vTmp)).atPos(i_pos).withFrame(env, *this).debugThrow();
|
||||
} else {
|
||||
if (s.empty()) s.reserve(es.size());
|
||||
/* skip canonization of first path, which would only be not
|
||||
|
@ -2035,7 +2035,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
|
|||
v.mkFloat(nf);
|
||||
else if (firstType == nPath) {
|
||||
if (!context.empty())
|
||||
state.errors.make<EvalError>("a string that refers to a store path cannot be appended to a path").atPos(pos).withFrame(env, *this).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("a string that refers to a store path cannot be appended to a path").atPos(pos).withFrame(env, *this).debugThrow();
|
||||
v.mkPath(CanonPath(canonPath(str())));
|
||||
} else
|
||||
v.mkStringMove(c_str(), context);
|
||||
|
@ -2050,7 +2050,7 @@ void ExprPos::eval(EvalState & state, Env & env, Value & v)
|
|||
|
||||
void ExprBlackHole::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
state.errors.make<InfiniteRecursionError>("infinite recursion encountered")
|
||||
state.ctx.errors.make<InfiniteRecursionError>("infinite recursion encountered")
|
||||
.atPos(v.determinePos(noPos))
|
||||
.debugThrow();
|
||||
}
|
||||
|
@ -2087,7 +2087,7 @@ void EvalState::forceValueDeep(Value & v)
|
|||
for (auto & i : *v.attrs)
|
||||
try {
|
||||
// If the value is a thunk, we're evaling. Otherwise no trace necessary.
|
||||
auto dts = debug && i.value->isThunk()
|
||||
auto dts = ctx.debug && i.value->isThunk()
|
||||
? makeDebugTraceStacker(*this, *i.value->thunk.expr, *i.value->thunk.env, ctx.positions[i.pos],
|
||||
"while evaluating the attribute '%1%'", ctx.symbols[i.name])
|
||||
: nullptr;
|
||||
|
@ -2114,7 +2114,7 @@ NixInt EvalState::forceInt(Value & v, const PosIdx pos, std::string_view errorCt
|
|||
try {
|
||||
forceValue(v, pos);
|
||||
if (v.type() != nInt)
|
||||
errors.make<TypeError>(
|
||||
ctx.errors.make<TypeError>(
|
||||
"expected an integer but found %1%: %2%",
|
||||
showType(v),
|
||||
ValuePrinter(*this, v, errorPrintOptions)
|
||||
|
@ -2136,7 +2136,7 @@ NixFloat EvalState::forceFloat(Value & v, const PosIdx pos, std::string_view err
|
|||
if (v.type() == nInt)
|
||||
return v.integer.value;
|
||||
else if (v.type() != nFloat)
|
||||
errors.make<TypeError>(
|
||||
ctx.errors.make<TypeError>(
|
||||
"expected a float but found %1%: %2%",
|
||||
showType(v),
|
||||
ValuePrinter(*this, v, errorPrintOptions)
|
||||
|
@ -2154,7 +2154,7 @@ bool EvalState::forceBool(Value & v, const PosIdx pos, std::string_view errorCtx
|
|||
try {
|
||||
forceValue(v, pos);
|
||||
if (v.type() != nBool)
|
||||
errors.make<TypeError>(
|
||||
ctx.errors.make<TypeError>(
|
||||
"expected a Boolean but found %1%: %2%",
|
||||
showType(v),
|
||||
ValuePrinter(*this, v, errorPrintOptions)
|
||||
|
@ -2180,7 +2180,7 @@ void EvalState::forceFunction(Value & v, const PosIdx pos, std::string_view erro
|
|||
try {
|
||||
forceValue(v, pos);
|
||||
if (v.type() != nFunction && !isFunctor(v))
|
||||
errors.make<TypeError>(
|
||||
ctx.errors.make<TypeError>(
|
||||
"expected a function but found %1%: %2%",
|
||||
showType(v),
|
||||
ValuePrinter(*this, v, errorPrintOptions)
|
||||
|
@ -2197,7 +2197,7 @@ std::string_view EvalState::forceString(Value & v, const PosIdx pos, std::string
|
|||
try {
|
||||
forceValue(v, pos);
|
||||
if (v.type() != nString)
|
||||
errors.make<TypeError>(
|
||||
ctx.errors.make<TypeError>(
|
||||
"expected a string but found %1%: %2%",
|
||||
showType(v),
|
||||
ValuePrinter(*this, v, errorPrintOptions)
|
||||
|
@ -2230,7 +2230,7 @@ std::string_view EvalState::forceStringNoCtx(Value & v, const PosIdx pos, std::s
|
|||
{
|
||||
auto s = forceString(v, pos, errorCtx);
|
||||
if (v.string.context) {
|
||||
errors.make<EvalError>("the string '%1%' is not allowed to refer to a store path (such as '%2%')", v.string.s, v.string.context[0]).withTrace(pos, errorCtx).debugThrow();
|
||||
ctx.errors.make<EvalError>("the string '%1%' is not allowed to refer to a store path (such as '%2%')", v.string.s, v.string.context[0]).withTrace(pos, errorCtx).debugThrow();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
@ -2295,7 +2295,7 @@ BackedStringView EvalState::coerceToString(
|
|||
return std::move(*maybeString);
|
||||
auto i = v.attrs->find(ctx.s.outPath);
|
||||
if (i == v.attrs->end()) {
|
||||
errors.make<TypeError>(
|
||||
ctx.errors.make<TypeError>(
|
||||
"cannot coerce %1% to a string: %2%",
|
||||
showType(v),
|
||||
ValuePrinter(*this, v, errorPrintOptions)
|
||||
|
@ -2345,7 +2345,7 @@ BackedStringView EvalState::coerceToString(
|
|||
}
|
||||
}
|
||||
|
||||
errors.make<TypeError>("cannot coerce %1% to a string: %2%",
|
||||
ctx.errors.make<TypeError>("cannot coerce %1% to a string: %2%",
|
||||
showType(v),
|
||||
ValuePrinter(*this, v, errorPrintOptions)
|
||||
)
|
||||
|
@ -2382,7 +2382,7 @@ SourcePath EvalState::coerceToPath(const PosIdx pos, Value & v, NixStringContext
|
|||
{
|
||||
auto path = coerceToString(pos, v, context, errorCtx, false, false, true).toOwned();
|
||||
if (path == "" || path[0] != '/')
|
||||
errors.make<EvalError>("string '%1%' doesn't represent an absolute path", path).withTrace(pos, errorCtx).debugThrow();
|
||||
ctx.errors.make<EvalError>("string '%1%' doesn't represent an absolute path", path).withTrace(pos, errorCtx).debugThrow();
|
||||
return CanonPath(path);
|
||||
}
|
||||
|
||||
|
@ -2392,7 +2392,7 @@ StorePath EvalState::coerceToStorePath(const PosIdx pos, Value & v, NixStringCon
|
|||
auto path = coerceToString(pos, v, context, errorCtx, false, false, true).toOwned();
|
||||
if (auto storePath = store->maybeParseStorePath(path))
|
||||
return *storePath;
|
||||
errors.make<EvalError>("path '%1%' is not in the Nix store", path).withTrace(pos, errorCtx).debugThrow();
|
||||
ctx.errors.make<EvalError>("path '%1%' is not in the Nix store", path).withTrace(pos, errorCtx).debugThrow();
|
||||
}
|
||||
|
||||
|
||||
|
@ -2402,7 +2402,7 @@ std::pair<SingleDerivedPath, std::string_view> EvalState::coerceToSingleDerivedP
|
|||
auto s = forceString(v, context, pos, errorCtx);
|
||||
auto csize = context.size();
|
||||
if (csize != 1)
|
||||
errors.make<EvalError>(
|
||||
ctx.errors.make<EvalError>(
|
||||
"string '%s' has %d entries in its context. It should only have exactly one entry",
|
||||
s, csize)
|
||||
.withTrace(pos, errorCtx).debugThrow();
|
||||
|
@ -2411,7 +2411,7 @@ std::pair<SingleDerivedPath, std::string_view> EvalState::coerceToSingleDerivedP
|
|||
return std::move(o);
|
||||
},
|
||||
[&](NixStringContextElem::DrvDeep &&) -> SingleDerivedPath {
|
||||
errors.make<EvalError>(
|
||||
ctx.errors.make<EvalError>(
|
||||
"string '%s' has a context which refers to a complete source and binary closure. This is not supported at this time",
|
||||
s).withTrace(pos, errorCtx).debugThrow();
|
||||
},
|
||||
|
@ -2436,13 +2436,13 @@ SingleDerivedPath EvalState::coerceToSingleDerivedPath(const PosIdx pos, Value &
|
|||
error message. */
|
||||
std::visit(overloaded {
|
||||
[&](const SingleDerivedPath::Opaque & o) {
|
||||
errors.make<EvalError>(
|
||||
ctx.errors.make<EvalError>(
|
||||
"path string '%s' has context with the different path '%s'",
|
||||
s, sExpected)
|
||||
.withTrace(pos, errorCtx).debugThrow();
|
||||
},
|
||||
[&](const SingleDerivedPath::Built & b) {
|
||||
errors.make<EvalError>(
|
||||
ctx.errors.make<EvalError>(
|
||||
"string '%s' has context with the output '%s' from derivation '%s', but the string is not the right placeholder for this derivation output. It should be '%s'",
|
||||
s, b.output, b.drvPath->to_string(*store), sExpected)
|
||||
.withTrace(pos, errorCtx).debugThrow();
|
||||
|
@ -2527,7 +2527,7 @@ bool EvalState::eqValues(Value & v1, Value & v2, const PosIdx pos, std::string_v
|
|||
|
||||
case nThunk: // Must not be left by forceValue
|
||||
default:
|
||||
errors.make<EvalError>("cannot compare %1% with %2%", showType(v1), showType(v2)).withTrace(pos, errorCtx).debugThrow();
|
||||
ctx.errors.make<EvalError>("cannot compare %1% with %2%", showType(v1), showType(v2)).withTrace(pos, errorCtx).debugThrow();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2832,7 +2832,7 @@ std::optional<std::string> EvalPaths::resolveSearchPathPath(const SearchPath::Pa
|
|||
|
||||
std::string ExternalValueBase::coerceToString(EvalState & state, const PosIdx & pos, NixStringContext & context, bool copyMore, bool copyToStore) const
|
||||
{
|
||||
state.errors.make<TypeError>(
|
||||
state.ctx.errors.make<TypeError>(
|
||||
"cannot coerce %1% to a string: %2%", showType(), *this
|
||||
).atPos(pos).debugThrow();
|
||||
}
|
||||
|
|
|
@ -142,14 +142,14 @@ static FlakeInput parseFlakeInput(EvalState & state,
|
|||
auto intValue = attr.value->integer.value;
|
||||
|
||||
if (intValue < 0) {
|
||||
state.errors.make<EvalError>("negative value given for flake input attribute %1%: %2%", state.ctx.symbols[attr.name], intValue).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("negative value given for flake input attribute %1%: %2%", state.ctx.symbols[attr.name], intValue).debugThrow();
|
||||
}
|
||||
uint64_t asUnsigned = intValue;
|
||||
attrs.emplace(state.ctx.symbols[attr.name], asUnsigned);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
state.errors.make<TypeError>("flake input attribute '%s' is %s while a string, Boolean, or integer is expected",
|
||||
state.ctx.errors.make<TypeError>("flake input attribute '%s' is %s while a string, Boolean, or integer is expected",
|
||||
state.ctx.symbols[attr.name], showType(*attr.value)).debugThrow();
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
@ -247,7 +247,7 @@ static Flake getFlake(
|
|||
|
||||
// Enforce that 'flake.nix' is a direct attrset, not a computation.
|
||||
if (!(dynamic_cast<ExprAttrs *>(&flakeExpr))) {
|
||||
state.errors.make<EvalError>("file '%s' must be an attribute set", resolvedFlakeFile).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("file '%s' must be an attribute set", resolvedFlakeFile).debugThrow();
|
||||
}
|
||||
|
||||
Value vInfo;
|
||||
|
@ -307,14 +307,14 @@ static Flake getFlake(
|
|||
std::vector<std::string> ss;
|
||||
for (auto elem : setting.value->listItems()) {
|
||||
if (elem->type() != nString)
|
||||
state.errors.make<TypeError>("list element in flake configuration setting '%s' is %s while a string is expected",
|
||||
state.ctx.errors.make<TypeError>("list element in flake configuration setting '%s' is %s while a string is expected",
|
||||
state.ctx.symbols[setting.name], showType(*setting.value)).debugThrow();
|
||||
ss.emplace_back(state.forceStringNoCtx(*elem, setting.pos, ""));
|
||||
}
|
||||
flake.config.settings.emplace(state.ctx.symbols[setting.name], ss);
|
||||
}
|
||||
else
|
||||
state.errors.make<TypeError>("flake configuration setting '%s' is %s",
|
||||
state.ctx.errors.make<TypeError>("flake configuration setting '%s' is %s",
|
||||
state.ctx.symbols[setting.name], showType(*setting.value)).debugThrow();
|
||||
}
|
||||
}
|
||||
|
@ -858,7 +858,7 @@ void prim_flakeRefToString(
|
|||
auto intValue = attr.value->integer.value;
|
||||
|
||||
if (intValue < 0) {
|
||||
state.errors.make<EvalError>("negative value given for flake ref attr %1%: %2%", state.ctx.symbols[attr.name], intValue).atPos(pos).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("negative value given for flake ref attr %1%: %2%", state.ctx.symbols[attr.name], intValue).atPos(pos).debugThrow();
|
||||
}
|
||||
uint64_t asUnsigned = intValue;
|
||||
|
||||
|
@ -870,7 +870,7 @@ void prim_flakeRefToString(
|
|||
attrs.emplace(state.ctx.symbols[attr.name],
|
||||
std::string(attr.value->str()));
|
||||
} else {
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"flake reference attribute sets may only contain integers, Booleans, "
|
||||
"and strings, but attribute '%s' is %s",
|
||||
state.ctx.symbols[attr.name],
|
||||
|
|
|
@ -50,7 +50,7 @@ std::string DrvInfo::queryName(EvalState & state)
|
|||
{
|
||||
if (name == "" && attrs) {
|
||||
auto i = attrs->find(state.ctx.s.name);
|
||||
if (i == attrs->end()) state.errors.make<TypeError>("derivation name missing").debugThrow();
|
||||
if (i == attrs->end()) state.ctx.errors.make<TypeError>("derivation name missing").debugThrow();
|
||||
name = state.forceStringNoCtx(*i->value, noPos, "while evaluating the 'name' attribute of a derivation");
|
||||
}
|
||||
return name;
|
||||
|
@ -431,7 +431,7 @@ static void getDerivations(EvalState & state, Value & vIn,
|
|||
|
||||
return;
|
||||
} else if (v.type() != nAttrs) {
|
||||
state.errors.make<TypeError>(
|
||||
state.ctx.errors.make<TypeError>(
|
||||
"expression was expected to be a derivation or collection of derivations, but instead was %s",
|
||||
showType(v.type(), true)
|
||||
).debugThrow();
|
||||
|
|
|
@ -285,16 +285,16 @@ void prim_importNative(EvalState & state, const PosIdx pos, Value * * args, Valu
|
|||
|
||||
void *handle = dlopen(path.path.c_str(), RTLD_LAZY | RTLD_LOCAL);
|
||||
if (!handle)
|
||||
state.errors.make<EvalError>("could not open '%1%': %2%", path, dlerror()).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("could not open '%1%': %2%", path, dlerror()).debugThrow();
|
||||
|
||||
dlerror();
|
||||
ValueInitializer func = reinterpret_cast<ValueInitializer>(dlsym(handle, sym.c_str()));
|
||||
if(!func) {
|
||||
char *message = dlerror();
|
||||
if (message)
|
||||
state.errors.make<EvalError>("could not load symbol '%1%' from '%2%': %3%", sym, path, message).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("could not load symbol '%1%' from '%2%': %3%", sym, path, message).debugThrow();
|
||||
else
|
||||
state.errors.make<EvalError>("symbol '%1%' from '%2%' resolved to NULL when a function pointer was expected", sym, path).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("symbol '%1%' from '%2%' resolved to NULL when a function pointer was expected", sym, path).debugThrow();
|
||||
}
|
||||
|
||||
(func)(state, v);
|
||||
|
@ -310,7 +310,7 @@ void prim_exec(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
|||
auto elems = args[0]->listElems();
|
||||
auto count = args[0]->listSize();
|
||||
if (count == 0)
|
||||
state.errors.make<EvalError>("at least one argument to 'exec' required").atPos(pos).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("at least one argument to 'exec' required").atPos(pos).debugThrow();
|
||||
NixStringContext context;
|
||||
auto program = state.coerceToString(pos, *elems[0], context,
|
||||
"while evaluating the first element of the argument passed to builtins.exec",
|
||||
|
@ -452,7 +452,7 @@ struct CompareValues
|
|||
if (v1->type() == nInt && v2->type() == nFloat)
|
||||
return v1->integer.value < v2->fpoint;
|
||||
if (v1->type() != v2->type())
|
||||
state.errors.make<EvalError>("cannot compare %s with %s", showType(*v1), showType(*v2)).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("cannot compare %s with %s", showType(*v1), showType(*v2)).debugThrow();
|
||||
// Allow selecting a subset of enum values
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wswitch-enum"
|
||||
|
@ -477,7 +477,7 @@ struct CompareValues
|
|||
}
|
||||
}
|
||||
default:
|
||||
state.errors.make<EvalError>("cannot compare %s with %s; values of that type are incomparable", showType(*v1), showType(*v2)).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("cannot compare %s with %s; values of that type are incomparable", showType(*v1), showType(*v2)).debugThrow();
|
||||
#pragma GCC diagnostic pop
|
||||
}
|
||||
} catch (Error & e) {
|
||||
|
@ -503,7 +503,7 @@ static Bindings::iterator getAttr(
|
|||
{
|
||||
Bindings::iterator value = attrSet->find(attrSym);
|
||||
if (value == attrSet->end()) {
|
||||
state.errors.make<TypeError>("attribute '%s' missing", state.ctx.symbols[attrSym]).withTrace(noPos, errorCtx).debugThrow();
|
||||
state.ctx.errors.make<TypeError>("attribute '%s' missing", state.ctx.symbols[attrSym]).withTrace(noPos, errorCtx).debugThrow();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
@ -572,14 +572,14 @@ static void prim_genericClosure(EvalState & state, const PosIdx pos, Value * * a
|
|||
|
||||
static void prim_break(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||
{
|
||||
if (auto trace = state.debug ? state.debug->traces().next() : std::nullopt) {
|
||||
if (auto trace = state.ctx.debug ? state.ctx.debug->traces().next() : std::nullopt) {
|
||||
auto error = EvalError(ErrorInfo {
|
||||
.level = lvlInfo,
|
||||
.msg = HintFmt("breakpoint reached"),
|
||||
.pos = state.ctx.positions[pos],
|
||||
});
|
||||
|
||||
state.debug->onEvalError(&error, (*trace)->env, (*trace)->expr);
|
||||
state.ctx.debug->onEvalError(&error, (*trace)->env, (*trace)->expr);
|
||||
}
|
||||
|
||||
// Return the value we were passed.
|
||||
|
@ -591,7 +591,7 @@ static void prim_abort(EvalState & state, const PosIdx pos, Value * * args, Valu
|
|||
NixStringContext context;
|
||||
auto s = state.coerceToString(pos, *args[0], context,
|
||||
"while evaluating the error message passed to builtins.abort").toOwned();
|
||||
state.errors.make<Abort>("evaluation aborted with the following error message: '%1%'", s).debugThrow();
|
||||
state.ctx.errors.make<Abort>("evaluation aborted with the following error message: '%1%'", s).debugThrow();
|
||||
}
|
||||
|
||||
static void prim_throw(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||
|
@ -599,7 +599,7 @@ static void prim_throw(EvalState & state, const PosIdx pos, Value * * args, Valu
|
|||
NixStringContext context;
|
||||
auto s = state.coerceToString(pos, *args[0], context,
|
||||
"while evaluating the error message passed to builtin.throw").toOwned();
|
||||
state.errors.make<ThrownError>(s).debugThrow();
|
||||
state.ctx.errors.make<ThrownError>(s).debugThrow();
|
||||
}
|
||||
|
||||
static void prim_addErrorContext(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||
|
@ -644,11 +644,11 @@ static void prim_tryEval(EvalState & state, const PosIdx pos, Value * * args, Va
|
|||
|
||||
std::optional<MaintainCount<int>> trylevel;
|
||||
std::unique_ptr<DebugState> savedDebug;
|
||||
if (state.debug) {
|
||||
trylevel.emplace(state.debug->trylevel);
|
||||
if (state.ctx.debug) {
|
||||
trylevel.emplace(state.ctx.debug->trylevel);
|
||||
if (evalSettings.ignoreExceptionsDuringTry) {
|
||||
/* to prevent starting the repl from exceptions withing a tryEval, null it. */
|
||||
savedDebug = std::move(state.debug);
|
||||
savedDebug = std::move(state.ctx.debug);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -663,7 +663,7 @@ static void prim_tryEval(EvalState & state, const PosIdx pos, Value * * args, Va
|
|||
|
||||
// restore the debugRepl pointer if we saved it earlier.
|
||||
if (savedDebug)
|
||||
state.debug = std::move(savedDebug);
|
||||
state.ctx.debug = std::move(savedDebug);
|
||||
|
||||
v.mkAttrs(attrs);
|
||||
}
|
||||
|
@ -701,11 +701,11 @@ static void prim_trace(EvalState & state, const PosIdx pos, Value * * args, Valu
|
|||
printError("trace: %1%", args[0]->string.s);
|
||||
else
|
||||
printError("trace: %1%", ValuePrinter(state, *args[0]));
|
||||
if (auto last = evalSettings.builtinsTraceDebugger && state.debug
|
||||
? state.debug->traces().next()
|
||||
if (auto last = evalSettings.builtinsTraceDebugger && state.ctx.debug
|
||||
? state.ctx.debug->traces().next()
|
||||
: std::nullopt)
|
||||
{
|
||||
state.debug->onEvalError(nullptr, (*last)->env, (*last)->expr);
|
||||
state.ctx.debug->onEvalError(nullptr, (*last)->env, (*last)->expr);
|
||||
}
|
||||
state.forceValue(*args[1], pos);
|
||||
v = *args[1];
|
||||
|
@ -827,7 +827,7 @@ drvName, Bindings * attrs, Value & v)
|
|||
experimentalFeatureSettings.require(Xp::DynamicDerivations);
|
||||
ingestionMethod = TextIngestionMethod {};
|
||||
} else
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"invalid value '%s' for 'outputHashMode' attribute", s
|
||||
).atPos(v).debugThrow();
|
||||
};
|
||||
|
@ -836,7 +836,7 @@ drvName, Bindings * attrs, Value & v)
|
|||
outputs.clear();
|
||||
for (auto & j : ss) {
|
||||
if (outputs.find(j) != outputs.end())
|
||||
state.errors.make<EvalError>("duplicate derivation output '%1%'", j)
|
||||
state.ctx.errors.make<EvalError>("duplicate derivation output '%1%'", j)
|
||||
.atPos(v)
|
||||
.debugThrow();
|
||||
/* !!! Check whether j is a valid attribute
|
||||
|
@ -845,13 +845,13 @@ drvName, Bindings * attrs, Value & v)
|
|||
then we'd have an attribute ‘drvPath’ in
|
||||
the resulting set. */
|
||||
if (j == "drv")
|
||||
state.errors.make<EvalError>("invalid derivation output name 'drv'")
|
||||
state.ctx.errors.make<EvalError>("invalid derivation output name 'drv'")
|
||||
.atPos(v)
|
||||
.debugThrow();
|
||||
outputs.insert(j);
|
||||
}
|
||||
if (outputs.empty())
|
||||
state.errors.make<EvalError>("derivation cannot have an empty set of outputs")
|
||||
state.ctx.errors.make<EvalError>("derivation cannot have an empty set of outputs")
|
||||
.atPos(v)
|
||||
.debugThrow();
|
||||
};
|
||||
|
@ -989,12 +989,12 @@ drvName, Bindings * attrs, Value & v)
|
|||
|
||||
/* Do we have all required attributes? */
|
||||
if (drv.builder == "")
|
||||
state.errors.make<EvalError>("required attribute 'builder' missing")
|
||||
state.ctx.errors.make<EvalError>("required attribute 'builder' missing")
|
||||
.atPos(v)
|
||||
.debugThrow();
|
||||
|
||||
if (drv.platform == "")
|
||||
state.errors.make<EvalError>("required attribute 'system' missing")
|
||||
state.ctx.errors.make<EvalError>("required attribute 'system' missing")
|
||||
.atPos(v)
|
||||
.debugThrow();
|
||||
|
||||
|
@ -1004,7 +1004,7 @@ drvName, Bindings * attrs, Value & v)
|
|||
outputs.size() == 1 &&
|
||||
*(outputs.begin()) == "out"))
|
||||
{
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"derivation names are allowed to end in '%s' only if they produce a single derivation file",
|
||||
drvExtension
|
||||
).atPos(v).debugThrow();
|
||||
|
@ -1016,7 +1016,7 @@ drvName, Bindings * attrs, Value & v)
|
|||
Ignore `__contentAddressed` because fixed output derivations are
|
||||
already content addressed. */
|
||||
if (outputs.size() != 1 || *(outputs.begin()) != "out")
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"multiple outputs are not supported in fixed-output derivations"
|
||||
).atPos(v).debugThrow();
|
||||
|
||||
|
@ -1037,7 +1037,7 @@ drvName, Bindings * attrs, Value & v)
|
|||
|
||||
else if (contentAddressed || isImpure) {
|
||||
if (contentAddressed && isImpure)
|
||||
state.errors.make<EvalError>("derivation cannot be both content-addressed and impure")
|
||||
state.ctx.errors.make<EvalError>("derivation cannot be both content-addressed and impure")
|
||||
.atPos(v).debugThrow();
|
||||
|
||||
auto ht = parseHashTypeOpt(outputHashAlgo).value_or(HashType::SHA256);
|
||||
|
@ -1079,7 +1079,7 @@ drvName, Bindings * attrs, Value & v)
|
|||
for (auto & i : outputs) {
|
||||
auto h = get(hashModulo.hashes, i);
|
||||
if (!h)
|
||||
state.errors.make<AssertionError>(
|
||||
state.ctx.errors.make<AssertionError>(
|
||||
"derivation produced no hash for output '%s'",
|
||||
i
|
||||
).atPos(v).debugThrow();
|
||||
|
@ -1167,7 +1167,7 @@ static void prim_toPath(EvalState & state, const PosIdx pos, Value * * args, Val
|
|||
static void prim_storePath(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||
{
|
||||
if (evalSettings.pureEval)
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"'%s' is not allowed in pure evaluation mode",
|
||||
"builtins.storePath"
|
||||
).atPos(pos).debugThrow();
|
||||
|
@ -1180,7 +1180,7 @@ static void prim_storePath(EvalState & state, const PosIdx pos, Value * * args,
|
|||
if (!state.store->isStorePath(path.abs()))
|
||||
path = CanonPath(canonPath(path.abs(), true));
|
||||
if (!state.store->isInStore(path.abs()))
|
||||
state.errors.make<EvalError>("path '%1%' is not in the Nix store", path)
|
||||
state.ctx.errors.make<EvalError>("path '%1%' is not in the Nix store", path)
|
||||
.atPos(pos).debugThrow();
|
||||
auto path2 = state.store->toStorePath(path.abs()).first;
|
||||
if (!settings.readOnlyMode)
|
||||
|
@ -1258,7 +1258,7 @@ static void prim_readFile(EvalState & state, const PosIdx pos, Value * * args, V
|
|||
auto path = realisePath(state, pos, *args[0]);
|
||||
auto s = path.readFile();
|
||||
if (s.find((char) 0) != std::string::npos)
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"the contents of the file '%1%' cannot be represented as a Nix string",
|
||||
path
|
||||
).atPos(pos).debugThrow();
|
||||
|
@ -1309,7 +1309,7 @@ static void prim_findFile(EvalState & state, const PosIdx pos, Value * * args, V
|
|||
auto rewrites = state.paths.realiseContext(context);
|
||||
path = rewriteStrings(path, rewrites);
|
||||
} catch (InvalidPathError & e) {
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"cannot find '%1%', since path '%2%' is not valid",
|
||||
path,
|
||||
e.path
|
||||
|
@ -1333,7 +1333,7 @@ static void prim_hashFile(EvalState & state, const PosIdx pos, Value * * args, V
|
|||
auto type = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.hashFile");
|
||||
std::optional<HashType> ht = parseHashType(type);
|
||||
if (!ht)
|
||||
state.errors.make<EvalError>("unknown hash type '%1%'", type).atPos(pos).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("unknown hash type '%1%'", type).atPos(pos).debugThrow();
|
||||
|
||||
auto path = realisePath(state, pos, *args[1]);
|
||||
|
||||
|
@ -1462,7 +1462,7 @@ static void prim_toFile(EvalState & state, const PosIdx pos, Value * * args, Val
|
|||
if (auto p = std::get_if<NixStringContextElem::Opaque>(&c.raw))
|
||||
refs.insert(p->path);
|
||||
else
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"files created by %1% may not reference derivations, but %2% references %3%",
|
||||
"builtins.toFile",
|
||||
name,
|
||||
|
@ -1549,7 +1549,7 @@ static void addPath(
|
|||
auto dstPath = fetchToStore(
|
||||
*state.store, CanonPath(path), name, method, &filter, state.repair);
|
||||
if (expectedHash && expectedStorePath != dstPath)
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"store path mismatch in (possibly filtered) path added from '%s'",
|
||||
path
|
||||
).atPos(pos).debugThrow();
|
||||
|
@ -1596,13 +1596,13 @@ static void prim_path(EvalState & state, const PosIdx pos, Value * * args, Value
|
|||
else if (n == "sha256")
|
||||
expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, attr.pos, "while evaluating the `sha256` attribute passed to builtins.path"), HashType::SHA256);
|
||||
else
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"unsupported argument '%1%' to 'addPath'",
|
||||
state.ctx.symbols[attr.name]
|
||||
).atPos(attr.pos).debugThrow();
|
||||
}
|
||||
if (!path)
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"missing required 'path' attribute in the first argument to builtins.path"
|
||||
).atPos(pos).debugThrow();
|
||||
if (name.empty())
|
||||
|
@ -1909,7 +1909,7 @@ static void prim_functionArgs(EvalState & state, const PosIdx pos, Value * * arg
|
|||
return;
|
||||
}
|
||||
if (!args[0]->isLambda())
|
||||
state.errors.make<TypeError>("'functionArgs' requires a function").atPos(pos).debugThrow();
|
||||
state.ctx.errors.make<TypeError>("'functionArgs' requires a function").atPos(pos).debugThrow();
|
||||
|
||||
if (!args[0]->lambda.fun->hasFormals()) {
|
||||
v.mkAttrs(&Bindings::EMPTY);
|
||||
|
@ -2006,7 +2006,7 @@ static void elemAt(EvalState & state, const PosIdx pos, Value & list, int n, Val
|
|||
{
|
||||
state.forceList(list, pos, "while evaluating the first argument passed to builtins.elemAt");
|
||||
if (n < 0 || (unsigned int) n >= list.listSize())
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"list index %1% is out of bounds",
|
||||
n
|
||||
).atPos(pos).debugThrow();
|
||||
|
@ -2034,7 +2034,7 @@ static void prim_tail(EvalState & state, const PosIdx pos, Value * * args, Value
|
|||
{
|
||||
state.forceList(*args[0], pos, "while evaluating the first argument passed to builtins.tail");
|
||||
if (args[0]->listSize() == 0)
|
||||
state.errors.make<EvalError>("'tail' called on an empty list").atPos(pos).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("'tail' called on an empty list").atPos(pos).debugThrow();
|
||||
|
||||
v = state.mem.newList(args[0]->listSize() - 1);
|
||||
for (unsigned int n = 0; n < v.listSize(); ++n)
|
||||
|
@ -2181,7 +2181,7 @@ static void prim_genList(EvalState & state, const PosIdx pos, Value * * args, Va
|
|||
auto len_ = state.forceInt(*args[1], pos, "while evaluating the second argument passed to builtins.genList").value;
|
||||
|
||||
if (len_ < 0)
|
||||
state.errors.make<EvalError>("cannot create list of size %1%", len_).atPos(pos).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("cannot create list of size %1%", len_).atPos(pos).debugThrow();
|
||||
|
||||
size_t len = len_;
|
||||
|
||||
|
@ -2354,7 +2354,7 @@ static void prim_add(EvalState & state, const PosIdx pos, Value * * args, Value
|
|||
if (auto result = result_.valueChecked(); result.has_value()) {
|
||||
v.mkInt(*result);
|
||||
} else {
|
||||
state.errors.make<EvalError>("integer overflow in adding %1% + %2%", i1, i2).atPos(pos).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("integer overflow in adding %1% + %2%", i1, i2).atPos(pos).debugThrow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2375,7 +2375,7 @@ static void prim_sub(EvalState & state, const PosIdx pos, Value * * args, Value
|
|||
if (auto result = result_.valueChecked(); result.has_value()) {
|
||||
v.mkInt(*result);
|
||||
} else {
|
||||
state.errors.make<EvalError>("integer overflow in subtracting %1% - %2%", i1, i2).atPos(pos).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("integer overflow in subtracting %1% - %2%", i1, i2).atPos(pos).debugThrow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2396,7 +2396,7 @@ static void prim_mul(EvalState & state, const PosIdx pos, Value * * args, Value
|
|||
if (auto result = result_.valueChecked(); result.has_value()) {
|
||||
v.mkInt(*result);
|
||||
} else {
|
||||
state.errors.make<EvalError>("integer overflow in multiplying %1% * %2%", i1, i2).atPos(pos).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("integer overflow in multiplying %1% * %2%", i1, i2).atPos(pos).debugThrow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2408,7 +2408,7 @@ static void prim_div(EvalState & state, const PosIdx pos, Value * * args, Value
|
|||
|
||||
NixFloat f2 = state.forceFloat(*args[1], pos, "while evaluating the second operand of the division");
|
||||
if (f2 == 0)
|
||||
state.errors.make<EvalError>("division by zero").atPos(pos).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("division by zero").atPos(pos).debugThrow();
|
||||
|
||||
if (args[0]->type() == nFloat || args[1]->type() == nFloat) {
|
||||
v.mkFloat(state.forceFloat(*args[0], pos, "while evaluating the first operand of the division") / f2);
|
||||
|
@ -2420,7 +2420,7 @@ static void prim_div(EvalState & state, const PosIdx pos, Value * * args, Value
|
|||
if (auto result = result_.valueChecked(); result.has_value()) {
|
||||
v.mkInt(*result);
|
||||
} else {
|
||||
state.errors.make<EvalError>("integer overflow in dividing %1% / %2%", i1, i2).atPos(pos).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("integer overflow in dividing %1% / %2%", i1, i2).atPos(pos).debugThrow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2484,7 +2484,7 @@ static void prim_substring(EvalState & state, const PosIdx pos, Value * * args,
|
|||
NixInt::Inner start = state.forceInt(*args[0], pos, "while evaluating the first argument (the start offset) passed to builtins.substring").value;
|
||||
|
||||
if (start < 0)
|
||||
state.errors.make<EvalError>("negative start position in 'substring'").atPos(pos).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("negative start position in 'substring'").atPos(pos).debugThrow();
|
||||
|
||||
|
||||
NixInt::Inner len = state.forceInt(*args[1], pos, "while evaluating the second argument (the substring length) passed to builtins.substring").value;
|
||||
|
@ -2524,7 +2524,7 @@ static void prim_hashString(EvalState & state, const PosIdx pos, Value * * args,
|
|||
auto type = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.hashString");
|
||||
std::optional<HashType> ht = parseHashType(type);
|
||||
if (!ht)
|
||||
state.errors.make<EvalError>("unknown hash algorithm '%1%'", type).atPos(pos).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("unknown hash algorithm '%1%'", type).atPos(pos).debugThrow();
|
||||
|
||||
NixStringContext context; // discarded
|
||||
auto s = state.forceString(*args[1], context, pos, "while evaluating the second argument passed to builtins.hashString");
|
||||
|
@ -2586,11 +2586,11 @@ void prim_match(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
|||
} catch (std::regex_error & e) {
|
||||
if (e.code() == std::regex_constants::error_space) {
|
||||
// limit is _GLIBCXX_REGEX_STATE_LIMIT for libstdc++
|
||||
state.errors.make<EvalError>("memory limit exceeded by regular expression '%s'", re)
|
||||
state.ctx.errors.make<EvalError>("memory limit exceeded by regular expression '%s'", re)
|
||||
.atPos(pos)
|
||||
.debugThrow();
|
||||
} else
|
||||
state.errors.make<EvalError>("invalid regular expression '%s'", re)
|
||||
state.ctx.errors.make<EvalError>("invalid regular expression '%s'", re)
|
||||
.atPos(pos)
|
||||
.debugThrow();
|
||||
}
|
||||
|
@ -2652,11 +2652,11 @@ void prim_split(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
|||
} catch (std::regex_error & e) {
|
||||
if (e.code() == std::regex_constants::error_space) {
|
||||
// limit is _GLIBCXX_REGEX_STATE_LIMIT for libstdc++
|
||||
state.errors.make<EvalError>("memory limit exceeded by regular expression '%s'", re)
|
||||
state.ctx.errors.make<EvalError>("memory limit exceeded by regular expression '%s'", re)
|
||||
.atPos(pos)
|
||||
.debugThrow();
|
||||
} else
|
||||
state.errors.make<EvalError>("invalid regular expression '%s'", re)
|
||||
state.ctx.errors.make<EvalError>("invalid regular expression '%s'", re)
|
||||
.atPos(pos)
|
||||
.debugThrow();
|
||||
}
|
||||
|
@ -2686,7 +2686,7 @@ static void prim_replaceStrings(EvalState & state, const PosIdx pos, Value * * a
|
|||
state.forceList(*args[0], pos, "while evaluating the first argument passed to builtins.replaceStrings");
|
||||
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.replaceStrings");
|
||||
if (args[0]->listSize() != args[1]->listSize())
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"'from' and 'to' arguments passed to builtins.replaceStrings have different lengths"
|
||||
).atPos(pos).debugThrow();
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ void prim_addDrvOutputDependencies(EvalState & state, const PosIdx pos, Value *
|
|||
|
||||
auto contextSize = context.size();
|
||||
if (contextSize != 1) {
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"context of string '%s' must have exactly one element, but has %d",
|
||||
*s,
|
||||
contextSize
|
||||
|
@ -66,7 +66,7 @@ void prim_addDrvOutputDependencies(EvalState & state, const PosIdx pos, Value *
|
|||
(NixStringContextElem { std::visit(overloaded {
|
||||
[&](const NixStringContextElem::Opaque & c) -> NixStringContextElem::DrvDeep {
|
||||
if (!c.path.isDerivation()) {
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"path '%s' is not a derivation",
|
||||
state.store->printStorePath(c.path)
|
||||
).atPos(pos).debugThrow();
|
||||
|
@ -76,7 +76,7 @@ void prim_addDrvOutputDependencies(EvalState & state, const PosIdx pos, Value *
|
|||
};
|
||||
},
|
||||
[&](const NixStringContextElem::Built & c) -> NixStringContextElem::DrvDeep {
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"`addDrvOutputDependencies` can only act on derivations, not on a derivation output such as '%1%'",
|
||||
c.output
|
||||
).atPos(pos).debugThrow();
|
||||
|
@ -176,7 +176,7 @@ static void prim_appendContext(EvalState & state, const PosIdx pos, Value * * ar
|
|||
for (auto & i : *args[1]->attrs) {
|
||||
const auto & name = state.ctx.symbols[i.name];
|
||||
if (!state.store->isStorePath(name))
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"context key '%s' is not a store path",
|
||||
name
|
||||
).atPos(i.pos).debugThrow();
|
||||
|
@ -196,7 +196,7 @@ static void prim_appendContext(EvalState & state, const PosIdx pos, Value * * ar
|
|||
if (iter != i.value->attrs->end()) {
|
||||
if (state.forceBool(*iter->value, iter->pos, "while evaluating the `allOutputs` attribute of a string context")) {
|
||||
if (!isDerivation(name)) {
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"tried to add all-outputs context of %s, which is not a derivation, to a string",
|
||||
name
|
||||
).atPos(i.pos).debugThrow();
|
||||
|
@ -211,7 +211,7 @@ static void prim_appendContext(EvalState & state, const PosIdx pos, Value * * ar
|
|||
if (iter != i.value->attrs->end()) {
|
||||
state.forceList(*iter->value, iter->pos, "while evaluating the `outputs` attribute of a string context");
|
||||
if (iter->value->listSize() && !isDerivation(name)) {
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"tried to add derivation output context of %s, which is not a derivation, to a string",
|
||||
name
|
||||
).atPos(i.pos).debugThrow();
|
||||
|
|
|
@ -38,11 +38,11 @@ static void prim_fetchMercurial(EvalState & state, const PosIdx pos, Value * * a
|
|||
else if (n == "name")
|
||||
name = state.forceStringNoCtx(*attr.value, attr.pos, "while evaluating the `name` attribute passed to builtins.fetchMercurial");
|
||||
else
|
||||
state.errors.make<EvalError>("unsupported argument '%s' to 'fetchMercurial'", state.ctx.symbols[attr.name]).atPos(attr.pos).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("unsupported argument '%s' to 'fetchMercurial'", state.ctx.symbols[attr.name]).atPos(attr.pos).debugThrow();
|
||||
}
|
||||
|
||||
if (url.empty())
|
||||
state.errors.make<EvalError>("'url' argument required").atPos(pos).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("'url' argument required").atPos(pos).debugThrow();
|
||||
|
||||
} else
|
||||
url = state.coerceToString(pos, *args[0], context,
|
||||
|
|
|
@ -124,12 +124,12 @@ static void fetchTree(
|
|||
|
||||
if (auto aType = args[0]->attrs->get(state.ctx.s.type)) {
|
||||
if (type)
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"unexpected attribute 'type'"
|
||||
).atPos(pos).debugThrow();
|
||||
type = state.forceStringNoCtx(*aType->value, aType->pos, "while evaluating the `type` attribute passed to builtins.fetchTree");
|
||||
} else if (!type)
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"attribute 'type' is missing in call to 'fetchTree'"
|
||||
).atPos(pos).debugThrow();
|
||||
|
||||
|
@ -153,19 +153,19 @@ static void fetchTree(
|
|||
auto intValue = attr.value->integer.value;
|
||||
|
||||
if (intValue < 0) {
|
||||
state.errors.make<EvalError>("negative value given for fetchTree attr %1%: %2%", state.ctx.symbols[attr.name], intValue).atPos(pos).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("negative value given for fetchTree attr %1%: %2%", state.ctx.symbols[attr.name], intValue).atPos(pos).debugThrow();
|
||||
}
|
||||
unsigned long asUnsigned = intValue;
|
||||
|
||||
attrs.emplace(state.ctx.symbols[attr.name], asUnsigned);
|
||||
} else
|
||||
state.errors.make<TypeError>("fetchTree argument '%s' is %s while a string, Boolean or integer is expected",
|
||||
state.ctx.errors.make<TypeError>("fetchTree argument '%s' is %s while a string, Boolean or integer is expected",
|
||||
state.ctx.symbols[attr.name], showType(*attr.value)).debugThrow();
|
||||
}
|
||||
|
||||
if (!params.allowNameArgument)
|
||||
if (auto nameIter = attrs.find("name"); nameIter != attrs.end())
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"attribute 'name' isn’t supported in call to 'fetchTree'"
|
||||
).atPos(pos).debugThrow();
|
||||
|
||||
|
@ -189,7 +189,7 @@ static void fetchTree(
|
|||
input = lookupInRegistries(state.store, input).first;
|
||||
|
||||
if (evalSettings.pureEval && !input.isLocked()) {
|
||||
state.errors.make<EvalError>("in pure evaluation mode, 'fetchTree' requires a locked input").atPos(pos).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("in pure evaluation mode, 'fetchTree' requires a locked input").atPos(pos).debugThrow();
|
||||
}
|
||||
|
||||
auto [tree, input2] = input.fetch(state.store);
|
||||
|
@ -231,12 +231,12 @@ static void fetch(EvalState & state, const PosIdx pos, Value * * args, Value & v
|
|||
else if (n == "name")
|
||||
name = state.forceStringNoCtx(*attr.value, attr.pos, "while evaluating the name of the content we should fetch");
|
||||
else
|
||||
state.errors.make<EvalError>("unsupported argument '%s' to '%s'", n, who)
|
||||
state.ctx.errors.make<EvalError>("unsupported argument '%s' to '%s'", n, who)
|
||||
.atPos(pos).debugThrow();
|
||||
}
|
||||
|
||||
if (!url)
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"'url' argument required").atPos(pos).debugThrow();
|
||||
} else
|
||||
url = state.forceStringNoCtx(*args[0], pos, "while evaluating the url we should fetch");
|
||||
|
@ -250,7 +250,7 @@ static void fetch(EvalState & state, const PosIdx pos, Value * * args, Value & v
|
|||
name = baseNameOf(*url);
|
||||
|
||||
if (evalSettings.pureEval && !expectedHash)
|
||||
state.errors.make<EvalError>("in pure evaluation mode, '%s' requires a 'sha256' argument", who).atPos(pos).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("in pure evaluation mode, '%s' requires a 'sha256' argument", who).atPos(pos).debugThrow();
|
||||
|
||||
// early exit if pinned and already in the store
|
||||
if (expectedHash && expectedHash->type == HashType::SHA256) {
|
||||
|
@ -280,7 +280,7 @@ static void fetch(EvalState & state, const PosIdx pos, Value * * args, Value & v
|
|||
? state.store->queryPathInfo(storePath)->narHash
|
||||
: hashFile(HashType::SHA256, state.store->toRealPath(storePath));
|
||||
if (hash != *expectedHash) {
|
||||
state.errors.make<EvalError>(
|
||||
state.ctx.errors.make<EvalError>(
|
||||
"hash mismatch in file downloaded from '%s':\n specified: %s\n got: %s",
|
||||
*url,
|
||||
expectedHash->to_string(Base::Base32, true),
|
||||
|
|
|
@ -83,7 +83,7 @@ void prim_fromTOML(EvalState & state, const PosIdx pos, Value * * args, Value &
|
|||
try {
|
||||
visit(val, toml::parse(tomlStream, "fromTOML" /* the "filename" */));
|
||||
} catch (std::exception & e) { // TODO: toml::syntax_error
|
||||
state.errors.make<EvalError>("while parsing TOML: %s", e.what()).atPos(pos).debugThrow();
|
||||
state.ctx.errors.make<EvalError>("while parsing TOML: %s", e.what()).atPos(pos).debugThrow();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ json printValueAsJSON(EvalState & state, bool strict,
|
|||
|
||||
case nThunk:
|
||||
case nFunction:
|
||||
state.errors.make<TypeError>(
|
||||
state.ctx.errors.make<TypeError>(
|
||||
"cannot convert %1% to JSON",
|
||||
showType(v)
|
||||
)
|
||||
|
@ -118,7 +118,7 @@ void printValueAsJSON(EvalState & state, bool strict,
|
|||
json ExternalValueBase::printValueAsJSON(EvalState & state, bool strict,
|
||||
NixStringContext & context, bool copyToStore) const
|
||||
{
|
||||
state.errors.make<TypeError>("cannot convert %1% to JSON", showType())
|
||||
state.ctx.errors.make<TypeError>("cannot convert %1% to JSON", showType())
|
||||
.debugThrow();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue