From 53c0e884d8aa80d34d88270bfc524761fbbcca3d Mon Sep 17 00:00:00 2001 From: skye Date: Mon, 23 Feb 2026 19:57:21 -0500 Subject: [PATCH] Migrate EvalState::eval from out param to return a `Value` Instead of taking in a final argument `Value &` out parameter which it writes to, it now returns its result Change-Id: Iab6bc3a3ac6a4b17c6d31115a766a6ea6a6a6964 --- lix/legacy/nix-build.cc | 6 ++---- lix/legacy/nix-env.cc | 5 ++--- lix/legacy/nix-instantiate.cc | 3 +-- lix/legacy/user-env.cc | 8 ++++---- lix/libcmd/installables.cc | 7 +++---- lix/libcmd/repl.cc | 2 +- lix/libexpr/eval.cc | 7 +++---- lix/libexpr/eval.hh | 4 +--- lix/libexpr/flake/flake.cc | 12 ++++-------- lix/libexpr/primops.cc | 20 +++++++++----------- lix/nix/eval.cc | 3 +-- lix/nix/main.cc | 10 +++------- lix/nix/prefetch.cc | 8 +++----- lix/nix/upgrade-nix.cc | 3 +-- subprojects/nix-eval-jobs/src/worker.cc | 2 +- tests/unit/libexpr-support/tests/libexpr.hh | 8 +++++--- tests/unit/libexpr/value/print.cc | 9 +++------ 17 files changed, 47 insertions(+), 70 deletions(-) diff --git a/lix/legacy/nix-build.cc b/lix/legacy/nix-build.cc index 7c0ce563f..83b94a947 100644 --- a/lix/legacy/nix-build.cc +++ b/lix/legacy/nix-build.cc @@ -272,8 +272,7 @@ static int main_nix_build(AsyncIoRoot & aio, std::string programName, Strings ar if (attrPaths.empty()) attrPaths = {""}; for (auto e : exprs) { - Value vRoot; - state->eval(e, vRoot); + Value vRoot = state->eval(e); std::function takesNixShellAttr; takesNixShellAttr = [&](const Value & v) { @@ -356,8 +355,7 @@ static int main_nix_build(AsyncIoRoot & aio, std::string programName, Strings ar "(import {}).bashInteractive", CanonPath::fromCwd()); - Value v; - state->eval(expr, v); + Value v = state->eval(expr); auto drv = getDerivation(*state, v, false); if (!drv) diff --git a/lix/legacy/nix-env.cc b/lix/legacy/nix-env.cc index 99ad20ba8..38455a08b 100644 --- a/lix/legacy/nix-env.cc +++ b/lix/legacy/nix-env.cc @@ -425,9 +425,8 @@ static void queryInstSources(EvalState & state, for (auto & i : args) { Expr & eFun = state.ctx.parseExprFromString(i, CanonPath::fromCwd()); - Value vFun, vTmp; - state.eval(eFun, vFun); - vTmp = {NewValueAs::app, state.ctx.mem, vFun, vArg}; + Value vFun = state.eval(eFun); + Value vTmp = {NewValueAs::app, state.ctx.mem, vFun, vArg}; getDerivations(state, vTmp, "", *instSource.autoArgs, elems, true); } diff --git a/lix/legacy/nix-instantiate.cc b/lix/legacy/nix-instantiate.cc index ab46e3ec3..c11d8c460 100644 --- a/lix/legacy/nix-instantiate.cc +++ b/lix/legacy/nix-instantiate.cc @@ -34,8 +34,7 @@ void processExpr(EvalState & state, const Strings & attrPaths, return; } - Value vRoot; - state.eval(e, vRoot); + Value vRoot = state.eval(e); for (auto & i : attrPaths) { Value v(findAlongAttrPath(state, i, autoArgs, vRoot).first); diff --git a/lix/legacy/user-env.cc b/lix/legacy/user-env.cc index fcd9d92c5..d4fe9f393 100644 --- a/lix/legacy/user-env.cc +++ b/lix/legacy/user-env.cc @@ -99,10 +99,10 @@ bool createUserEnv(EvalState & state, DrvInfos & elems, str.str(), references)); /* Get the environment builder expression. */ - Value envBuilder; - state.eval(state.ctx.parseExprFromString( - #include "buildenv.nix.gen.hh" - , CanonPath::root), envBuilder); + Value envBuilder = state.eval(state.ctx.parseExprFromString( +#include "buildenv.nix.gen.hh" + , CanonPath::root + )); /* Construct a Nix expression that calls the user environment builder with the manifest as argument. */ diff --git a/lix/libcmd/installables.cc b/lix/libcmd/installables.cc index a18323f69..03a6556fe 100644 --- a/lix/libcmd/installables.cc +++ b/lix/libcmd/installables.cc @@ -219,8 +219,7 @@ void SourceExprCommand::completeInstallable(EvalState & state, AddCompletions & state.aio.blockOn(lookupFileArg(*evaluator, *file)).unwrap() )); - Value root; - state.eval(e, root); + Value root = state.eval(e); auto autoArgs = getAutoArgs(*evaluator); @@ -453,13 +452,13 @@ Installables SourceExprCommand::parseInstallables( if (file == "-") { auto & e = evaluator->parseStdin(); - state.eval(e, vFile); + vFile = state.eval(e); } else if (file) state.evalFile(state.aio.blockOn(lookupFileArg(*evaluator, *file)).unwrap(), vFile); else { auto & e = evaluator->parseExprFromString(*expr, CanonPath::fromCwd()); - state.eval(e, vFile); + vFile = state.eval(e); } for (auto & s : ss) { diff --git a/lix/libcmd/repl.cc b/lix/libcmd/repl.cc index 37c677cd4..61b2bc06e 100644 --- a/lix/libcmd/repl.cc +++ b/lix/libcmd/repl.cc @@ -1434,7 +1434,7 @@ Value NixRepl::getReplOverlaysEvalFunction() evaluator.builtins.staticEnv ); - state.eval(expr, **replOverlaysEvalFunction); + **replOverlaysEvalFunction = state.eval(expr); return **replOverlaysEvalFunction; } diff --git a/lix/libexpr/eval.cc b/lix/libexpr/eval.cc index 484660ab9..4040ec2d3 100644 --- a/lix/libexpr/eval.cc +++ b/lix/libexpr/eval.cc @@ -955,7 +955,7 @@ void EvalState::evalFile(const SourcePath & path_, Value & v) "while evaluating the file '%1%':", resolvedPath.to_string()) : nullptr; - eval(e, v); + v = eval(e); } catch (Error & e) { e.addTrace(nullptr, "while evaluating the file '%1%':", resolvedPath.to_string()); throw; @@ -972,10 +972,9 @@ void EvalState::resetFileCache() ctx.caches.fileEval.clear(); } - -void EvalState::eval(Expr & e, Value & v) +Value EvalState::eval(Expr & e) { - v = e.eval(*this, ctx.builtins.env); + return e.eval(*this, ctx.builtins.env); } std::string showAttrPath(EvalState & state, Env & env, const AttrPath & attrPath) diff --git a/lix/libexpr/eval.hh b/lix/libexpr/eval.hh index 28a69031a..8693bcfb2 100644 --- a/lix/libexpr/eval.hh +++ b/lix/libexpr/eval.hh @@ -652,10 +652,8 @@ public: /** * Evaluate an expression to normal form - * - * @param [out] v The resulting is stored here. */ - void eval(Expr & e, Value & v); + Value eval(Expr & e); /** * If `v` is a thunk, enter it and overwrite `v` with the result diff --git a/lix/libexpr/flake/flake.cc b/lix/libexpr/flake/flake.cc index 72e79ddb0..b11792656 100644 --- a/lix/libexpr/flake/flake.cc +++ b/lix/libexpr/flake/flake.cc @@ -331,8 +331,7 @@ static Flake getFlake( state.ctx.errors.make("file '%s' must be an attribute set", resolvedFlakeFile).debugThrow(); } - Value vInfo; - state.eval(flakeExpr, vInfo); + Value vInfo = state.eval(flakeExpr); if (auto description = vInfo.attrs()->get(state.ctx.symbols.sym_description)) { expectType(state, nString, description->value, description->pos); @@ -964,13 +963,10 @@ void callFlake(EvalState & state, if (!state.ctx.caches.vCallFlake) { state.ctx.caches.vCallFlake = allocRootValue({}); - state.eval( - state.ctx.parseExprFromString( + *state.ctx.caches.vCallFlake = state.eval(state.ctx.parseExprFromString( #include "call-flake.nix.gen.hh" - , CanonPath::root - ), - *state.ctx.caches.vCallFlake - ); + , CanonPath::root + )); } Value vTmp1 = state.callFunction(*state.ctx.caches.vCallFlake, vLocks, noPos); diff --git a/lix/libexpr/primops.cc b/lix/libexpr/primops.cc index 6f9ed6ff4..89b398a59 100644 --- a/lix/libexpr/primops.cc +++ b/lix/libexpr/primops.cc @@ -201,13 +201,10 @@ static void import(EvalState & state, Value & vPath, Value * vScope, Value & v) if (!state.ctx.caches.vImportedDrvToDerivation) { state.ctx.caches.vImportedDrvToDerivation = allocRootValue({}); - state.eval( - state.ctx.parseExprFromString( + *state.ctx.caches.vImportedDrvToDerivation = state.eval(state.ctx.parseExprFromString( #include "imported-drv-to-derivation.nix.gen.hh" - , CanonPath::root - ), - *state.ctx.caches.vImportedDrvToDerivation - ); + , CanonPath::root + )); } state.forceFunction( @@ -220,9 +217,10 @@ static void import(EvalState & state, Value & vPath, Value * vScope, Value & v) } else if (path2 == corepkgsPrefix + "fetchurl.nix") { - state.eval(state.ctx.parseExprFromString( - #include "fetchurl.nix.gen.hh" - , CanonPath::root), v); + v = state.eval(state.ctx.parseExprFromString( +#include "fetchurl.nix.gen.hh" + , CanonPath::root + )); } else { @@ -347,7 +345,7 @@ void prim_exec(EvalState & state, Value * * args, Value & v) throw; } try { - state.eval(*parsed, v); + v = state.eval(*parsed); } catch (Error & e) { e.addTrace(nullptr, "while evaluating the output from '%1%'", program); throw; @@ -3113,7 +3111,7 @@ void EvalBuiltins::createBaseEnv(const SearchPath & searchPath, const Path & sto auto & expr = *state.ctx.parse( code, sizeof(code), Pos::Hidden{}, {CanonPath::root}, state.ctx.builtins.staticEnv ); - state.eval(expr, v); + v = state.eval(expr); }, }}; static Value initializeDerivation{NewValueAs::primop, prim_initializeDerivation}; diff --git a/lix/nix/eval.cc b/lix/nix/eval.cc index fa72b9e4a..d64be9d8d 100644 --- a/lix/nix/eval.cc +++ b/lix/nix/eval.cc @@ -79,8 +79,7 @@ struct CmdEval : MixJSON, InstallableCommand, MixReadOnlyOption NixStringContext context; if (apply) { - Value vApply; - state->eval(evaluator->parseExprFromString(*apply, CanonPath::fromCwd()), vApply); + Value vApply = state->eval(evaluator->parseExprFromString(*apply, CanonPath::fromCwd())); v = state->callFunction(vApply, v, noPos); } diff --git a/lix/nix/main.cc b/lix/nix/main.cc index 6158d0c04..9cc2b53ed 100644 --- a/lix/nix/main.cc +++ b/lix/nix/main.cc @@ -360,14 +360,10 @@ static void showHelp(AsyncIoRoot & aio, std::vector subcommand, Nix Evaluator evaluator(aio, {}, aio.blockOn(openStore("dummy://"))); auto state = evaluator.begin(aio); - Value vGenerateManpage; - state->eval( - evaluator.parseExprFromString( + Value vGenerateManpage = state->eval(evaluator.parseExprFromString( #include "generate-manpage.nix.gen.hh" - , CanonPath::root - ), - vGenerateManpage - ); + , CanonPath::root + )); Value vDump; vDump.mkString(toplevel.dumpCli()); diff --git a/lix/nix/prefetch.cc b/lix/nix/prefetch.cc index 5cad445a3..f3a3624d4 100644 --- a/lix/nix/prefetch.cc +++ b/lix/nix/prefetch.cc @@ -28,12 +28,10 @@ std::string resolveMirrorUrl(EvalState & state, const std::string & url) if (p == std::string::npos) throw Error("invalid mirror URL '%s'", url); std::string mirrorName(s, 0, p); - Value vMirrors; // FIXME: use nixpkgs flake - state.eval(state.ctx.parseExprFromString( - "import ", - CanonPath::root), - vMirrors); + Value vMirrors = state.eval(state.ctx.parseExprFromString( + "import ", CanonPath::root + )); state.forceAttrs(vMirrors, noPos, "while evaluating the set of all mirrors"); auto mirrorList = vMirrors.attrs()->get(state.ctx.symbols.create(mirrorName)); diff --git a/lix/nix/upgrade-nix.cc b/lix/nix/upgrade-nix.cc index 681039137..6617b4818 100644 --- a/lix/nix/upgrade-nix.cc +++ b/lix/nix/upgrade-nix.cc @@ -311,8 +311,7 @@ struct CmdUpgradeNix : MixDryRun, EvalCommand auto evaluator = std::make_unique(aio(), SearchPath{}, store); auto state = evaluator->begin(aio()); - Value v; - state->eval(evaluator->parseExprFromString(data, CanonPath("/no-such-path")), v); + Value v = state->eval(evaluator->parseExprFromString(data, CanonPath("/no-such-path"))); Bindings & bindings(*evaluator->mem.allocBindings(0)); auto v2 = findAlongAttrPath(*state, settings.thisSystem, bindings, v).first; diff --git a/subprojects/nix-eval-jobs/src/worker.cc b/subprojects/nix-eval-jobs/src/worker.cc index 9910a1db2..886728547 100644 --- a/subprojects/nix-eval-jobs/src/worker.cc +++ b/subprojects/nix-eval-jobs/src/worker.cc @@ -50,7 +50,7 @@ static nix::Value releaseExprTopLevelValue(nix::EvalState &state, if (args.fromArgs) { nix::Expr &e = state.ctx.parseExprFromString(args.releaseExpr, nix::CanonPath::fromCwd()); - state.eval(e, vTop); + vTop = state.eval(e); } else { state.evalFile( state.aio.blockOn(nix::lookupFileArg(state.ctx, args.releaseExpr)) diff --git a/tests/unit/libexpr-support/tests/libexpr.hh b/tests/unit/libexpr-support/tests/libexpr.hh index 4a00a7d39..91c762d95 100644 --- a/tests/unit/libexpr-support/tests/libexpr.hh +++ b/tests/unit/libexpr-support/tests/libexpr.hh @@ -31,10 +31,12 @@ namespace nix { , state(*statePtr) { } - Value eval(std::string input, bool forceValue = true, const FeatureSettings & fSettings = featureSettings) { - Value v; + Value eval( + std::string input, bool forceValue = true, const FeatureSettings & fSettings = featureSettings + ) + { Expr & e = evaluator.parseExprFromString(input, CanonPath::root, fSettings); - state.eval(e, v); + Value v = state.eval(e); if (forceValue) state.forceValue(v, noPos); return v; diff --git a/tests/unit/libexpr/value/print.cc b/tests/unit/libexpr/value/print.cc index ee24fce0b..24d21516c 100644 --- a/tests/unit/libexpr/value/print.cc +++ b/tests/unit/libexpr/value/print.cc @@ -435,9 +435,8 @@ TEST_F(ValuePrintingTests, ansiColorsDerivation) TEST_F(ValuePrintingTests, ansiColorsError) { - Value vError; auto & e = evaluator.parseExprFromString("{ a = throw \"uh oh!\"; }", {CanonPath::root}); - state.eval(e, vError); + Value vError = state.eval(e); test( vError.attrs()->begin()->value, @@ -451,11 +450,10 @@ TEST_F(ValuePrintingTests, ansiColorsError) TEST_F(ValuePrintingTests, ansiColorsDerivationError) { - Value vAttrs; auto & e = evaluator.parseExprFromString( "{ type = \"derivation\"; drvPath = throw \"uh oh!\"; }", {CanonPath::root} ); - state.eval(e, vAttrs); + Value vAttrs = state.eval(e); test(vAttrs, "{ drvPath = " @@ -486,8 +484,7 @@ TEST_F(ValuePrintingTests, ansiColorsDerivationError) TEST_F(ValuePrintingTests, ansiColorsAssert) { auto & e = evaluator.parseExprFromString("{ a = assert false; 1; }", {CanonPath::root}); - Value v; - state.eval(e, v); + Value v = state.eval(e); ASSERT_EQ(v.type(), nAttrs); test(