libexpr: extract eval path handling into new type

Change-Id: Icf38113076a4dd0f8515a27b501f405033aec73b
This commit is contained in:
eldritch horrors 2024-12-03 20:38:41 +01:00
parent a65e9e5828
commit 32f7a93f71
15 changed files with 183 additions and 161 deletions

View file

@ -252,7 +252,7 @@ static void main_nix_build(std::string programName, Strings argv)
else
/* If we're in a #! script, interpret filenames
relative to the script. */
exprs.push_back(state->parseExprFromFile(resolveExprPath(state->checkSourcePath(lookupFileArg(*state,
exprs.push_back(state->parseExprFromFile(resolveExprPath(state->paths.checkSourcePath(lookupFileArg(*state,
inShebang && !packages ? absPath(i, absPath(dirOf(script))) : i)))));
}
}

View file

@ -166,7 +166,7 @@ static int main_nix_instantiate(std::string programName, Strings argv)
if (findFile) {
for (auto & i : files) {
auto p = state->findFile(i);
auto p = state->paths.findFile(i);
if (auto fn = p.getPhysicalPath())
std::cout << fn->abs() << std::endl;
else
@ -185,7 +185,7 @@ static int main_nix_instantiate(std::string programName, Strings argv)
for (auto & i : files) {
Expr & e = fromArgs
? state->parseExprFromString(i, CanonPath::fromCwd())
: state->parseExprFromFile(resolveExprPath(state->checkSourcePath(lookupFileArg(*state, i))));
: state->parseExprFromFile(resolveExprPath(state->paths.checkSourcePath(lookupFileArg(*state, i))));
processExpr(*state, attrPaths, parseOnly, strict, autoArgs,
evalOnly, outputKind, xmlOutputSourceLocation, e);
}

View file

@ -104,7 +104,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
/* Construct a Nix expression that calls the user environment
builder with the manifest as argument. */
auto attrs = state.buildBindings(3);
state.mkStorePathString(manifestFile, attrs.alloc("manifest"));
state.paths.mkStorePathString(manifestFile, attrs.alloc("manifest"));
attrs.insert(state.symbols.create("derivations"), &manifest);
Value args;
args.mkAttrs(attrs);

View file

@ -162,8 +162,8 @@ ProfileManifest::ProfileManifest(EvalState & state, const Path & profile)
}
} else if (pathExists(profile + "/manifest.nix")) {
// FIXME: needed because of pure mode; ugly.
state.allowPath(state.store->followLinksToStore(profile));
state.allowPath(state.store->followLinksToStore(profile + "/manifest.nix"));
state.paths.allowPath(state.store->followLinksToStore(profile));
state.paths.allowPath(state.store->followLinksToStore(profile + "/manifest.nix"));
auto drvInfos = queryInstalled(state, state.store->followLinksToStore(profile));

View file

@ -205,7 +205,7 @@ SourcePath lookupFileArg(EvalState & state, std::string_view fileArg)
return CanonPath(state.store->toRealPath(storePath));
} else if (fileArg.size() > 2 && fileArg.at(0) == '<' && fileArg.at(fileArg.size() - 1) == '>') {
Path p(fileArg.substr(1, fileArg.size() - 2));
return state.findFile(p);
return state.paths.findFile(p);
} else {
return CanonPath::fromCwd(fileArg);
}

View file

@ -215,7 +215,7 @@ void SourceExprCommand::completeInstallable(AddCompletions & completions, std::s
evalSettings.pureEval.override(false);
auto state = getEvalState();
Expr & e = state->parseExprFromFile(
resolveExprPath(state->checkSourcePath(lookupFileArg(*state, *file)))
resolveExprPath(state->paths.checkSourcePath(lookupFileArg(*state, *file)))
);
Value root;

View file

@ -271,44 +271,21 @@ EvalBuiltins::EvalBuiltins(
createBaseEnv(searchPath, storeDir);
}
EvalState::EvalState(
const SearchPath & _searchPath,
ref<Store> store,
std::shared_ptr<Store> buildStore,
std::function<ReplExitStatus(EvalState & es, ValMap const & extraEnv)> debugRepl)
: s(symbols)
, searchPath([&] {
SearchPath searchPath;
if (!evalSettings.pureEval) {
for (auto & i : _searchPath.elements)
searchPath.elements.emplace_back(SearchPath::Elem {i});
for (auto & i : evalSettings.nixPath.get())
searchPath.elements.emplace_back(SearchPath::Elem::parse(i));
}
return searchPath;
}())
, builtins(mem, symbols, searchPath, store->config().storeDir)
, repair(NoRepair)
, store(store)
, buildStore(buildStore ? buildStore : store)
, debug{
debugRepl ? std::make_unique<DebugState>(
positions,
symbols,
[this, debugRepl](const ValMap & extraEnv) { return debugRepl(*this, extraEnv); }
)
: nullptr
}
, errors{positions, debug.get()}
EvalPaths::EvalPaths(
const ref<Store> & store,
const ref<Store> buildStore,
SearchPath searchPath,
EvalErrorContext & errors
)
: store(store)
, buildStore(buildStore)
, searchPath_(std::move(searchPath))
, errors(errors)
{
countCalls = getEnv("NIX_COUNT_CALLS").value_or("0") != "0";
static_assert(sizeof(Env) <= 16, "environment must be <= 16 bytes");
if (evalSettings.restrictEval || evalSettings.pureEval) {
allowedPaths = std::optional(PathSet());
for (auto & i : searchPath.elements) {
for (auto & i : searchPath_.elements) {
auto r = resolveSearchPathPath(i.path);
if (!r) continue;
@ -329,32 +306,66 @@ EvalState::EvalState(
}
}
EvalState::EvalState(
const SearchPath & _searchPath,
ref<Store> store,
std::shared_ptr<Store> buildStore,
std::function<ReplExitStatus(EvalState & es, ValMap const & extraEnv)> debugRepl)
: s(symbols)
, paths(store, buildStore ? ref(buildStore) : store, [&] {
SearchPath searchPath;
if (!evalSettings.pureEval) {
for (auto & i : _searchPath.elements)
searchPath.elements.emplace_back(SearchPath::Elem {i});
for (auto & i : evalSettings.nixPath.get())
searchPath.elements.emplace_back(SearchPath::Elem::parse(i));
}
return searchPath;
}(), errors)
, builtins(mem, symbols, paths.searchPath(), store->config().storeDir)
, repair(NoRepair)
, store(store)
, debug{
debugRepl ? std::make_unique<DebugState>(
positions,
symbols,
[this, debugRepl](const ValMap & extraEnv) { return debugRepl(*this, extraEnv); }
)
: nullptr
}
, errors{positions, debug.get()}
{
countCalls = getEnv("NIX_COUNT_CALLS").value_or("0") != "0";
static_assert(sizeof(Env) <= 16, "environment must be <= 16 bytes");
}
EvalState::~EvalState()
{
}
void EvalState::allowPath(const Path & path)
void EvalPaths::allowPath(const Path & path)
{
if (allowedPaths)
allowedPaths->insert(path);
}
void EvalState::allowPath(const StorePath & storePath)
void EvalPaths::allowPath(const StorePath & storePath)
{
if (allowedPaths)
allowedPaths->insert(store->toRealPath(storePath));
}
void EvalState::allowAndSetStorePathString(const StorePath & storePath, Value & v)
void EvalPaths::allowAndSetStorePathString(const StorePath & storePath, Value & v)
{
allowPath(storePath);
mkStorePathString(storePath, v);
}
SourcePath EvalState::checkSourcePath(const SourcePath & path_)
SourcePath EvalPaths::checkSourcePath(const SourcePath & path_)
{
if (!allowedPaths) return path_;
@ -401,7 +412,7 @@ SourcePath EvalState::checkSourcePath(const SourcePath & path_)
}
void EvalState::checkURI(const std::string & uri)
void EvalPaths::checkURI(const std::string & uri)
{
if (!evalSettings.restrictEval) return;
@ -433,7 +444,7 @@ void EvalState::checkURI(const std::string & uri)
}
Path EvalState::toRealPath(const Path & path, const NixStringContext & context)
Path EvalPaths::toRealPath(const Path & path, const NixStringContext & context)
{
// FIXME: check whether 'path' is in 'context'.
return
@ -796,7 +807,7 @@ void EvalState::mkPos(Value & v, PosIdx p)
}
void EvalState::mkStorePathString(const StorePath & p, Value & v)
void EvalPaths::mkStorePathString(const StorePath & p, Value & v)
{
v.mkString(
store->printStorePath(p),
@ -926,7 +937,7 @@ struct CachedEvalFile
void EvalState::evalFile(const SourcePath & path_, Value & v)
{
auto path = checkSourcePath(path_);
auto path = paths.checkSourcePath(path_);
if (auto i = caches.fileEval.find(path); i != caches.fileEval.end()) {
v = i->second->result;
@ -940,7 +951,7 @@ void EvalState::evalFile(const SourcePath & path_, Value & v)
}
debug("evaluating file '%1%'", resolvedPath);
Expr & e = parseExprFromFile(checkSourcePath(resolvedPath));
Expr & e = parseExprFromFile(paths.checkSourcePath(resolvedPath));
try {
auto dts = debug
@ -2271,7 +2282,7 @@ BackedStringView EvalState::coerceToString(
// slash, as in /foo/${x}.
v._path
: copyToStore
? store->printStorePath(copyPathToStore(context, v.path()))
? store->printStorePath(paths.copyPathToStore(context, v.path(), repair))
: std::string(v.path().path.abs());
}
@ -2340,7 +2351,7 @@ BackedStringView EvalState::coerceToString(
}
StorePath EvalState::copyPathToStore(NixStringContext & context, const SourcePath & path)
StorePath EvalPaths::copyPathToStore(NixStringContext & context, const SourcePath & path, RepairFlag repair)
{
if (nix::isDerivation(path.path.abs()))
errors.make<EvalError>("file names are not allowed to end in '%1%'", drvExtension).debugThrow();
@ -2731,13 +2742,13 @@ Expr & EvalState::parseStdin()
}
SourcePath EvalState::findFile(const std::string_view path)
SourcePath EvalPaths::findFile(const std::string_view path)
{
return findFile(searchPath, path);
return findFile(searchPath_, path);
}
SourcePath EvalState::findFile(const SearchPath & searchPath, const std::string_view path, const PosIdx pos)
SourcePath EvalPaths::findFile(const SearchPath & searchPath, const std::string_view path, const PosIdx pos)
{
for (auto & i : searchPath.elements) {
auto suffixOpt = i.prefix.suffixIfPotentialMatch(path);
@ -2765,7 +2776,7 @@ SourcePath EvalState::findFile(const SearchPath & searchPath, const std::string_
}
std::optional<std::string> EvalState::resolveSearchPathPath(const SearchPath::Path & value0)
std::optional<std::string> EvalPaths::resolveSearchPathPath(const SearchPath::Path & value0)
{
auto & value = value0.s;
auto i = searchPathResolved.find(value);

View file

@ -360,29 +360,20 @@ struct EvalErrorContext
}
};
class EvalState
class EvalPaths
{
friend class EvalBuiltins;
public:
SymbolTable symbols;
PosTable positions;
const StaticSymbols s;
EvalMemory mem;
EvalRuntimeCaches caches;
private:
SearchPath searchPath;
public:
EvalBuiltins builtins;
ref<Store> store;
/**
* If set, force copying files to the Nix store even if they
* already exist there.
* Store used to build stuff.
*/
RepairFlag repair;
ref<Store> buildStore;
SearchPath searchPath_;
EvalErrorContext & errors;
public:
EvalPaths(const ref<Store> & store, const ref<Store> buildStore, SearchPath searchPath, EvalErrorContext & errors);
const SearchPath & searchPath() const { return searchPath_; }
/**
* The allowed filesystem paths in restricted or pure evaluation
@ -390,19 +381,6 @@ public:
*/
std::optional<PathSet> allowedPaths;
/**
* Store used to materialise .drv files.
*/
const ref<Store> store;
/**
* Store used to build stuff.
*/
const ref<Store> buildStore;
std::unique_ptr<DebugState> debug;
EvalErrorContext errors;
private:
/* Cache for calls to addToStore(); maps source paths to the store
@ -417,15 +395,6 @@ private:
std::unordered_map<Path, SourcePath> resolvedPaths;
public:
EvalState(
const SearchPath & _searchPath,
ref<Store> store,
std::shared_ptr<Store> buildStore = nullptr,
std::function<ReplExitStatus(EvalState & es, ValMap const & extraEnv)> debugRepl = nullptr
);
~EvalState();
/**
* Allow access to a path.
*/
@ -461,6 +430,78 @@ public:
*/
Path toRealPath(const Path & path, const NixStringContext & context);
/**
* Look up a file in the search path.
*/
SourcePath findFile(const std::string_view path);
SourcePath findFile(const SearchPath & searchPath, const std::string_view path, const PosIdx pos = noPos);
/**
* Try to resolve a search path value (not the optinal key part)
*
* If the specified search path element is a URI, download it.
*
* If it is not found, return `std::nullopt`
*/
std::optional<std::string> resolveSearchPathPath(const SearchPath::Path & path);
StorePath copyPathToStore(
NixStringContext & context, const SourcePath & path, RepairFlag repair = NoRepair
);
/**
* Create a string representing a store path.
*
* The string is the printed store path with a context containing a
* 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]] StringMap realiseContext(const NixStringContext & context);
};
class EvalState
{
friend class EvalBuiltins;
public:
SymbolTable symbols;
PosTable positions;
const StaticSymbols s;
EvalMemory mem;
EvalRuntimeCaches caches;
EvalPaths paths;
EvalBuiltins builtins;
/**
* If set, force copying files to the Nix store even if they
* already exist there.
*/
RepairFlag repair;
/**
* Store used to materialise .drv files.
*/
const ref<Store> store;
std::unique_ptr<DebugState> debug;
EvalErrorContext errors;
public:
EvalState(
const SearchPath & _searchPath,
ref<Store> store,
std::shared_ptr<Store> buildStore = nullptr,
std::function<ReplExitStatus(EvalState & es, ValMap const & extraEnv)> debugRepl = nullptr
);
~EvalState();
/**
* Parse a Nix expression from the specified file.
*/
@ -491,21 +532,6 @@ public:
void resetFileCache();
/**
* Look up a file in the search path.
*/
SourcePath findFile(const std::string_view path);
SourcePath findFile(const SearchPath & searchPath, const std::string_view path, const PosIdx pos = noPos);
/**
* Try to resolve a search path value (not the optinal key part)
*
* If the specified search path element is a URI, download it.
*
* If it is not found, return `std::nullopt`
*/
std::optional<std::string> resolveSearchPathPath(const SearchPath::Path & path);
/**
* Evaluate an expression to normal form
*
@ -577,8 +603,6 @@ public:
bool coerceMore = false, bool copyToStore = true,
bool canonicalizePath = true);
StorePath copyPathToStore(NixStringContext & context, const SourcePath & path);
/**
* Path coercion.
*
@ -669,14 +693,6 @@ public:
void mkThunk_(Value & v, Expr & expr);
void mkPos(Value & v, PosIdx pos);
/**
* Create a string representing a store path.
*
* The string is the printed store path with a context containing a
* single `NixStringContextElem::Opaque` element of that store path.
*/
void mkStorePathString(const StorePath & storePath, Value & v);
/**
* Create a string representing a `SingleDerivedPath::Built`.
*
@ -735,12 +751,6 @@ public:
*/
bool fullGC();
/**
* 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);
private:
/**

View file

@ -68,7 +68,7 @@ static std::tuple<fetchers::Tree, FlakeRef, FlakeRef> fetchOrSubstituteTree(
debug("got tree '%s' from '%s'",
state.store->printStorePath(tree.storePath), lockedRef);
state.allowPath(tree.storePath);
state.paths.allowPath(tree.storePath);
assert(!originalRef.input.getNarHash() || tree.storePath == originalRef.input.computeStorePath(*state.store));
@ -242,8 +242,8 @@ static Flake getFlake(
};
// FIXME: symlink attack
auto resolvedFlakeFile = resolveExprPath(state.checkSourcePath(CanonPath(flakeFile)));
Expr & flakeExpr = state.parseExprFromFile(state.checkSourcePath(resolvedFlakeFile));
auto resolvedFlakeFile = resolveExprPath(state.paths.checkSourcePath(CanonPath(flakeFile)));
Expr & flakeExpr = state.parseExprFromFile(state.paths.checkSourcePath(resolvedFlakeFile));
// Enforce that 'flake.nix' is a direct attrset, not a computation.
if (!(dynamic_cast<ExprAttrs *>(&flakeExpr))) {

View file

@ -39,7 +39,7 @@ namespace nix {
* Miscellaneous
*************************************************************/
StringMap EvalState::realiseContext(const NixStringContext & context)
StringMap EvalPaths::realiseContext(const NixStringContext & context)
{
std::vector<DerivedPath::Built> drvs;
StringMap res;
@ -129,12 +129,12 @@ static SourcePath realisePath(EvalState & state, const PosIdx pos, Value & v, co
auto path = state.coerceToPath(noPos, v, context, "while realising the context of a path");
try {
StringMap rewrites = state.realiseContext(context);
StringMap rewrites = state.paths.realiseContext(context);
auto realPath = CanonPath(state.toRealPath(rewriteStrings(path.path.abs(), rewrites), context));
auto realPath = CanonPath(state.paths.toRealPath(rewriteStrings(path.path.abs(), rewrites), context));
return flags.checkForPureEval
? state.checkSourcePath(realPath)
? state.paths.checkSourcePath(realPath)
: realPath;
} catch (Error & e) {
e.addTrace(state.positions[pos], "while realising the context of path '%s'", path);
@ -323,7 +323,7 @@ void prim_exec(EvalState & state, const PosIdx pos, Value * * args, Value & v)
false, false).toOwned());
}
try {
auto _ = state.realiseContext(context); // FIXME: Handle CA derivations
auto _ = state.paths.realiseContext(context); // FIXME: Handle CA derivations
} catch (InvalidPathError & e) {
e.addTrace(state.positions[pos], "while realising the context for builtins.exec");
throw;
@ -1173,7 +1173,7 @@ static void prim_storePath(EvalState & state, const PosIdx pos, Value * * args,
).atPos(pos).debugThrow();
NixStringContext context;
auto path = state.checkSourcePath(state.coerceToPath(pos, *args[0], context, "while evaluating the first argument passed to builtins.storePath")).path;
auto path = state.paths.checkSourcePath(state.coerceToPath(pos, *args[0], context, "while evaluating the first argument passed to builtins.storePath")).path;
/* Resolve symlinks in path, unless path itself is a symlink
directly in the store. The latter condition is necessary so
e.g. nix-push does the right thing. */
@ -1207,6 +1207,7 @@ static void prim_pathExists(EvalState & state, const PosIdx pos, Value * * args,
try {
auto checked = state
.paths
.checkSourcePath(path)
.resolveSymlinks(mustBeDir ? SymlinkResolution::Full : SymlinkResolution::Ancestors);
@ -1305,7 +1306,7 @@ static void prim_findFile(EvalState & state, const PosIdx pos, Value * * args, V
false, false).toOwned();
try {
auto rewrites = state.realiseContext(context);
auto rewrites = state.paths.realiseContext(context);
path = rewriteStrings(path, rewrites);
} catch (InvalidPathError & e) {
state.errors.make<EvalError>(
@ -1323,7 +1324,7 @@ static void prim_findFile(EvalState & state, const PosIdx pos, Value * * args, V
auto path = state.forceStringNoCtx(*args[1], pos, "while evaluating the second argument passed to builtins.findFile");
v.mkPath(state.checkSourcePath(state.findFile(searchPath, path, pos)));
v.mkPath(state.paths.checkSourcePath(state.paths.findFile(searchPath, path, pos)));
}
/* Return the cryptographic hash of a file in base-16. */
@ -1478,7 +1479,7 @@ static void prim_toFile(EvalState & state, const PosIdx pos, Value * * args, Val
used in args[1]. */
/* Add the output of this to the allowed paths. */
state.allowAndSetStorePathString(storePath, v);
state.paths.allowAndSetStorePathString(storePath, v);
}
static void addPath(
@ -1495,8 +1496,8 @@ static void addPath(
try {
// FIXME: handle CA derivation outputs (where path needs to
// be rewritten to the actual output).
auto rewrites = state.realiseContext(context);
path = state.toRealPath(rewriteStrings(path, rewrites), context);
auto rewrites = state.paths.realiseContext(context);
path = state.paths.toRealPath(rewriteStrings(path, rewrites), context);
StorePathSet refs;
@ -1512,7 +1513,7 @@ static void addPath(
path = evalSettings.pureEval && expectedHash
? path
: state.checkSourcePath(CanonPath(path)).path.abs();
: state.paths.checkSourcePath(CanonPath(path)).path.abs();
PathFilter filter = filterFun ? ([&](const Path & path) {
auto st = lstat(path);
@ -1552,9 +1553,9 @@ static void addPath(
"store path mismatch in (possibly filtered) path added from '%s'",
path
).atPos(pos).debugThrow();
state.allowAndSetStorePathString(dstPath, v);
state.paths.allowAndSetStorePathString(dstPath, v);
} else
state.allowAndSetStorePathString(*expectedStorePath, v);
state.paths.allowAndSetStorePathString(*expectedStorePath, v);
} catch (Error & e) {
e.addTrace(state.positions[pos], "while adding path '%s'", path);
throw;

View file

@ -58,7 +58,7 @@ static void runFetchClosureWithRewrite(EvalState & state, const PosIdx pos, Stor
});
}
state.mkStorePathString(toPath, v);
state.paths.mkStorePathString(toPath, v);
}
/**
@ -84,7 +84,7 @@ static void runFetchClosureWithContentAddressedPath(EvalState & state, const Pos
});
}
state.mkStorePathString(fromPath, v);
state.paths.mkStorePathString(fromPath, v);
}
/**
@ -107,7 +107,7 @@ static void runFetchClosureWithInputAddressedPath(EvalState & state, const PosId
});
}
state.mkStorePathString(fromPath, v);
state.paths.mkStorePathString(fromPath, v);
}
typedef std::optional<StorePath> StorePathOrGap;

View file

@ -51,7 +51,7 @@ static void prim_fetchMercurial(EvalState & state, const PosIdx pos, Value * * a
// FIXME: git externals probably can be used to bypass the URI
// whitelist. Ah well.
state.checkURI(url);
state.paths.checkURI(url);
if (evalSettings.pureEval && !rev)
throw Error("in pure evaluation mode, 'fetchMercurial' requires a Mercurial revision");
@ -68,7 +68,7 @@ static void prim_fetchMercurial(EvalState & state, const PosIdx pos, Value * * a
auto [tree, input2] = input.fetch(state.store);
auto attrs2 = state.buildBindings(8);
state.mkStorePathString(tree.storePath, attrs2.alloc(state.s.outPath));
state.paths.mkStorePathString(tree.storePath, attrs2.alloc(state.s.outPath));
if (input2.getRef())
attrs2.alloc("branch").mkString(*input2.getRef());
// Backward compatibility: set 'rev' to
@ -80,7 +80,7 @@ static void prim_fetchMercurial(EvalState & state, const PosIdx pos, Value * * a
attrs2.alloc("revCount").mkInt(*revCount);
v.mkAttrs(attrs2);
state.allowPath(tree.storePath);
state.paths.allowPath(tree.storePath);
}
static RegisterPrimOp r_fetchMercurial({

View file

@ -27,7 +27,7 @@ void emitTreeAttrs(
auto attrs = state.buildBindings(10);
state.mkStorePathString(tree.storePath, attrs.alloc(state.s.outPath));
state.paths.mkStorePathString(tree.storePath, attrs.alloc(state.s.outPath));
// FIXME: support arbitrary input attributes.
@ -74,7 +74,7 @@ void emitTreeAttrs(
std::string fixURI(std::string uri, EvalState & state, const std::string & defaultScheme = "file")
{
state.checkURI(uri);
state.paths.checkURI(uri);
if (uri.find("://") == std::string::npos) {
const auto p = ParsedURL {
.scheme = defaultScheme,
@ -194,7 +194,7 @@ static void fetchTree(
auto [tree, input2] = input.fetch(state.store);
state.allowPath(tree.storePath);
state.paths.allowPath(tree.storePath);
emitTreeAttrs(state, tree, input2, v, params.emptyRevFallback, false);
}
@ -244,7 +244,7 @@ static void fetch(EvalState & state, const PosIdx pos, Value * * args, Value & v
if (who == "fetchTarball")
url = evalSettings.resolvePseudoUrl(*url);
state.checkURI(*url);
state.paths.checkURI(*url);
if (name == "")
name = baseNameOf(*url);
@ -263,7 +263,7 @@ static void fetch(EvalState & state, const PosIdx pos, Value * * args, Value & v
});
if (state.store->isValidPath(expectedPath)) {
state.allowAndSetStorePathString(expectedPath, v);
state.paths.allowAndSetStorePathString(expectedPath, v);
return;
}
}
@ -290,7 +290,7 @@ static void fetch(EvalState & state, const PosIdx pos, Value * * args, Value & v
}
}
state.allowAndSetStorePathString(storePath, v);
state.paths.allowAndSetStorePathString(storePath, v);
}
void prim_fetchurl(EvalState & state, const PosIdx pos, Value * * args, Value & v)

View file

@ -37,7 +37,7 @@ json printValueAsJSON(EvalState & state, bool strict,
case nPath:
if (copyToStore)
out = state.store->printStorePath(
state.copyPathToStore(context, v.path()));
state.paths.copyPathToStore(context, v.path(), state.repair));
else
out = v.path().path.abs();
break;

View file

@ -26,7 +26,7 @@ RC_GTEST_FIXTURE_PROP(
(const SingleDerivedPath::Opaque & o))
{
auto * v = state.mem.allocValue();
state.mkStorePathString(o.path, *v);
state.paths.mkStorePathString(o.path, *v);
auto d = state.coerceToSingleDerivedPath(noPos, *v, "");
RC_ASSERT(SingleDerivedPath { o } == d);
}