diff --git a/src/libflake/flake-primops.cc b/src/libflake/flake-primops.cc index 4d27c6848272..33c7b7d8789a 100644 --- a/src/libflake/flake-primops.cc +++ b/src/libflake/flake-primops.cc @@ -9,6 +9,7 @@ #include #include "nix/flake/flake-primops.hh" +#include "nix/store/store-api.hh" #include "nix/expr/eval.hh" #include "nix/flake/flake.hh" #include "nix/flake/flakeref.hh" @@ -66,6 +67,25 @@ PrimOp getFlake(const Settings & settings) flakeRefS, state.positions[pos]); + /* Backward compatibility hack: If this is a `path` flake and it's a virtual path that had + * `unsafeDiscardStringContext` applied to it, then treat it like the `nPath` case, i.e. call lockFlake() on + * the virtual path directly. This is necessary because the `path` fetcher doesn't see virtual paths. */ + if (flakeRef.input.getType() == "path") { + if (auto sourcePath = flakeRef.input.getSourcePath(); + sourcePath && state.store->isInStore(sourcePath->string())) { + auto [storePath, subPath] = state.store->toStorePath(sourcePath->string()); + for (auto & c : context) { + if (auto p = std::get_if(&c.raw); p && p->storePath == storePath) { + auto path = state.storePath(storePath) / CanonPath(subPath); + if (!flakeRef.subdir.empty()) + path = path / flakeRef.subdir; + callFlake(state, lockFlake(settings, state, path, lockFlags), v); + return; + } + } + } + } + callFlake(state, lockFlake(settings, state, flakeRef, lockFlags), v); } };