From d30027a37a1e9bdb9adb239cb0c5c9be5699d492 Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Tue, 3 Dec 2024 20:38:41 +0100 Subject: [PATCH] libexpr: associate error creation and debugging with EvalContext Change-Id: I80beedd0c58361ebc67cebcee97d64879baed050 --- lix/libexpr/attr-path.cc | 4 +- lix/libexpr/eval-cache.cc | 24 +++--- lix/libexpr/eval-inline.hh | 4 +- lix/libexpr/eval.cc | 86 ++++++++++----------- lix/libexpr/flake/flake.cc | 14 ++-- lix/libexpr/get-drvs.cc | 4 +- lix/libexpr/primops.cc | 106 +++++++++++++------------- lix/libexpr/primops/context.cc | 12 +-- lix/libexpr/primops/fetchMercurial.cc | 4 +- lix/libexpr/primops/fetchTree.cc | 20 ++--- lix/libexpr/primops/fromTOML.cc | 2 +- lix/libexpr/value-to-json.cc | 4 +- 12 files changed, 142 insertions(+), 142 deletions(-) diff --git a/lix/libexpr/attr-path.cc b/lix/libexpr/attr-path.cc index b89d511f9..8fee8ebb6 100644 --- a/lix/libexpr/attr-path.cc +++ b/lix/libexpr/attr-path.cc @@ -56,7 +56,7 @@ std::pair findAlongAttrPath(EvalState & state, const std::strin if (!attrIndex) { if (v->type() != nAttrs) - state.errors.make( + state.ctx.errors.make( "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 findAlongAttrPath(EvalState & state, const std::strin else { if (!v->isList()) - state.errors.make( + state.ctx.errors.make( "the expression selected by the selection path '%1%' should be a list but is %2%", attrPath, showType(*v)).debugThrow(); diff --git a/lix/libexpr/eval-cache.cc b/lix/libexpr/eval-cache.cc index e7b34fc9a..ee1ac45f2 100644 --- a/lix/libexpr/eval-cache.cc +++ b/lix/libexpr/eval-cache.cc @@ -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("'%s' is not a string", getAttrPathStr(state)).debugThrow(); + state.ctx.errors.make("'%s' is not a string", getAttrPathStr(state)).debugThrow(); } } auto & v = forceValue(state); if (v.type() != nString && v.type() != nPath) { - state.errors.make("'%s' is not a string but %s", getAttrPathStr(state), v.type()).debugThrow(); + state.ctx.errors.make("'%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("'%s' is not a string", getAttrPathStr(state)).debugThrow(); + state.ctx.errors.make("'%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("'%s' is not a string but %s", getAttrPathStr(state), v.type()).debugThrow(); + state.ctx.errors.make("'%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("'%s' is not a Boolean", getAttrPathStr(state)).debugThrow(); + state.ctx.errors.make("'%s' is not a Boolean", getAttrPathStr(state)).debugThrow(); } } auto & v = forceValue(state); if (v.type() != nBool) - state.errors.make("'%s' is not a Boolean", getAttrPathStr(state)).debugThrow(); + state.ctx.errors.make("'%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("'%s' is not an integer", getAttrPathStr(state)).debugThrow(); + state.ctx.errors.make("'%s' is not an integer", getAttrPathStr(state)).debugThrow(); } } auto & v = forceValue(state); if (v.type() != nInt) - state.errors.make("'%s' is not an integer", getAttrPathStr(state)).debugThrow(); + state.ctx.errors.make("'%s' is not an integer", getAttrPathStr(state)).debugThrow(); return v.integer; } @@ -666,7 +666,7 @@ std::vector AttrCursor::getListOfStrings(EvalState & state) debug("using cached list of strings attribute '%s'", getAttrPathStr(state)); return *l; } else - state.errors.make("'%s' is not a list of strings", getAttrPathStr(state)).debugThrow(); + state.ctx.errors.make("'%s' is not a list of strings", getAttrPathStr(state)).debugThrow(); } } @@ -676,7 +676,7 @@ std::vector AttrCursor::getListOfStrings(EvalState & state) state.forceValue(v, noPos); if (v.type() != nList) - state.errors.make("'%s' is not a list", getAttrPathStr(state)).debugThrow(); + state.ctx.errors.make("'%s' is not a list", getAttrPathStr(state)).debugThrow(); std::vector res; @@ -699,14 +699,14 @@ std::vector AttrCursor::getAttrs(EvalState & state) debug("using cached attrset attribute '%s'", getAttrPathStr(state)); return attrs->p; } else - state.errors.make("'%s' is not an attribute set", getAttrPathStr(state)).debugThrow(); + state.ctx.errors.make("'%s' is not an attribute set", getAttrPathStr(state)).debugThrow(); } } auto & v = forceValue(state); if (v.type() != nAttrs) - state.errors.make("'%s' is not an attribute set", getAttrPathStr(state)).debugThrow(); + state.ctx.errors.make("'%s' is not an attribute set", getAttrPathStr(state)).debugThrow(); fullattr_t attrs; for (auto & attr : *getValue(state).attrs) diff --git a/lix/libexpr/eval-inline.hh b/lix/libexpr/eval-inline.hh index 882242731..9a5211e70 100644 --- a/lix/libexpr/eval-inline.hh +++ b/lix/libexpr/eval-inline.hh @@ -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( + ctx.errors.make( "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( + ctx.errors.make( "expected a list but found %1%: %2%", showType(v), ValuePrinter(*this, v, errorPrintOptions) diff --git a/lix/libexpr/eval.cc b/lix/libexpr/eval.cc index 8e32896bb..d69794b8c 100644 --- a/lix/libexpr/eval.cc +++ b/lix/libexpr/eval.cc @@ -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, 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("undefined variable '%1%'", ctx.symbols[var.name]).atPos(var.pos).withFrame(*env, var).debugThrow(); + ctx.errors.make("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( + ctx.errors.make( "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( + ctx.errors.make( "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("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("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( + state.ctx.errors.make( "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("attribute '%s' missing", state.ctx.symbols[name]) + state.ctx.errors.make("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("stack overflow; max-call-depth exceeded").atPos(pos).debugThrow(); + ctx.errors.make("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("function '%s' called without required argument '%s'", lambda.getName(ctx.symbols), missing) + ctx.errors.make("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("function '%s' called with unexpected argument '%s'", lambda.getName(ctx.symbols), unex) + ctx.errors.make("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( + ctx.errors.make( "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(R"(cannot evaluate a function that has an argument without a value ('%1%') + ctx.errors.make(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("assertion '%1%' failed", out.str()).atPos(pos).withFrame(env, *this).debugThrow(); + state.ctx.errors.make("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("integer overflow in adding %1% + %2%", n, vTmp.integer).atPos(i_pos).debugThrow(); + state.ctx.errors.make("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("cannot add %1% to an integer", showType(vTmp)).atPos(i_pos).withFrame(env, *this).debugThrow(); + state.ctx.errors.make("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("cannot add %1% to a float", showType(vTmp)).atPos(i_pos).withFrame(env, *this).debugThrow(); + state.ctx.errors.make("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("a string that refers to a store path cannot be appended to a path").atPos(pos).withFrame(env, *this).debugThrow(); + state.ctx.errors.make("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("infinite recursion encountered") + state.ctx.errors.make("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( + ctx.errors.make( "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( + ctx.errors.make( "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( + ctx.errors.make( "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( + ctx.errors.make( "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( + ctx.errors.make( "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("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("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( + ctx.errors.make( "cannot coerce %1% to a string: %2%", showType(v), ValuePrinter(*this, v, errorPrintOptions) @@ -2345,7 +2345,7 @@ BackedStringView EvalState::coerceToString( } } - errors.make("cannot coerce %1% to a string: %2%", + ctx.errors.make("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("string '%1%' doesn't represent an absolute path", path).withTrace(pos, errorCtx).debugThrow(); + ctx.errors.make("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("path '%1%' is not in the Nix store", path).withTrace(pos, errorCtx).debugThrow(); + ctx.errors.make("path '%1%' is not in the Nix store", path).withTrace(pos, errorCtx).debugThrow(); } @@ -2402,7 +2402,7 @@ std::pair EvalState::coerceToSingleDerivedP auto s = forceString(v, context, pos, errorCtx); auto csize = context.size(); if (csize != 1) - errors.make( + ctx.errors.make( "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 EvalState::coerceToSingleDerivedP return std::move(o); }, [&](NixStringContextElem::DrvDeep &&) -> SingleDerivedPath { - errors.make( + ctx.errors.make( "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( + ctx.errors.make( "path string '%s' has context with the different path '%s'", s, sExpected) .withTrace(pos, errorCtx).debugThrow(); }, [&](const SingleDerivedPath::Built & b) { - errors.make( + ctx.errors.make( "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("cannot compare %1% with %2%", showType(v1), showType(v2)).withTrace(pos, errorCtx).debugThrow(); + ctx.errors.make("cannot compare %1% with %2%", showType(v1), showType(v2)).withTrace(pos, errorCtx).debugThrow(); } } @@ -2832,7 +2832,7 @@ std::optional EvalPaths::resolveSearchPathPath(const SearchPath::Pa std::string ExternalValueBase::coerceToString(EvalState & state, const PosIdx & pos, NixStringContext & context, bool copyMore, bool copyToStore) const { - state.errors.make( + state.ctx.errors.make( "cannot coerce %1% to a string: %2%", showType(), *this ).atPos(pos).debugThrow(); } diff --git a/lix/libexpr/flake/flake.cc b/lix/libexpr/flake/flake.cc index 8ea83755f..fa03d098e 100644 --- a/lix/libexpr/flake/flake.cc +++ b/lix/libexpr/flake/flake.cc @@ -142,14 +142,14 @@ static FlakeInput parseFlakeInput(EvalState & state, auto intValue = attr.value->integer.value; if (intValue < 0) { - state.errors.make("negative value given for flake input attribute %1%: %2%", state.ctx.symbols[attr.name], intValue).debugThrow(); + state.ctx.errors.make("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("flake input attribute '%s' is %s while a string, Boolean, or integer is expected", + state.ctx.errors.make("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(&flakeExpr))) { - state.errors.make("file '%s' must be an attribute set", resolvedFlakeFile).debugThrow(); + state.ctx.errors.make("file '%s' must be an attribute set", resolvedFlakeFile).debugThrow(); } Value vInfo; @@ -307,14 +307,14 @@ static Flake getFlake( std::vector ss; for (auto elem : setting.value->listItems()) { if (elem->type() != nString) - state.errors.make("list element in flake configuration setting '%s' is %s while a string is expected", + state.ctx.errors.make("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("flake configuration setting '%s' is %s", + state.ctx.errors.make("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("negative value given for flake ref attr %1%: %2%", state.ctx.symbols[attr.name], intValue).atPos(pos).debugThrow(); + state.ctx.errors.make("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( + state.ctx.errors.make( "flake reference attribute sets may only contain integers, Booleans, " "and strings, but attribute '%s' is %s", state.ctx.symbols[attr.name], diff --git a/lix/libexpr/get-drvs.cc b/lix/libexpr/get-drvs.cc index a1116f068..e935555cd 100644 --- a/lix/libexpr/get-drvs.cc +++ b/lix/libexpr/get-drvs.cc @@ -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("derivation name missing").debugThrow(); + if (i == attrs->end()) state.ctx.errors.make("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( + state.ctx.errors.make( "expression was expected to be a derivation or collection of derivations, but instead was %s", showType(v.type(), true) ).debugThrow(); diff --git a/lix/libexpr/primops.cc b/lix/libexpr/primops.cc index b38021959..cca48cc63 100644 --- a/lix/libexpr/primops.cc +++ b/lix/libexpr/primops.cc @@ -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("could not open '%1%': %2%", path, dlerror()).debugThrow(); + state.ctx.errors.make("could not open '%1%': %2%", path, dlerror()).debugThrow(); dlerror(); ValueInitializer func = reinterpret_cast(dlsym(handle, sym.c_str())); if(!func) { char *message = dlerror(); if (message) - state.errors.make("could not load symbol '%1%' from '%2%': %3%", sym, path, message).debugThrow(); + state.ctx.errors.make("could not load symbol '%1%' from '%2%': %3%", sym, path, message).debugThrow(); else - state.errors.make("symbol '%1%' from '%2%' resolved to NULL when a function pointer was expected", sym, path).debugThrow(); + state.ctx.errors.make("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("at least one argument to 'exec' required").atPos(pos).debugThrow(); + state.ctx.errors.make("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("cannot compare %s with %s", showType(*v1), showType(*v2)).debugThrow(); + state.ctx.errors.make("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("cannot compare %s with %s; values of that type are incomparable", showType(*v1), showType(*v2)).debugThrow(); + state.ctx.errors.make("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("attribute '%s' missing", state.ctx.symbols[attrSym]).withTrace(noPos, errorCtx).debugThrow(); + state.ctx.errors.make("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("evaluation aborted with the following error message: '%1%'", s).debugThrow(); + state.ctx.errors.make("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(s).debugThrow(); + state.ctx.errors.make(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> trylevel; std::unique_ptr 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( + state.ctx.errors.make( "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("duplicate derivation output '%1%'", j) + state.ctx.errors.make("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("invalid derivation output name 'drv'") + state.ctx.errors.make("invalid derivation output name 'drv'") .atPos(v) .debugThrow(); outputs.insert(j); } if (outputs.empty()) - state.errors.make("derivation cannot have an empty set of outputs") + state.ctx.errors.make("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("required attribute 'builder' missing") + state.ctx.errors.make("required attribute 'builder' missing") .atPos(v) .debugThrow(); if (drv.platform == "") - state.errors.make("required attribute 'system' missing") + state.ctx.errors.make("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( + state.ctx.errors.make( "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( + state.ctx.errors.make( "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("derivation cannot be both content-addressed and impure") + state.ctx.errors.make("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( + state.ctx.errors.make( "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( + state.ctx.errors.make( "'%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("path '%1%' is not in the Nix store", path) + state.ctx.errors.make("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( + state.ctx.errors.make( "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( + state.ctx.errors.make( "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 ht = parseHashType(type); if (!ht) - state.errors.make("unknown hash type '%1%'", type).atPos(pos).debugThrow(); + state.ctx.errors.make("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(&c.raw)) refs.insert(p->path); else - state.errors.make( + state.ctx.errors.make( "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( + state.ctx.errors.make( "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( + state.ctx.errors.make( "unsupported argument '%1%' to 'addPath'", state.ctx.symbols[attr.name] ).atPos(attr.pos).debugThrow(); } if (!path) - state.errors.make( + state.ctx.errors.make( "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("'functionArgs' requires a function").atPos(pos).debugThrow(); + state.ctx.errors.make("'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( + state.ctx.errors.make( "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("'tail' called on an empty list").atPos(pos).debugThrow(); + state.ctx.errors.make("'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("cannot create list of size %1%", len_).atPos(pos).debugThrow(); + state.ctx.errors.make("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("integer overflow in adding %1% + %2%", i1, i2).atPos(pos).debugThrow(); + state.ctx.errors.make("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("integer overflow in subtracting %1% - %2%", i1, i2).atPos(pos).debugThrow(); + state.ctx.errors.make("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("integer overflow in multiplying %1% * %2%", i1, i2).atPos(pos).debugThrow(); + state.ctx.errors.make("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("division by zero").atPos(pos).debugThrow(); + state.ctx.errors.make("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("integer overflow in dividing %1% / %2%", i1, i2).atPos(pos).debugThrow(); + state.ctx.errors.make("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("negative start position in 'substring'").atPos(pos).debugThrow(); + state.ctx.errors.make("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 ht = parseHashType(type); if (!ht) - state.errors.make("unknown hash algorithm '%1%'", type).atPos(pos).debugThrow(); + state.ctx.errors.make("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("memory limit exceeded by regular expression '%s'", re) + state.ctx.errors.make("memory limit exceeded by regular expression '%s'", re) .atPos(pos) .debugThrow(); } else - state.errors.make("invalid regular expression '%s'", re) + state.ctx.errors.make("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("memory limit exceeded by regular expression '%s'", re) + state.ctx.errors.make("memory limit exceeded by regular expression '%s'", re) .atPos(pos) .debugThrow(); } else - state.errors.make("invalid regular expression '%s'", re) + state.ctx.errors.make("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( + state.ctx.errors.make( "'from' and 'to' arguments passed to builtins.replaceStrings have different lengths" ).atPos(pos).debugThrow(); diff --git a/lix/libexpr/primops/context.cc b/lix/libexpr/primops/context.cc index 7c425f907..aece52520 100644 --- a/lix/libexpr/primops/context.cc +++ b/lix/libexpr/primops/context.cc @@ -56,7 +56,7 @@ void prim_addDrvOutputDependencies(EvalState & state, const PosIdx pos, Value * auto contextSize = context.size(); if (contextSize != 1) { - state.errors.make( + state.ctx.errors.make( "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( + state.ctx.errors.make( "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( + state.ctx.errors.make( "`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( + state.ctx.errors.make( "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( + state.ctx.errors.make( "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( + state.ctx.errors.make( "tried to add derivation output context of %s, which is not a derivation, to a string", name ).atPos(i.pos).debugThrow(); diff --git a/lix/libexpr/primops/fetchMercurial.cc b/lix/libexpr/primops/fetchMercurial.cc index 22eea51e0..3407b8b54 100644 --- a/lix/libexpr/primops/fetchMercurial.cc +++ b/lix/libexpr/primops/fetchMercurial.cc @@ -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("unsupported argument '%s' to 'fetchMercurial'", state.ctx.symbols[attr.name]).atPos(attr.pos).debugThrow(); + state.ctx.errors.make("unsupported argument '%s' to 'fetchMercurial'", state.ctx.symbols[attr.name]).atPos(attr.pos).debugThrow(); } if (url.empty()) - state.errors.make("'url' argument required").atPos(pos).debugThrow(); + state.ctx.errors.make("'url' argument required").atPos(pos).debugThrow(); } else url = state.coerceToString(pos, *args[0], context, diff --git a/lix/libexpr/primops/fetchTree.cc b/lix/libexpr/primops/fetchTree.cc index 3279d194e..dae495616 100644 --- a/lix/libexpr/primops/fetchTree.cc +++ b/lix/libexpr/primops/fetchTree.cc @@ -124,12 +124,12 @@ static void fetchTree( if (auto aType = args[0]->attrs->get(state.ctx.s.type)) { if (type) - state.errors.make( + state.ctx.errors.make( "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( + state.ctx.errors.make( "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("negative value given for fetchTree attr %1%: %2%", state.ctx.symbols[attr.name], intValue).atPos(pos).debugThrow(); + state.ctx.errors.make("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("fetchTree argument '%s' is %s while a string, Boolean or integer is expected", + state.ctx.errors.make("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( + state.ctx.errors.make( "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("in pure evaluation mode, 'fetchTree' requires a locked input").atPos(pos).debugThrow(); + state.ctx.errors.make("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("unsupported argument '%s' to '%s'", n, who) + state.ctx.errors.make("unsupported argument '%s' to '%s'", n, who) .atPos(pos).debugThrow(); } if (!url) - state.errors.make( + state.ctx.errors.make( "'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("in pure evaluation mode, '%s' requires a 'sha256' argument", who).atPos(pos).debugThrow(); + state.ctx.errors.make("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( + state.ctx.errors.make( "hash mismatch in file downloaded from '%s':\n specified: %s\n got: %s", *url, expectedHash->to_string(Base::Base32, true), diff --git a/lix/libexpr/primops/fromTOML.cc b/lix/libexpr/primops/fromTOML.cc index 2a66fc95b..069eb6097 100644 --- a/lix/libexpr/primops/fromTOML.cc +++ b/lix/libexpr/primops/fromTOML.cc @@ -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("while parsing TOML: %s", e.what()).atPos(pos).debugThrow(); + state.ctx.errors.make("while parsing TOML: %s", e.what()).atPos(pos).debugThrow(); } } diff --git a/lix/libexpr/value-to-json.cc b/lix/libexpr/value-to-json.cc index dd6d30f62..21fca1b1c 100644 --- a/lix/libexpr/value-to-json.cc +++ b/lix/libexpr/value-to-json.cc @@ -99,7 +99,7 @@ json printValueAsJSON(EvalState & state, bool strict, case nThunk: case nFunction: - state.errors.make( + state.ctx.errors.make( "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("cannot convert %1% to JSON", showType()) + state.ctx.errors.make("cannot convert %1% to JSON", showType()) .debugThrow(); }