From 650809f66e49cf83c8dffd8b9ff07083747c7418 Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Wed, 27 Nov 2024 02:09:08 +0100 Subject: [PATCH] drop unnecessary EvalState shared pointers currently ref<>s are used to share eval states between whatever created that state and the various repl instances. repls however do not own any eval states, not even partially. they only provide interactive use of a previously allocated state that is owned by something else, notably for debug repls which are run from *within* an evaluation which may already be wrapped by another repl instance. presumably this was originally set up like this to guarantee memory safety, even though it's never needed. Change-Id: I29a2cd1d4245c077f9270452a0873d4c47448729 --- lix/libcmd/repl.cc | 192 ++++++++++++++++++++--------------------- lix/libcmd/repl.hh | 11 ++- lix/libexpr/eval.cc | 2 +- lix/libexpr/eval.hh | 4 +- lix/libexpr/primops.cc | 2 +- lix/nix/repl.cc | 2 +- 6 files changed, 108 insertions(+), 105 deletions(-) diff --git a/lix/libcmd/repl.cc b/lix/libcmd/repl.cc index 8a4547e34..c31421d1d 100644 --- a/lix/libcmd/repl.cc +++ b/lix/libcmd/repl.cc @@ -133,7 +133,7 @@ struct NixRepl box_ptr interacter; - NixRepl(const SearchPath & searchPath, nix::ref store,ref state, + NixRepl(const SearchPath & searchPath, nix::ref store, EvalState & state, std::function getValues); virtual ~NixRepl() = default; @@ -206,7 +206,7 @@ struct NixRepl Value & v, unsigned int maxDepth = std::numeric_limits::max()) { - ::nix::printValue(*state, str, v, PrintOptions { + ::nix::printValue(state, str, v, PrintOptions { .ansiColors = true, .force = true, .derivationPaths = true, @@ -232,12 +232,12 @@ static box_ptr makeInteracter() { return make_box_ptr(getDataDir() + "/nix/repl-history"); } -NixRepl::NixRepl(const SearchPath & searchPath, nix::ref store, ref state, +NixRepl::NixRepl(const SearchPath & searchPath, nix::ref store, EvalState & state, std::function getValues) : AbstractNixRepl(state) , debugTraceIndex(0) , getValues(getValues) - , staticEnv(new StaticEnv(nullptr, state->staticBaseEnv.get())) + , staticEnv(new StaticEnv(nullptr, state.staticBaseEnv.get())) , interacter(makeInteracter()) { } @@ -285,7 +285,7 @@ ReplExitStatus NixRepl::mainLoop() { if (isFirstRepl) { std::string_view debuggerNotice = ""; - if (state->debugRepl) { + if (state.debugRepl) { debuggerNotice = " debugger"; } notice("Lix %1%%2%\nType :? for help.", nixVersion, debuggerNotice); @@ -310,7 +310,7 @@ ReplExitStatus NixRepl::mainLoop() // number of chars as the prompt. if (!interacter->getLine(input, input.empty() ? ReplPromptType::ReplPrompt : ReplPromptType::ContinuationPrompt)) { // Ctrl-D should exit the debugger. - state->debugStop = false; + state.debugStop = false; logger->cout(""); // TODO: Should Ctrl-D exit just the current debugger session or // the entire program? @@ -366,7 +366,7 @@ StringSet NixRepl::completePrefix(const std::string & prefix) } } - if (state->debugRepl) { + if (state.debugRepl) { for (auto const & colonCmd : this->DEBUG_COMMANDS) { if (colonCmd.starts_with(prefix)) { completions.insert(std::string(colonCmd)); @@ -416,9 +416,9 @@ StringSet NixRepl::completePrefix(const std::string & prefix) } } else { /* Temporarily disable the debugger, to avoid re-entering readline. */ - auto debug_repl = state->debugRepl; - state->debugRepl = nullptr; - Finally restoreDebug([&]() { state->debugRepl = debug_repl; }); + auto debug_repl = state.debugRepl; + state.debugRepl = nullptr; + Finally restoreDebug([&]() { state.debugRepl = debug_repl; }); try { /* This is an expression that should evaluate to an attribute set. Evaluate it to get the names of the @@ -428,11 +428,11 @@ StringSet NixRepl::completePrefix(const std::string & prefix) Expr & e = parseString(expr); Value v; - e.eval(*state, *env, v); - state->forceAttrs(v, noPos, "while evaluating an attrset for the purpose of completion (this error should not be displayed; file an issue?)"); + e.eval(state, *env, v); + state.forceAttrs(v, noPos, "while evaluating an attrset for the purpose of completion (this error should not be displayed; file an issue?)"); for (auto & i : *v.attrs) { - std::string_view name = state->symbols[i.name]; + std::string_view name = state.symbols[i.name]; if (name.substr(0, cur2.size()) != cur2) continue; completions.insert(concatStrings(prev, expr, ".", name)); } @@ -470,14 +470,14 @@ static bool isVarName(std::string_view s) StorePath NixRepl::getDerivationPath(Value & v) { - auto drvInfo = getDerivation(*state, v, false); + auto drvInfo = getDerivation(state, v, false); if (!drvInfo) throw Error("expression does not evaluate to a derivation, so I can't build it"); auto drvPath = drvInfo->queryDrvPath(); if (!drvPath) throw Error("expression did not evaluate to a valid derivation (no 'drvPath' attribute)"); - if (!state->store->isValidPath(*drvPath)) - throw Error("expression evaluated to invalid derivation '%s'", state->store->printStorePath(*drvPath)); + if (!state.store->isValidPath(*drvPath)) + throw Error("expression evaluated to invalid derivation '%s'", state.store->printStorePath(*drvPath)); return *drvPath; } @@ -485,13 +485,13 @@ void NixRepl::loadDebugTraceEnv(DebugTrace & dt) { initEnv(); - auto se = state->getStaticEnv(dt.expr); + auto se = state.getStaticEnv(dt.expr); if (se) { - auto vm = mapStaticEnvBindings(state->symbols, *se.get(), dt.env); + auto vm = mapStaticEnvBindings(state.symbols, *se.get(), dt.env); // add staticenv vars. for (auto & [name, value] : *(vm.get())) - addVarToScope(state->symbols.create(name), *value); + addVarToScope(state.symbols.create(name), *value); } } @@ -541,7 +541,7 @@ ProcessLineResult NixRepl::processLine(std::string line) << " errors\n" << " :?, :help Brings up this help menu\n" ; - if (state->debugRepl) { + if (state.debugRepl) { std::cout << "\n" << " Debug mode commands\n" @@ -556,49 +556,49 @@ ProcessLineResult NixRepl::processLine(std::string line) } - else if (state->debugRepl && (command == ":bt" || command == ":backtrace")) { - for (const auto & [idx, i] : enumerate(state->debugTraces)) { + else if (state.debugRepl && (command == ":bt" || command == ":backtrace")) { + for (const auto & [idx, i] : enumerate(state.debugTraces)) { std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; - showDebugTrace(std::cout, state->positions, i); + showDebugTrace(std::cout, state.positions, i); } } - else if (state->debugRepl && (command == ":env")) { - for (const auto & [idx, i] : enumerate(state->debugTraces)) { + else if (state.debugRepl && (command == ":env")) { + for (const auto & [idx, i] : enumerate(state.debugTraces)) { if (idx == debugTraceIndex) { - printEnvBindings(*state, i.expr, i.env); + printEnvBindings(state, i.expr, i.env); break; } } } - else if (state->debugRepl && (command == ":st")) { + else if (state.debugRepl && (command == ":st")) { try { // change the DebugTrace index. debugTraceIndex = stoi(arg); } catch (...) { } - for (const auto & [idx, i] : enumerate(state->debugTraces)) { + for (const auto & [idx, i] : enumerate(state.debugTraces)) { if (idx == debugTraceIndex) { std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; - showDebugTrace(std::cout, state->positions, i); + showDebugTrace(std::cout, state.positions, i); std::cout << std::endl; - printEnvBindings(*state, i.expr, i.env); + printEnvBindings(state, i.expr, i.env); loadDebugTraceEnv(i); break; } } } - else if (state->debugRepl && (command == ":s" || command == ":step")) { + else if (state.debugRepl && (command == ":s" || command == ":step")) { // set flag to stop at next DebugTrace; exit repl. - state->debugStop = true; + state.debugStop = true; return ProcessLineResult::Continue; } - else if (state->debugRepl && (command == ":c" || command == ":continue")) { + else if (state.debugRepl && (command == ":c" || command == ":continue")) { // set flag to run to next breakpoint or end of program; exit repl. - state->debugStop = false; + state.debugStop = false; return ProcessLineResult::Continue; } @@ -609,7 +609,7 @@ ProcessLineResult NixRepl::processLine(std::string line) } else if (command == ":l" || command == ":load") { - state->resetFileCache(); + state.resetFileCache(); loadFile(arg); } @@ -618,7 +618,7 @@ ProcessLineResult NixRepl::processLine(std::string line) } else if (command == ":r" || command == ":reload") { - state->resetFileCache(); + state.resetFileCache(); reloadFiles(); } @@ -629,17 +629,17 @@ ProcessLineResult NixRepl::processLine(std::string line) const auto [path, line] = [&] () -> std::pair { if (v.type() == nPath || v.type() == nString) { NixStringContext context; - auto path = state->coerceToPath(noPos, v, context, "while evaluating the filename to edit"); + auto path = state.coerceToPath(noPos, v, context, "while evaluating the filename to edit"); return {path, 0}; } else if (v.isLambda()) { - auto pos = state->positions[v.lambda.fun->pos]; + auto pos = state.positions[v.lambda.fun->pos]; if (auto path = std::get_if(&pos.origin)) return {*path, pos.line}; else throw Error("'%s' cannot be shown in an editor", pos); } else { // assume it's a derivation - return findPackageFilename(*state, v, arg); + return findPackageFilename(state, v, arg); } }(); @@ -654,8 +654,8 @@ ProcessLineResult NixRepl::processLine(std::string line) // Reload right after exiting the editor if path is not in store // Store is immutable, so there could be no changes, so there's no need to reload - if (!state->store->isInStore(path.resolveSymlinks().path.abs())) { - state->resetFileCache(); + if (!state.store->isInStore(path.resolveSymlinks().path.abs())) { + state.resetFileCache(); reloadFiles(); } } @@ -670,15 +670,15 @@ ProcessLineResult NixRepl::processLine(std::string line) Value v, f, result; evalString(arg, v); evalString("drv: (import {}).runCommand \"shell\" { buildInputs = [ drv ]; } \"\"", f); - state->callFunction(f, v, result, PosIdx()); + state.callFunction(f, v, result, PosIdx()); StorePath drvPath = getDerivationPath(result); - runNix("nix-shell", {state->store->printStorePath(drvPath)}); + runNix("nix-shell", {state.store->printStorePath(drvPath)}); } else if (command == ":log") { StorePath drvPath = ([&] { - auto maybeDrvPath = state->store->maybeParseStorePath(arg); + auto maybeDrvPath = state.store->maybeParseStorePath(arg); if (maybeDrvPath && maybeDrvPath->isDerivation()) { return std::move(*maybeDrvPath); } else { @@ -687,7 +687,7 @@ ProcessLineResult NixRepl::processLine(std::string line) return getDerivationPath(v); } })(); - Path drvPathRaw = state->store->printStorePath(drvPath); + Path drvPathRaw = state.store->printStorePath(drvPath); settings.readOnlyMode = true; Finally roModeReset([&]() { @@ -695,7 +695,7 @@ ProcessLineResult NixRepl::processLine(std::string line) }); auto subs = getDefaultSubstituters(); - subs.push_front(state->store); + subs.push_front(state.store); bool foundLog = false; RunPager pager; @@ -722,7 +722,7 @@ ProcessLineResult NixRepl::processLine(std::string line) Value v; evalString(arg, v); StorePath drvPath = getDerivationPath(v); - Path drvPathRaw = state->store->printStorePath(drvPath); + Path drvPathRaw = state.store->printStorePath(drvPath); if (command == ":b" || command == ":bl") { // TODO: this only shows a progress bar for explicitly initiated builds, @@ -734,22 +734,22 @@ ProcessLineResult NixRepl::processLine(std::string line) logger->pause(); }); - state->store->buildPaths({ + state.store->buildPaths({ DerivedPath::Built { .drvPath = makeConstantStorePathRef(drvPath), .outputs = OutputsSpec::All { }, }, }); - auto drv = state->store->readDerivation(drvPath); + auto drv = state.store->readDerivation(drvPath); logger->cout("\nThis derivation produced the following outputs:"); - for (auto & [outputName, outputPath] : state->store->queryDerivationOutputMap(drvPath)) { - auto localStore = state->store.dynamic_pointer_cast(); + for (auto & [outputName, outputPath] : state.store->queryDerivationOutputMap(drvPath)) { + auto localStore = state.store.dynamic_pointer_cast(); if (localStore && command == ":bl") { std::string symlink = "repl-result-" + outputName; localStore->addPermRoot(outputPath, absPath(symlink)); - logger->cout(" ./%s -> %s", symlink, state->store->printStorePath(outputPath)); + logger->cout(" ./%s -> %s", symlink, state.store->printStorePath(outputPath)); } else { - logger->cout(" %s -> %s", outputName, state->store->printStorePath(outputPath)); + logger->cout(" %s -> %s", outputName, state.store->printStorePath(outputPath)); } } } else if (command == ":i") { @@ -771,14 +771,14 @@ ProcessLineResult NixRepl::processLine(std::string line) } else if (command == ":q" || command == ":quit") { - state->debugStop = false; + state.debugStop = false; return ProcessLineResult::Quit; } else if (command == ":doc") { Value v; evalString(arg, v); - if (auto doc = state->getDoc(v)) { + if (auto doc = state.getDoc(v)) { std::string markdown; if (!doc->args.empty() && doc->name) { @@ -795,7 +795,7 @@ ProcessLineResult NixRepl::processLine(std::string line) logger->cout(trim(renderMarkdownToTerminal(markdown))); } else if (v.isLambda()) { - auto pos = state->positions[v.lambda.fun->pos]; + auto pos = state.positions[v.lambda.fun->pos]; if (auto path = std::get_if(&pos.origin)) { // Path and position have now been obtained, feed to nix-doc library to get data. auto docComment = lambdaDocsForPos(*path, pos); @@ -838,9 +838,9 @@ ProcessLineResult NixRepl::processLine(std::string line) isVarName(name = removeWhitespace(line.substr(0, p)))) { Expr & e = parseString(line.substr(p + 1)); - Value & v(*state->allocValue()); + Value & v(*state.allocValue()); v.mkThunk(env, e); - addVarToScope(state->symbols.create(name), v); + addVarToScope(state.symbols.create(name), v); } else { Value v; evalString(line, v); @@ -857,8 +857,8 @@ void NixRepl::loadFile(const Path & path) loadedFiles.remove(path); loadedFiles.push_back(path); Value v, v2; - state->evalFile(lookupFileArg(*state, path), v); - state->autoCallFunction(*autoArgs, v, v2); + state.evalFile(lookupFileArg(state, path), v); + state.autoCallFunction(*autoArgs, v, v2); addAttrsToScope(v2); } @@ -873,8 +873,8 @@ void NixRepl::loadFlake(const std::string & flakeRefS) Value v; - flake::callFlake(*state, - flake::lockFlake(*state, flakeRef, + flake::callFlake(state, + flake::lockFlake(state, flakeRef, flake::LockFlags { .updateLockFile = false, .useRegistries = !evalSettings.pureEval, @@ -887,14 +887,14 @@ void NixRepl::loadFlake(const std::string & flakeRefS) void NixRepl::initEnv() { - env = &state->allocEnv(envSize); - env->up = &state->baseEnv; + env = &state.allocEnv(envSize); + env->up = &state.baseEnv; displ = 0; staticEnv->vars.clear(); varNames.clear(); - for (auto & i : state->staticBaseEnv->vars) - varNames.emplace(state->symbols[i.first]); + for (auto & i : state.staticBaseEnv->vars) + varNames.emplace(state.symbols[i.first]); } @@ -933,9 +933,9 @@ void NixRepl::loadReplOverlays() notice("Loading '%1%'...", Magenta("repl-overlays")); auto replInitFilesFunction = getReplOverlaysEvalFunction(); - Value &newAttrs(*state->allocValue()); + Value &newAttrs(*state.allocValue()); SmallValueVector<3> args = {replInitInfo(), bindingsToAttrs(), replOverlays()}; - state->callFunction( + state.callFunction( *replInitFilesFunction, args.size(), args.data(), @@ -958,25 +958,25 @@ Value * NixRepl::getReplOverlaysEvalFunction() } auto evalReplInitFilesPath = CanonPath::root + "repl-overlays.nix"; - *replOverlaysEvalFunction = state->allocValue(); + *replOverlaysEvalFunction = state.allocValue(); auto code = #include "repl-overlays.nix.gen.hh" ; - auto & expr = state->parseExprFromString( + auto & expr = state.parseExprFromString( code, SourcePath(evalReplInitFilesPath), - state->staticBaseEnv + state.staticBaseEnv ); - state->eval(expr, **replOverlaysEvalFunction); + state.eval(expr, **replOverlaysEvalFunction); return *replOverlaysEvalFunction; } Value * NixRepl::replOverlays() { - Value * replInits(state->allocValue()); - state->mkList(*replInits, evalSettings.replOverlays.get().size()); + Value * replInits(state.allocValue()); + state.mkList(*replInits, evalSettings.replOverlays.get().size()); Value ** replInitElems = replInits->listElems(); size_t i = 0; @@ -986,10 +986,10 @@ Value * NixRepl::replOverlays() auto replInit = evalFile(sourcePath); if (!replInit->isLambda()) { - state->error( + state.error( "Expected `repl-overlays` to be a lambda but found %1%: %2%", showType(*replInit), - ValuePrinter(*state, *replInit, errorPrintOptions) + ValuePrinter(state, *replInit, errorPrintOptions) ) .atPos(replInit->determinePos(noPos)) .debugThrow(); @@ -997,7 +997,7 @@ Value * NixRepl::replOverlays() if (replInit->lambda.fun->hasFormals() && !replInit->lambda.fun->formals->ellipsis) { - state->error( + state.error( "Expected first argument of %1% to have %2% to allow future versions of Lix to add additional attributes to the argument", "repl-overlays", "..." @@ -1016,13 +1016,13 @@ Value * NixRepl::replOverlays() Value * NixRepl::replInitInfo() { - auto builder = state->buildBindings(2); + auto builder = state.buildBindings(2); - Value * currentSystem(state->allocValue()); + Value * currentSystem(state.allocValue()); currentSystem->mkString(evalSettings.getCurrentSystem()); - builder.insert(state->symbols.create("currentSystem"), currentSystem); + builder.insert(state.symbols.create("currentSystem"), currentSystem); - Value * info(state->allocValue()); + Value * info(state.allocValue()); info->mkAttrs(builder.finish()); return info; } @@ -1030,14 +1030,14 @@ Value * NixRepl::replInitInfo() void NixRepl::addAttrsToScope(Value & attrs) { - state->forceAttrs(attrs, [&]() { return attrs.determinePos(noPos); }, "while evaluating an attribute set to be merged in the global scope"); + state.forceAttrs(attrs, [&]() { return attrs.determinePos(noPos); }, "while evaluating an attribute set to be merged in the global scope"); if (displ + attrs.attrs->size() >= envSize) throw Error("environment full; cannot add more variables"); for (auto & i : *attrs.attrs) { staticEnv->vars.emplace_back(i.name, displ); env->values[displ++] = i.value; - varNames.emplace(state->symbols[i.name]); + varNames.emplace(state.symbols[i.name]); } staticEnv->sort(); staticEnv->deduplicate(); @@ -1054,17 +1054,17 @@ void NixRepl::addVarToScope(const Symbol name, Value & v) staticEnv->vars.emplace_back(name, displ); staticEnv->sort(); env->values[displ++] = &v; - varNames.emplace(state->symbols[name]); + varNames.emplace(state.symbols[name]); } Value * NixRepl::bindingsToAttrs() { - auto builder = state->buildBindings(staticEnv->vars.size()); + auto builder = state.buildBindings(staticEnv->vars.size()); for (auto & [symbol, displacement] : staticEnv->vars) { builder.insert(symbol, env->values[displacement]); } - Value * attrs(state->allocValue()); + Value * attrs(state.allocValue()); attrs->mkAttrs(builder.finish()); return attrs; } @@ -1072,30 +1072,30 @@ Value * NixRepl::bindingsToAttrs() Expr & NixRepl::parseString(std::string s) { - return state->parseExprFromString(std::move(s), state->rootPath(CanonPath::fromCwd()), staticEnv); + return state.parseExprFromString(std::move(s), state.rootPath(CanonPath::fromCwd()), staticEnv); } void NixRepl::evalString(std::string s, Value & v) { Expr & e = parseString(s); - e.eval(*state, *env, v); - state->forceValue(v, v.determinePos(noPos)); + e.eval(state, *env, v); + state.forceValue(v, v.determinePos(noPos)); } Value * NixRepl::evalFile(SourcePath & path) { - auto & expr = state->parseExprFromFile(path, staticEnv); - Value * result(state->allocValue()); - expr.eval(*state, *env, *result); - state->forceValue(*result, result->determinePos(noPos)); + auto & expr = state.parseExprFromFile(path, staticEnv); + Value * result(state.allocValue()); + expr.eval(state, *env, *result); + state.forceValue(*result, result->determinePos(noPos)); return result; } ReplExitStatus AbstractNixRepl::run( const SearchPath & searchPath, nix::ref store, - ref state, + EvalState & state, std::function getValues, const ValMap & extraEnv, Bindings * autoArgs @@ -1106,12 +1106,12 @@ ReplExitStatus AbstractNixRepl::run( repl.autoArgs = autoArgs; repl.initEnv(); for (auto & [name, value] : extraEnv) { - repl.addVarToScope(repl.state->symbols.create(name), *value); + repl.addVarToScope(repl.state.symbols.create(name), *value); } return repl.mainLoop(); } -ReplExitStatus AbstractNixRepl::runSimple(ref evalState, const ValMap & extraEnv) +ReplExitStatus AbstractNixRepl::runSimple(EvalState & evalState, const ValMap & extraEnv) { return run( {}, openStore(), evalState, [] { return AnnotatedValues{}; }, extraEnv, nullptr diff --git a/lix/libcmd/repl.hh b/lix/libcmd/repl.hh index 12b3198a2..0e24ba573 100644 --- a/lix/libcmd/repl.hh +++ b/lix/libcmd/repl.hh @@ -12,23 +12,26 @@ struct AbstractNixRepl static ReplExitStatus run(const SearchPath & searchPath, nix::ref store, - ref state, + EvalState & state, std::function getValues, const ValMap & extraEnv, Bindings * autoArgs); static ReplExitStatus runSimple( - ref evalState, + EvalState & evalState, const ValMap & extraEnv); protected: - ref state; + EvalState & state; Bindings * autoArgs; - AbstractNixRepl(ref state) + AbstractNixRepl(EvalState & state) : state(state) { } + virtual ~AbstractNixRepl() + { } + virtual void initEnv() = 0; virtual ReplExitStatus mainLoop() = 0; diff --git a/lix/libexpr/eval.cc b/lix/libexpr/eval.cc index 5bc90ec34..79fc23dd7 100644 --- a/lix/libexpr/eval.cc +++ b/lix/libexpr/eval.cc @@ -669,7 +669,7 @@ void EvalState::runDebugRepl(const Error * error, const Env & env, const Expr & if (se) { auto vm = mapStaticEnvBindings(symbols, *se.get(), env); DebuggerGuard _guard(inDebugger); - auto exitStatus = (debugRepl)(ref(shared_from_this()), *vm); + auto exitStatus = (debugRepl)(*this, *vm); switch (exitStatus) { case ReplExitStatus::QuitAll: if (error) diff --git a/lix/libexpr/eval.hh b/lix/libexpr/eval.hh index c7fd56a7f..e011db998 100644 --- a/lix/libexpr/eval.hh +++ b/lix/libexpr/eval.hh @@ -153,7 +153,7 @@ struct DebugTrace { }; -class EvalState : public std::enable_shared_from_this +class EvalState { public: SymbolTable symbols; @@ -212,7 +212,7 @@ public: /** * Debugger */ - std::function es, ValMap const & extraEnv)> debugRepl; + std::function debugRepl; bool debugStop; bool inDebugger = false; int trylevel; diff --git a/lix/libexpr/primops.cc b/lix/libexpr/primops.cc index 9bc32fd80..deb47c15a 100644 --- a/lix/libexpr/primops.cc +++ b/lix/libexpr/primops.cc @@ -640,7 +640,7 @@ static void prim_tryEval(EvalState & state, const PosIdx pos, Value * * args, Va /* increment state.trylevel, and decrement it when this function returns. */ MaintainCount trylevel(state.trylevel); - std::function es, ValMap const & extraEnv)> savedDebugRepl; + std::function savedDebugRepl; if (state.debugRepl && evalSettings.ignoreExceptionsDuringTry) { /* to prevent starting the repl from exceptions withing a tryEval, null it. */ diff --git a/lix/nix/repl.cc b/lix/nix/repl.cc index 186c10b51..8e37ccbf7 100644 --- a/lix/nix/repl.cc +++ b/lix/nix/repl.cc @@ -86,7 +86,7 @@ struct CmdRepl : RawInstallablesCommand } return values; }; - AbstractNixRepl::run(searchPath, openStore(), state, getValues, {}, getAutoArgs(*state)); + AbstractNixRepl::run(searchPath, openStore(), *state, getValues, {}, getAutoArgs(*state)); } };