libexpr: move realiseContext back to EvalState
throwing debuggable errors is effectively never-async, and realising a context requires acquiring a context first, i.e. evaluating something. since realiseContext is only used by primops the effect is very minor. Change-Id: I73b3b277188700e5cdf6f30599fb6674ec1ab753
This commit is contained in:
+2
-3
@@ -280,12 +280,10 @@ EvalBuiltins::EvalBuiltins(
|
||||
EvalPaths::EvalPaths(
|
||||
AsyncIoRoot & aio,
|
||||
const ref<Store> & store,
|
||||
const ref<Store> buildStore,
|
||||
SearchPath searchPath,
|
||||
EvalErrorContext & errors
|
||||
)
|
||||
: store(store)
|
||||
, buildStore(buildStore)
|
||||
, searchPath_(std::move(searchPath))
|
||||
, errors(errors)
|
||||
{
|
||||
@@ -321,7 +319,7 @@ Evaluator::Evaluator(
|
||||
std::function<ReplExitStatus(EvalState & es, ValMap const & extraEnv)> 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<DebugState>(
|
||||
positions,
|
||||
|
||||
+11
-11
@@ -365,10 +365,6 @@ struct EvalErrorContext
|
||||
class EvalPaths
|
||||
{
|
||||
ref<Store> store;
|
||||
/**
|
||||
* Store used to build stuff.
|
||||
*/
|
||||
ref<Store> buildStore;
|
||||
SearchPath searchPath_;
|
||||
EvalErrorContext & errors;
|
||||
|
||||
@@ -376,7 +372,6 @@ public:
|
||||
EvalPaths(
|
||||
AsyncIoRoot & aio,
|
||||
const ref<Store> & store,
|
||||
const ref<Store> 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<Result<StringMap>> realiseContext(const NixStringContext & context);
|
||||
};
|
||||
|
||||
struct EvalStatistics
|
||||
@@ -540,6 +529,11 @@ public:
|
||||
*/
|
||||
const ref<Store> store;
|
||||
|
||||
/**
|
||||
* Store used to build stuff.
|
||||
*/
|
||||
ref<Store> buildStore;
|
||||
|
||||
std::unique_ptr<DebugState> 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
|
||||
|
||||
+27
-35
@@ -42,23 +42,17 @@ namespace nix {
|
||||
* Miscellaneous
|
||||
*************************************************************/
|
||||
|
||||
kj::Promise<Result<StringMap>> EvalPaths::realiseContext(const NixStringContext & context)
|
||||
try {
|
||||
StringMap EvalState::realiseContext(const NixStringContext & context)
|
||||
{
|
||||
std::vector<DerivedPath::Built> drvs;
|
||||
StringMap res;
|
||||
|
||||
for (auto & c : context) {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines)
|
||||
auto ensureValid = [&](const StorePath & p) -> kj::Promise<Result<void>> {
|
||||
try {
|
||||
if (!TRY_AWAIT(store->isValidPath(p)))
|
||||
errors.make<InvalidPathError>(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<InvalidPathError>(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<EvalError>(
|
||||
ctx.errors.make<EvalError>(
|
||||
"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<DerivedPath> 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<EvalError>(
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user