diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index ab242bd84..f04ec79a6 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -989,10 +989,10 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos) error if a cycle is detected and roll back the transaction. Cycles can only occur when a derivation has multiple outputs. */ - auto topoSortResult = topoSort(paths, {[&](const StorePath & path) { - auto i = infos.find(path); - return i == infos.end() ? StorePathSet() : i->second.references; - }}); + auto topoSortResult = topoSort(paths, [&](const StorePath & path) { + auto i = infos.find(path); + return i == infos.end() ? StorePathSet() : i->second.references; + }); std::visit( overloaded{ diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc index 9d11648d2..f9a339a00 100644 --- a/src/libstore/misc.cc +++ b/src/libstore/misc.cc @@ -313,13 +313,13 @@ MissingPaths Store::queryMissing(const std::vector & targets) StorePaths Store::topoSortPaths(const StorePathSet & paths) { - auto result = topoSort(paths, {[&](const StorePath & path) { - try { - return queryPathInfo(path)->references; - } catch (InvalidPath &) { - return StorePathSet(); - } - }}); + auto result = topoSort(paths, [&](const StorePath & path) { + try { + return queryPathInfo(path)->references; + } catch (InvalidPath &) { + return StorePathSet(); + } + }); return std::visit( overloaded{ diff --git a/src/libstore/unix/build/derivation-builder.cc b/src/libstore/unix/build/derivation-builder.cc index 333c4dff8..428430086 100644 --- a/src/libstore/unix/build/derivation-builder.cc +++ b/src/libstore/unix/build/derivation-builder.cc @@ -1470,32 +1470,32 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs() outputStats.insert_or_assign(outputName, std::move(st)); } - auto topoSortResult = topoSort(outputsToSort, {[&](const std::string & name) { - auto orifu = get(outputReferencesIfUnregistered, name); - if (!orifu) - throw BuildError( - BuildResult::Failure::OutputRejected, - "no output reference for '%s' in build of '%s'", - name, - store.printStorePath(drvPath)); - return std::visit( - overloaded{ - /* Since we'll use the already installed versions of these, we - can treat them as leaves and ignore any references they - have. */ - [&](const AlreadyRegistered &) { return StringSet{}; }, - [&](const PerhapsNeedToRegister & refs) { - StringSet referencedOutputs; - /* FIXME build inverted map up front so no quadratic waste here */ - for (auto & r : refs.refs) - for (auto & [o, p] : scratchOutputs) - if (r == p) - referencedOutputs.insert(o); - return referencedOutputs; - }, - }, - *orifu); - }}); + auto topoSortResult = topoSort(outputsToSort, [&](const std::string & name) { + auto orifu = get(outputReferencesIfUnregistered, name); + if (!orifu) + throw BuildError( + BuildResult::Failure::OutputRejected, + "no output reference for '%s' in build of '%s'", + name, + store.printStorePath(drvPath)); + return std::visit( + overloaded{ + /* Since we'll use the already installed versions of these, we + can treat them as leaves and ignore any references they + have. */ + [&](const AlreadyRegistered &) { return StringSet{}; }, + [&](const PerhapsNeedToRegister & refs) { + StringSet referencedOutputs; + /* FIXME build inverted map up front so no quadratic waste here */ + for (auto & r : refs.refs) + for (auto & [o, p] : scratchOutputs) + if (r == p) + referencedOutputs.insert(o); + return referencedOutputs; + }, + }, + *orifu); + }); auto sortedOutputNames = std::visit( overloaded{ diff --git a/src/libutil/include/nix/util/topo-sort.hh b/src/libutil/include/nix/util/topo-sort.hh index 285c34316..fb918117b 100644 --- a/src/libutil/include/nix/util/topo-sort.hh +++ b/src/libutil/include/nix/util/topo-sort.hh @@ -3,6 +3,7 @@ #include "nix/util/error.hh" #include +#include namespace nix { @@ -16,8 +17,9 @@ struct Cycle template using TopoSortResult = std::variant, Cycle>; -template -TopoSortResult topoSort(std::set items, std::function(const T &)> getChildren) +template F> + requires std::same_as>, std::set> +TopoSortResult topoSort(std::set items, F && getChildren) { std::vector sorted; decltype(items) visited, parents; @@ -34,7 +36,7 @@ TopoSortResult topoSort(std::set items, std::function