diff --git a/lix/libexpr/eval.cc b/lix/libexpr/eval.cc index 7a5b29558..311f31a78 100644 --- a/lix/libexpr/eval.cc +++ b/lix/libexpr/eval.cc @@ -280,12 +280,10 @@ EvalBuiltins::EvalBuiltins( EvalPaths::EvalPaths( AsyncIoRoot & aio, const ref & store, - const ref buildStore, SearchPath searchPath, EvalErrorContext & errors ) : store(store) - , buildStore(buildStore) , searchPath_(std::move(searchPath)) , errors(errors) { @@ -321,7 +319,7 @@ Evaluator::Evaluator( std::function debugRepl ) : s(symbols) - , paths(aio, store, buildStore ? ref(buildStore) : store, [&] { + , paths(aio, store, [&] { SearchPath searchPath; if (!evalSettings.pureEval) { for (auto & i : _searchPath.elements) @@ -334,6 +332,7 @@ Evaluator::Evaluator( , builtins(mem, symbols, paths.searchPath(), store->config().storeDir) , repair(NoRepair) , store(store) + , buildStore(buildStore ? ref(buildStore) : store) , debug{ debugRepl ? std::make_unique( positions, diff --git a/lix/libexpr/eval.hh b/lix/libexpr/eval.hh index e69d251ce..a464ac05a 100644 --- a/lix/libexpr/eval.hh +++ b/lix/libexpr/eval.hh @@ -365,10 +365,6 @@ struct EvalErrorContext class EvalPaths { ref store; - /** - * Store used to build stuff. - */ - ref buildStore; SearchPath searchPath_; EvalErrorContext & errors; @@ -376,7 +372,6 @@ public: EvalPaths( AsyncIoRoot & aio, const ref & store, - const ref buildStore, SearchPath searchPath, EvalErrorContext & errors ); @@ -484,12 +479,6 @@ public: * single `NixStringContextElem::Opaque` element of that store path. */ void mkStorePathString(const StorePath & storePath, Value & v); - - /** - * Realise the given context, and return a mapping from the placeholders - * used to construct the associated value to their final store path - */ - [[nodiscard]] kj::Promise> realiseContext(const NixStringContext & context); }; struct EvalStatistics @@ -540,6 +529,11 @@ public: */ const ref store; + /** + * Store used to build stuff. + */ + ref buildStore; + std::unique_ptr debug; EvalErrorContext errors; @@ -713,6 +707,12 @@ public: std::string_view forceString(Value & v, NixStringContext & context, const PosIdx pos, std::string_view errorCtx); std::string_view forceStringNoCtx(Value & v, const PosIdx pos, std::string_view errorCtx); + /** + * Realise the given context, and return a mapping from the placeholders + * used to construct the associated value to their final store path + */ + [[nodiscard]] StringMap realiseContext(const NixStringContext & context); + public: /** * @return true iff the value `v` denotes a derivation (i.e. a diff --git a/lix/libexpr/primops.cc b/lix/libexpr/primops.cc index d33bd4d47..98f3e70ef 100644 --- a/lix/libexpr/primops.cc +++ b/lix/libexpr/primops.cc @@ -42,23 +42,17 @@ namespace nix { * Miscellaneous *************************************************************/ -kj::Promise> EvalPaths::realiseContext(const NixStringContext & context) -try { +StringMap EvalState::realiseContext(const NixStringContext & context) +{ std::vector drvs; StringMap res; for (auto & c : context) { - // NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines) - auto ensureValid = [&](const StorePath & p) -> kj::Promise> { - try { - if (!TRY_AWAIT(store->isValidPath(p))) - errors.make(store->printStorePath(p)).debugThrow(); - co_return result::success(); - } catch (...) { - co_return result::current_exception(); - } + auto ensureValid = [&](const StorePath & p) { + if (!aio.blockOn(ctx.store->isValidPath(p))) + ctx.errors.make(ctx.store->printStorePath(p)).debugThrow(); }; - TRY_AWAIT(std::visit(overloaded { + std::visit(overloaded { [&](const NixStringContextElem::Built & b) { drvs.push_back(DerivedPath::Built { .drvPath = b.drvPath, @@ -67,36 +61,36 @@ try { return ensureValid(b.drvPath->getBaseStorePath()); }, [&](const NixStringContextElem::Opaque & o) { - auto ctxS = store->printStorePath(o.path); + auto ctxS = ctx.store->printStorePath(o.path); res.insert_or_assign(ctxS, ctxS); return ensureValid(o.path); }, [&](const NixStringContextElem::DrvDeep & d) { /* Treat same as Opaque */ - auto ctxS = store->printStorePath(d.drvPath); + auto ctxS = ctx.store->printStorePath(d.drvPath); res.insert_or_assign(ctxS, ctxS); return ensureValid(d.drvPath); }, - }, c.raw)); + }, c.raw); } - if (drvs.empty()) co_return StringMap{}; + if (drvs.empty()) return StringMap{}; if (!evalSettings.enableImportFromDerivation) - errors.make( + ctx.errors.make( "cannot build '%1%' during evaluation because the option 'allow-import-from-derivation' is disabled", - drvs.begin()->to_string(*store) + drvs.begin()->to_string(*ctx.store) ).debugThrow(); /* Build/substitute the context. */ std::vector buildReqs; for (auto & d : drvs) buildReqs.emplace_back(DerivedPath { d }); - TRY_AWAIT(buildStore->buildPaths(buildReqs, bmNormal, store)); + aio.blockOn(ctx.buildStore->buildPaths(buildReqs, bmNormal, ctx.store)); StorePathSet outputsToCopyAndAllow; for (auto & drv : drvs) { - auto outputs = TRY_AWAIT(resolveDerivedPath(*buildStore, drv, &*store)); + auto outputs = aio.blockOn(resolveDerivedPath(*ctx.buildStore, drv, &*ctx.store)); for (auto & [outputName, outputPath] : outputs) { outputsToCopyAndAllow.insert(outputPath); @@ -108,24 +102,22 @@ try { .drvPath = drv.drvPath, .output = outputName, }).render(), - buildStore->printStorePath(outputPath) + ctx.buildStore->printStorePath(outputPath) ); } } } - if (store != buildStore) TRY_AWAIT(copyClosure(*buildStore, *store, outputsToCopyAndAllow)); - if (allowedPaths) { - for (auto & outputPath : outputsToCopyAndAllow) { - /* Add the output of this derivations to the allowed - paths. */ - allowPath(outputPath); - } + if (ctx.store != ctx.buildStore) { + aio.blockOn(copyClosure(*ctx.buildStore, *ctx.store, outputsToCopyAndAllow)); + } + for (auto & outputPath : outputsToCopyAndAllow) { + /* Add the output of this derivations to the allowed + paths. */ + ctx.paths.allowPath(outputPath); } - co_return res; -} catch (...) { - co_return result::current_exception(); + return res; } static auto realisePath(EvalState & state, const PosIdx pos, Value & v, auto checkFn) @@ -135,7 +127,7 @@ static auto realisePath(EvalState & state, const PosIdx pos, Value & v, auto che auto path = state.coerceToPath(noPos, v, context, "while realising the context of a path"); try { - StringMap rewrites = state.aio.blockOn(state.ctx.paths.realiseContext(context)); + StringMap rewrites = state.realiseContext(context); return checkFn(SourcePath(CanonPath( state.ctx.paths.toRealPath(rewriteStrings(path.canonical().abs(), rewrites), context) @@ -332,7 +324,7 @@ void prim_exec(EvalState & state, const PosIdx pos, Value * * args, Value & v) false, false).toOwned()); } try { - auto _ = state.aio.blockOn(state.ctx.paths.realiseContext(context)); // FIXME: Handle CA derivations + auto _ = state.realiseContext(context); // FIXME: Handle CA derivations } catch (InvalidPathError & e) { e.addTrace(state.ctx.positions[pos], "while realising the context for builtins.exec"); throw; @@ -1328,7 +1320,7 @@ static void prim_findFile(EvalState & state, const PosIdx pos, Value * * args, V false, false).toOwned(); try { - auto rewrites = state.aio.blockOn(state.ctx.paths.realiseContext(context)); + auto rewrites = state.realiseContext(context); path = rewriteStrings(path, rewrites); } catch (InvalidPathError & e) { state.ctx.errors.make( @@ -1520,7 +1512,7 @@ static void addPath( try { // FIXME: handle CA derivation outputs (where path needs to // be rewritten to the actual output). - auto rewrites = state.aio.blockOn(state.ctx.paths.realiseContext(context)); + auto rewrites = state.realiseContext(context); path = rewriteStrings(path, rewrites); Path realPath = path;