Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package nix for openSUSE:Factory checked in 
at 2026-07-15 16:55:11
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/nix (Old)
 and      /work/SRC/openSUSE:Factory/.nix.new.1991 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "nix"

Wed Jul 15 16:55:11 2026 rev:20 rq:1365947 version:2.34.8

Changes:
--------
--- /work/SRC/openSUSE:Factory/nix/nix.changes  2026-05-28 23:12:16.072210170 
+0200
+++ /work/SRC/openSUSE:Factory/.nix.new.1991/nix.changes        2026-07-15 
17:11:54.656162643 +0200
@@ -1,0 +2,6 @@
+Wed Jul  8 11:17:31 UTC 2026 - Eyad Issa <[email protected]>
+
+- Update to version 2.37.8:
+  see /usr/share/doc/packages/rl-2.34.md
+
+-------------------------------------------------------------------

Old:
----
  nix-2.34.7.tar.gz

New:
----
  nix-2.34.8.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ nix.spec ++++++
--- /var/tmp/diff_new_pack.ZGpOno/_old  2026-07-15 17:11:55.388187593 +0200
+++ /var/tmp/diff_new_pack.ZGpOno/_new  2026-07-15 17:11:55.388187593 +0200
@@ -26,7 +26,7 @@
 %bcond_with docs
 
 Name:           nix
-Version:        2.34.7
+Version:        2.34.8
 Release:        0
 Summary:        The purely functional package manager
 License:        LGPL-2.1-only

++++++ nix-2.34.7.tar.gz -> nix-2.34.8.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.34.7/.version new/nix-2.34.8/.version
--- old/nix-2.34.7/.version     2026-05-04 19:22:33.000000000 +0200
+++ new/nix-2.34.8/.version     2026-07-01 22:22:08.000000000 +0200
@@ -1 +1 @@
-2.34.7
+2.34.8
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.34.7/scripts/install-nix-from-tarball.sh 
new/nix-2.34.8/scripts/install-nix-from-tarball.sh
--- old/nix-2.34.7/scripts/install-nix-from-tarball.sh  2026-05-04 
19:22:33.000000000 +0200
+++ new/nix-2.34.8/scripts/install-nix-from-tarball.sh  2026-07-01 
22:22:08.000000000 +0200
@@ -28,14 +28,15 @@
 
 OS="$(uname -s)"
 
-# macOS support for 10.12.6 or higher
+# Since nixpkgs 25.11 the minimum deployment target is macOS 14.0
 if [ "$OS" = "Darwin" ]; then
+    # shellcheck disable=SC2034
     IFS='.' read -r macos_major macos_minor macos_patch << EOF
 $(sw_vers -productVersion)
 EOF
-    if [ "$macos_major" -lt 10 ] || { [ "$macos_major" -eq 10 ] && [ 
"$macos_minor" -lt 12 ]; } || { [ "$macos_minor" -eq 12 ] && [ "$macos_patch" 
-lt 6 ]; }; then
+    if [ "$macos_major" -lt 14 ]; then
         # patch may not be present; command substitution for simplicity
-        echo "$0: macOS $(sw_vers -productVersion) is not supported, upgrade 
to 10.12.6 or higher"
+        echo "$0: macOS $(sw_vers -productVersion) is not supported, upgrade 
to 14.0 or higher"
         exit 1
     fi
 fi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.34.7/src/libcmd/include/nix/cmd/markdown.hh 
new/nix-2.34.8/src/libcmd/include/nix/cmd/markdown.hh
--- old/nix-2.34.7/src/libcmd/include/nix/cmd/markdown.hh       2026-05-04 
19:22:33.000000000 +0200
+++ new/nix-2.34.8/src/libcmd/include/nix/cmd/markdown.hh       2026-07-01 
22:22:08.000000000 +0200
@@ -1,6 +1,7 @@
 #pragma once
 ///@file
 
+#include <string>
 #include <string_view>
 
 namespace nix {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.34.7/src/libcmd/repl.cc 
new/nix-2.34.8/src/libcmd/repl.cc
--- old/nix-2.34.7/src/libcmd/repl.cc   2026-05-04 19:22:33.000000000 +0200
+++ new/nix-2.34.8/src/libcmd/repl.cc   2026-07-01 22:22:08.000000000 +0200
@@ -659,6 +659,8 @@
         ExprAttrs * bindings = nullptr;
         try {
             bindings = parseReplBindings(line);
+        } catch (IncompleteReplExpr &) {
+            throw;
         } catch (ParseError &) {
         }
 
@@ -875,7 +877,13 @@
     // Use original source (s) for error messages, not s + ";"
     try {
         return state->parseReplBindings(s + ";", s, basePath, staticEnv);
-    } catch (ParseError &) {
+    } catch (ParseError & e) {
+        // All binding parse attempts failed. If the last error indicates
+        // incomplete input (e.g. unclosed multi-line string), signal the
+        // mainLoop to read continuation lines instead of falling through
+        // to expression parsing which would produce a misleading error.
+        if (e.msg().find("unexpected end of file") != std::string::npos)
+            throw IncompleteReplExpr(e.msg());
         // Semicolon retry failed; rethrow the original bindings error
         std::rethrow_exception(bindingsError);
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.34.7/src/libfetchers/git-lfs-fetch.cc 
new/nix-2.34.8/src/libfetchers/git-lfs-fetch.cc
--- old/nix-2.34.7/src/libfetchers/git-lfs-fetch.cc     2026-05-04 
19:22:33.000000000 +0200
+++ new/nix-2.34.8/src/libfetchers/git-lfs-fetch.cc     2026-07-01 
22:22:08.000000000 +0200
@@ -7,6 +7,7 @@
 #include "nix/util/users.hh"
 #include "nix/util/util.hh"
 #include "nix/util/hash.hh"
+#include "nix/util/json-utils.hh"
 #include "nix/store/ssh.hh"
 
 #include <git2/attr.h>
@@ -290,7 +291,8 @@
 
     const auto obj = objUrls[0];
     try {
-        std::string sha256 = obj.at("oid"); // oid is also the sha256
+        // Use the committed pointer's oid/size for integrity, not server's 
claim
+        std::string sha256 = pointer->oid;
         std::string ourl = obj.at("actions").at("download").at("href");
         auto authHeader = [&]() -> std::optional<std::string> {
             const auto & download = obj.at("actions").at("download");
@@ -302,7 +304,20 @@
                 return std::nullopt;
             return std::string(*authIt);
         }();
-        const uint64_t size = obj.at("size");
+        const uint64_t size = pointer->size;
+
+        auto objOid = getString(valueAt(getObject(obj), "oid"));
+        auto objSize = getUnsigned(valueAt(getObject(obj), "size"));
+        if (objOid != pointer->oid || objSize != pointer->size) {
+            throw Error(
+                "LFS server returned mismatched oid/size for '%s' (got oid=%s 
size=%d, expected oid=%s size=%d)",
+                pointerFilePath,
+                objOid,
+                objSize,
+                pointer->oid,
+                pointer->size);
+        }
+
         sizeCallback(size);
         downloadToSink(ourl, authHeader, sink, sha256, size);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.34.7/src/libstore/build/derivation-goal.cc 
new/nix-2.34.8/src/libstore/build/derivation-goal.cc
--- old/nix-2.34.7/src/libstore/build/derivation-goal.cc        2026-05-04 
19:22:33.000000000 +0200
+++ new/nix-2.34.8/src/libstore/build/derivation-goal.cc        2026-07-01 
22:22:08.000000000 +0200
@@ -161,12 +161,16 @@
     }
 
     auto resolutionGoal = worker.makeDerivationResolutionGoal(drvPath, *drv, 
buildMode);
+    /* We'll handle the error below. */
+    resolutionGoal->preserveFailure = true;
     {
         Goals waitees{resolutionGoal};
         co_await await(std::move(waitees));
     }
     if (nrFailed != 0) {
-        co_return doneFailure({BuildResult::Failure::DependencyFailed, "Build 
failed due to failed dependency"});
+        auto * failure = resolutionGoal->buildResult.tryGetFailure();
+        assert(failure);
+        co_return doneFailure(*failure);
     }
 
     if (resolutionGoal->resolvedDrv) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nix-2.34.7/src/libstore/build/derivation-trampoline-goal.cc 
new/nix-2.34.8/src/libstore/build/derivation-trampoline-goal.cc
--- old/nix-2.34.7/src/libstore/build/derivation-trampoline-goal.cc     
2026-05-04 19:22:33.000000000 +0200
+++ new/nix-2.34.8/src/libstore/build/derivation-trampoline-goal.cc     
2026-07-01 22:22:08.000000000 +0200
@@ -2,6 +2,9 @@
 #include "nix/store/build/worker.hh"
 #include "nix/store/derivations.hh"
 
+#include <ranges>
+#include <algorithm>
+
 namespace nix {
 
 DerivationTrampolineGoal::DerivationTrampolineGoal(
@@ -145,6 +148,9 @@
         },
         wantedOutputs.raw);
 
+    /* Must have at least one wanted output. This is assumed below. */
+    assert(!resolvedWantedOutputs.empty());
+
     Goals concreteDrvGoals;
 
     /* Build this step! */
@@ -156,20 +162,71 @@
         concreteDrvGoals.insert(std::move(g));
     }
 
-    // Copy on purpose
-    co_await await(Goals(concreteDrvGoals));
+    co_await await(concreteDrvGoals);
 
     trace("outer build done");
 
-    auto & g = *concreteDrvGoals.begin();
-    buildResult = g->buildResult;
-    if (auto * successP = buildResult.tryGetSuccess())
-        for (auto & g2 : concreteDrvGoals)
-            if (auto * successP2 = g2->buildResult.tryGetSuccess())
-                for (auto && [x, y] : successP2->builtOutputs)
-                    successP->builtOutputs.insert_or_assign(x, y);
+    if (nrFailed != 0) {
+        auto gi = std::ranges::find_if(concreteDrvGoals, [](const GoalPtr & 
goal) -> bool {
+            auto exitCode = goal->exitCode;
+            /* Note that without --keep-going waitees might be cancelled before
+               we are woken up. */
+            return exitCode != ecBusy && exitCode != ecSuccess;
+        });
+
+        const Goal * g = gi->get();
+        assert(gi != concreteDrvGoals.end() && "expected a failing goal");
+        auto exitCode = g->exitCode;
+        const auto * failure = g->buildResult.tryGetFailure();
+        assert(failure && "failing goal does not report a failed build 
result");
+
+        /* Report the exit status of *some* failing goal. This might not be 
strictly
+           correct, since multiple subgoals can fail independently, but this 
should be
+           a good enough heuristic without --keep-going. */
+        co_return doneFailure(exitCode, *failure);
+    }
+
+    SingleDrvOutputs outputs;
 
-    co_return amDone(g->exitCode);
+    auto successes = std::views::transform(concreteDrvGoals, [](const GoalPtr 
& a) -> const BuildResult::Success & {
+        auto * success = a->buildResult.tryGetSuccess();
+        assert(success && "goal succeeded, but some waitees do not report a 
successful status");
+        return *success;
+    });
+
+    for (const auto & success : successes)
+        std::ranges::copy(success.builtOutputs, std::inserter(outputs, 
outputs.end()));
+
+    auto statuses = successes | 
std::views::transform(&BuildResult::Success::status);
+
+    /* Aggregate the status code. If some outputs we already valid, but we had
+       to build/substitute the other ones, report it as the smallest common
+       denominator. */
+    auto compareSuccesses = [](auto a, auto b) {
+        /* This is technically an identity mapping of the underlying values, 
but
+           it would be worse to rely on the enum ordering here. */
+        auto toPriority = [](auto st) {
+            using enum BuildResult::Success::Status;
+            switch (st) {
+            case Built:
+                return 0;
+            case Substituted:
+                return 1;
+            case AlreadyValid:
+                return 2;
+            case ResolvesToAlreadyValid:
+                return 3;
+            default:
+                unreachable();
+            }
+        };
+        return toPriority(a) < toPriority(b);
+    };
+
+    co_return doneSuccess({
+        .status = std::ranges::min(statuses, compareSuccesses),
+        .builtOutputs = std::move(outputs),
+    });
 }
 
 } // namespace nix
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.34.7/src/libstore/derivations.cc 
new/nix-2.34.8/src/libstore/derivations.cc
--- old/nix-2.34.7/src/libstore/derivations.cc  2026-05-04 19:22:33.000000000 
+0200
+++ new/nix-2.34.8/src/libstore/derivations.cc  2026-07-01 22:22:08.000000000 
+0200
@@ -225,6 +225,7 @@
     size_t start = 0;
     size_t end = str.remaining.size();
     const auto data = str.remaining.data();
+    bool foundClose = false;
     while (start < end) {
         auto idx = str.remaining.find('"', start);
         if (idx == std::string_view::npos) {
@@ -235,10 +236,13 @@
             ;
         if ((idx - pos) % 2 == 0) { // even number of backslashes
             end = idx;
+            foundClose = true;
             break;
         }
         start = idx + 1;
     }
+    if (!foundClose)
+        throw FormatError("unterminated string in derivation");
 
     start = 0;
     const auto content = str.remaining.substr(start, end);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.34.7/src/libstore/filetransfer.cc 
new/nix-2.34.8/src/libstore/filetransfer.cc
--- old/nix-2.34.7/src/libstore/filetransfer.cc 2026-05-04 19:22:33.000000000 
+0200
+++ new/nix-2.34.8/src/libstore/filetransfer.cc 2026-07-01 22:22:08.000000000 
+0200
@@ -798,6 +798,8 @@
     private:
         bool quitting = false;
     public:
+        bool work = false;
+
         void quit()
         {
             quitting = true;
@@ -853,12 +855,14 @@
     void stopWorkerThread()
     {
         /* Signal the worker thread to exit. */
-        state_.lock()->quit();
-        wakeupMulti();
+        auto state(state_.lock());
+        state->quit();
+        wakeupMulti(*state);
     }
 
-    void wakeupMulti()
+    void wakeupMulti(State & state)
     {
+        state.work = true;
         if (auto ec = ::curl_multi_wakeup(curlm.get()))
             throw curlMultiError(ec);
     }
@@ -908,25 +912,12 @@
                 }
             }
 
-            /* Wait for activity, including wakeup events. */
-            long maxSleepTimeMs = items.empty() ? 10000 : 100;
-            auto sleepTimeMs = nextWakeup != 
std::chrono::steady_clock::time_point()
-                                   ? std::max(
-                                         0,
-                                         (int) 
std::chrono::duration_cast<std::chrono::milliseconds>(
-                                             nextWakeup - 
std::chrono::steady_clock::now())
-                                             .count())
-                                   : maxSleepTimeMs;
-
-            int numfds = 0;
-            mc = curl_multi_poll(curlm.get(), nullptr, 0, sleepTimeMs, 
&numfds);
-            if (mc != CURLM_OK)
-                throw curlMultiError(mc);
-
             nextWakeup = std::chrono::steady_clock::time_point();
 
             std::vector<std::shared_ptr<TransferItem>> incoming;
+            std::vector<std::weak_ptr<Item>> unpause;
             auto now = std::chrono::steady_clock::now();
+            bool haveWork;
 
             {
                 auto state(state_.lock());
@@ -948,7 +939,9 @@
                         break;
                     }
                 }
+                unpause = std::exchange(state->unpause, {});
                 quit = state->isQuitting();
+                haveWork = std::exchange(state->work, false);
             }
 
             for (auto & item : incoming) {
@@ -959,14 +952,10 @@
                 items[item->req] = item;
             }
 
-            /* NOTE: Unpausing may invoke callbacks to flush all buffers. */
-            auto unpause = [&]() {
-                auto state(state_.lock());
-                auto res = state->unpause;
-                state->unpause.clear();
-                return res;
-            }();
+            if (quit)
+                break;
 
+            /* NOTE: Unpausing may invoke callbacks to flush all buffers. */
             for (auto & item : unpause) {
                 /* The transfer might have completed (failed) between it 
getting
                    enqueued for unpause and by the time the worker thread 
picked
@@ -976,6 +965,26 @@
                     continue;
                 static_cast<TransferItem &>(*ptr).unpause();
             }
+
+            /* Wait for activity, including wakeup events. */
+            long maxSleepTimeMs = items.empty() ? 10000 : 100;
+            auto sleepTimeMs = nextWakeup != 
std::chrono::steady_clock::time_point()
+                                   ? std::max(
+                                         0,
+                                         (int) 
std::chrono::duration_cast<std::chrono::milliseconds>(
+                                             nextWakeup - 
std::chrono::steady_clock::now())
+                                             .count())
+                                   : maxSleepTimeMs;
+
+            /* Since 
https://github.com/curl/curl/commit/2a2104f3cff44bb28bb570a093be52bbeeed8f23 
(8.21),
+               curl_multi_perform seems to swallow queued up events ¯\_(ツ)_/¯. 
*/
+            if (haveWork)
+                sleepTimeMs = 0;
+
+            int numfds = 0;
+            mc = curl_multi_poll(curlm.get(), nullptr, 0, sleepTimeMs, 
&numfds);
+            if (mc != CURLM_OK)
+                throw curlMultiError(mc);
         }
 
         debug("download thread shutting down");
@@ -1012,9 +1021,9 @@
                 throw nix::Error("cannot enqueue download request because the 
download thread is shutting down");
             state->incoming.push(item);
             item->enqueued = true; /* Now any exceptions should be reported 
via the callback. */
+            wakeupMulti(*state);
         }
 
-        wakeupMulti();
         return ItemHandle(item.get_ptr());
     }
 
@@ -1034,7 +1043,7 @@
     {
         auto state(state_.lock());
         state->unpause.push_back(std::move(item));
-        wakeupMulti();
+        wakeupMulti(*state);
     }
 
     void unpauseTransfer(ItemHandle handle) override
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.34.7/src/libstore/local-store.cc 
new/nix-2.34.8/src/libstore/local-store.cc
--- old/nix-2.34.7/src/libstore/local-store.cc  2026-05-04 19:22:33.000000000 
+0200
+++ new/nix-2.34.8/src/libstore/local-store.cc  2026-07-01 22:22:08.000000000 
+0200
@@ -212,7 +212,7 @@
 #if HAVE_POSIX_FALLOCATE
             res = posix_fallocate(fd.get(), 0, gcSettings.reservedSize);
 #endif
-            if (res == -1) {
+            if (res != 0) {
                 writeFull(fd.get(), std::string(gcSettings.reservedSize, 'X'));
                 [[gnu::unused]] auto res2 =
 
@@ -393,17 +393,7 @@
 AutoCloseFD LocalStore::openGCLock()
 {
     auto fnGCLock = config->stateDir.get() / "gc.lock";
-    auto fdGCLock = open(
-        fnGCLock.string().c_str(),
-        O_RDWR | O_CREAT
-#ifndef _WIN32
-            | O_CLOEXEC
-#endif
-        ,
-        0600);
-    if (!fdGCLock)
-        throw SysError("opening global GC lock %1%", PathFmt(fnGCLock));
-    return toDescriptor(fdGCLock);
+    return openLockFile(fnGCLock, /*create=*/true);
 }
 
 void LocalStore::deleteStorePath(const std::filesystem::path & path, uint64_t 
& bytesFreed, bool isKnownPath)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nix-2.34.7/src/libstore/unix/build/derivation-builder.cc 
new/nix-2.34.8/src/libstore/unix/build/derivation-builder.cc
--- old/nix-2.34.7/src/libstore/unix/build/derivation-builder.cc        
2026-05-04 19:22:33.000000000 +0200
+++ new/nix-2.34.8/src/libstore/unix/build/derivation-builder.cc        
2026-07-01 22:22:08.000000000 +0200
@@ -499,8 +499,7 @@
                 .gid = gid,
                 .chdir = "/"});
         if (!statusOk(diffRes.first))
-            throw ExecError(
-                diffRes.first, "diff-hook program %s %2%", PathFmt(diffHook), 
statusToString(diffRes.first));
+            throw ExecError(diffRes.first, "diff-hook program %s %s", 
PathFmt(diffHook), statusToString(diffRes.first));
 
         if (diffRes.second != "")
             printError(chomp(diffRes.second));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nix-2.34.7/src/libstore-tests/derivation/external-formats.cc 
new/nix-2.34.8/src/libstore-tests/derivation/external-formats.cc
--- old/nix-2.34.7/src/libstore-tests/derivation/external-formats.cc    
2026-05-04 19:22:33.000000000 +0200
+++ new/nix-2.34.8/src/libstore-tests/derivation/external-formats.cc    
2026-07-01 22:22:08.000000000 +0200
@@ -15,6 +15,14 @@
         parseDerivation(*store, readFile(goldenMaster("bad-version.drv")), 
"whatever", mockXpSettings), FormatError);
 }
 
+TEST_F(DerivationTest, UnterminatedString)
+{
+    ASSERT_THROW(
+        parseDerivation(
+            *store, 
"Derive([(\"out\",\"/nix/store/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo", "bar", 
mockXpSettings),
+        FormatError);
+}
+
 TEST_F(DynDerivationTest, BadATerm_oldVersionDynDeps)
 {
     ASSERT_THROW(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.34.7/src/libutil/archive.cc 
new/nix-2.34.8/src/libutil/archive.cc
--- old/nix-2.34.7/src/libutil/archive.cc       2026-05-04 19:22:33.000000000 
+0200
+++ new/nix-2.34.8/src/libutil/archive.cc       2026-07-01 22:22:08.000000000 
+0200
@@ -34,8 +34,7 @@
 
 /* Maximum directory nesting depth for dumpPath()/parseDump(). Bounds
    stack usage so deep trees cannot overflow the (possibly coroutine)
-   stack these run on. Chosen to fit comfortably in the default 128 KiB
-   boost coroutine stack. */
+   stack these run on. */
 static constexpr size_t narMaxDepth = 64;
 
 PathFilter defaultPathFilter = [](const std::string &) { return true; };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.34.7/src/libutil/serialise.cc 
new/nix-2.34.8/src/libutil/serialise.cc
--- old/nix-2.34.7/src/libutil/serialise.cc     2026-05-04 19:22:33.000000000 
+0200
+++ new/nix-2.34.8/src/libutil/serialise.cc     2026-07-01 22:22:08.000000000 
+0200
@@ -305,6 +305,13 @@
 {
 }
 
+/* 512KiB is a conservative estimate for deeply nested NARs, which are limited
+   to 64 levels. We also tend to allocate rather large buffers on the stack, so
+   we should leave plenty of headroom. Note that no evaluation is supposed to
+   happen on sourceToSink/sinkToSource coroutine stacks (for Boehm GC reasons),
+   which requires much more stack space. */
+static constexpr size_t defaultCoroutineStackSize = 512 * 1024;
+
 std::unique_ptr<FinishSink> sourceToSink(fun<void(Source &)> reader)
 {
     struct SourceToSink : FinishSink
@@ -328,8 +335,9 @@
             cur = in;
 
             if (!coro) {
-                coro =
-                    
coro_t::push_type(boost::coroutines2::protected_fixedsize_stack(), 
[&](coro_t::pull_type & yield) {
+                coro = coro_t::push_type(
+                    
boost::coroutines2::protected_fixedsize_stack(defaultCoroutineStackSize),
+                    [&](coro_t::pull_type & yield) {
                         LambdaSource source([&](char * out, size_t out_len) {
                             if (cur.empty()) {
                                 yield();
@@ -386,8 +394,9 @@
         {
             bool hasCoro = coro.has_value();
             if (!hasCoro) {
-                coro =
-                    
coro_t::pull_type(boost::coroutines2::protected_fixedsize_stack(), 
[&](coro_t::push_type & yield) {
+                coro = coro_t::pull_type(
+                    
boost::coroutines2::protected_fixedsize_stack(defaultCoroutineStackSize),
+                    [&](coro_t::push_type & yield) {
                         LambdaSink sink([&](std::string_view data) {
                             if (!data.empty()) {
                                 yield(data);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.34.7/src/libutil/unix/processes.cc 
new/nix-2.34.8/src/libutil/unix/processes.cc
--- old/nix-2.34.7/src/libutil/unix/processes.cc        2026-05-04 
19:22:33.000000000 +0200
+++ new/nix-2.34.8/src/libutil/unix/processes.cc        2026-07-01 
22:22:08.000000000 +0200
@@ -51,11 +51,13 @@
 }
 
 Pid::~Pid()
-try {
-    if (pid != -1)
-        kill(/*allowInterrupts=*/false);
-} catch (...) {
-    ignoreExceptionInDestructor();
+{
+    try {
+        if (pid != -1)
+            kill(/*allowInterrupts=*/false);
+    } catch (...) {
+        ignoreExceptionInDestructor();
+    }
 }
 
 void Pid::operator=(pid_t pid)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.34.7/src/nix/nix-store/nix-store.cc 
new/nix-2.34.8/src/nix/nix-store/nix-store.cc
--- old/nix-2.34.7/src/nix/nix-store/nix-store.cc       2026-05-04 
19:22:33.000000000 +0200
+++ new/nix-2.34.8/src/nix/nix-store/nix-store.cc       2026-07-01 
22:22:08.000000000 +0200
@@ -575,6 +575,7 @@
 
 static void registerValidity(bool reregister, bool hashGiven, bool 
canonicalise)
 {
+    auto localStore = ensureLocalStore();
     ValidPathInfos infos;
 
     while (1) {
@@ -592,7 +593,7 @@
             /* !!! races */
             if (canonicalise)
                 canonicalisePathMetaData(
-                    store->printStorePath(info->path),
+                    localStore->toRealPath(info->path),
                     
{NIX_WHEN_SUPPORT_ACLS(settings.getLocalSettings().ignoredAcls)});
             if (!hashGiven) {
                 HashResult hash = hashPath(
@@ -606,7 +607,7 @@
         }
     }
 
-    ensureLocalStore()->registerValidPaths(infos);
+    localStore->registerValidPaths(infos);
 }
 
 static void opLoadDB(Strings opFlags, Strings opArgs)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.34.7/tests/functional/build.sh 
new/nix-2.34.8/tests/functional/build.sh
--- old/nix-2.34.7/tests/functional/build.sh    2026-05-04 19:22:33.000000000 
+0200
+++ new/nix-2.34.8/tests/functional/build.sh    2026-07-01 22:22:08.000000000 
+0200
@@ -191,13 +191,9 @@
 # Precise number of errors depends on daemon version / goal refactorings
 (( "$(<<<"$out" grep -cE '^error:')" >= 2 ))
 
-if isDaemonNewer "2.31"; then
+if isDaemonNewer "2.29pre"; then
     <<<"$out" grepQuiet -E "error: Cannot build '.*-x4\\.drv'"
     <<<"$out" grepQuiet -E "Reason: 1 dependency failed."
-elif isDaemonNewer "2.29pre"; then
-    <<<"$out" grepQuiet -E "error: Cannot build '.*-x4\\.drv'"
-    <<<"$out" grepQuiet -E "Reason: 1 dependency failed."
-    <<<"$out" grepQuiet -E "Build failed due to failed dependency"
 else
     <<<"$out" grepQuiet -E "error: 1 dependencies of derivation '.*-x4\\.drv' 
failed to build"
 fi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.34.7/tests/functional/chroot-store.sh 
new/nix-2.34.8/tests/functional/chroot-store.sh
--- old/nix-2.34.7/tests/functional/chroot-store.sh     2026-05-04 
19:22:33.000000000 +0200
+++ new/nix-2.34.8/tests/functional/chroot-store.sh     2026-07-01 
22:22:08.000000000 +0200
@@ -60,6 +60,15 @@
 # Path gets decoded.
 [[ ! -d "$TEST_ROOT/x%2Bchroot" ]]
 
+# Regression test: `nix-store --register-validity` against a chroot store must
+# canonicalise the real (chroot-prefixed) path, not the logical store path
+# (which does not exist on the host filesystem).
+regPath=$NIX_STORE_DIR/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-reg
+touch "$TEST_ROOT/x/nix/store/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-reg"
+[[ ! -e "$regPath" ]]
+(echo "$regPath" && echo && echo 0) | nix-store --store 
"local?root=$TEST_ROOT/x" --register-validity
+nix-store --store "$TEST_ROOT/x" --check-validity "$regPath"
+
 # Ensure store info trusted works with local store
 nix --store "$TEST_ROOT/x" store info --json | jq -e '.trusted'
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.34.7/tests/functional/meson.build 
new/nix-2.34.8/tests/functional/meson.build
--- old/nix-2.34.7/tests/functional/meson.build 2026-05-04 19:22:33.000000000 
+0200
+++ new/nix-2.34.8/tests/functional/meson.build 2026-07-01 22:22:08.000000000 
+0200
@@ -66,6 +66,7 @@
       'user-envs-migration.sh',
       'cli-characterisation.sh',
       'binary-cache.sh',
+      'multiple-outputs-substitute-failure.sh',
       'multiple-outputs.sh',
       'nix-build.sh',
       'gc-concurrent.sh',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nix-2.34.7/tests/functional/multiple-outputs-substitute-failure.sh 
new/nix-2.34.8/tests/functional/multiple-outputs-substitute-failure.sh
--- old/nix-2.34.7/tests/functional/multiple-outputs-substitute-failure.sh      
1970-01-01 01:00:00.000000000 +0100
+++ new/nix-2.34.8/tests/functional/multiple-outputs-substitute-failure.sh      
2026-07-01 22:22:08.000000000 +0200
@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+
+# See https://github.com/NixOS/nix/issues/15916
+
+source common.sh
+
+TODO_NixOS # Requires substituting from a local binary cache, enable when we 
sign paths in NixOS tests
+needLocalStore "'--no-require-sigs' can’t be used with the daemon"
+
+BINARY_CACHE=file://$cacheDir
+
+readarray -t outPaths < <(nix build -f multiple-outputs.nix 'independent^*' 
--no-link --print-out-paths)
+[[ ${#outPaths[@]} -eq 2 ]]
+nix copy --to "$BINARY_CACHE" "${outPaths[@]}"
+for p in "${outPaths[@]}"; do
+    [[ $p == *-second ]] && secondOut=$p
+done
+
+# Corrupt the second output, so that the substitution partially succeeds.
+secondNarInfoFile="$cacheDir/$(basename "$secondOut" | cut -c1-32).narinfo"
+sed -i 's|^NarHash:.*|NarHash: 
sha256:0000000000000000000000000000000000000000000000000000|' 
"$secondNarInfoFile"
+
+clearStore
+clearCacheCache
+
+# Note that using "^*" matters here. We want all wanted outputs for the same 
goal.
+expect 1 nix build -j 0 -f multiple-outputs.nix "independent^*" --no-link \
+    --substituters "$BINARY_CACHE" --no-require-sigs --substitute 2>&1 | 
grepQuiet "hash mismatch"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nix-2.34.7/tests/functional/repl/multiline-string-binding.expected 
new/nix-2.34.8/tests/functional/repl/multiline-string-binding.expected
--- old/nix-2.34.7/tests/functional/repl/multiline-string-binding.expected      
1970-01-01 01:00:00.000000000 +0100
+++ new/nix-2.34.8/tests/functional/repl/multiline-string-binding.expected      
2026-07-01 22:22:08.000000000 +0200
@@ -0,0 +1,9 @@
+Nix <nix version>
+Type :? for help.
+
+nix-repl> x = ''
+        >   hello
+        > ''
+
+nix-repl> x
+"hello\n"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nix-2.34.7/tests/functional/repl/multiline-string-binding.in 
new/nix-2.34.8/tests/functional/repl/multiline-string-binding.in
--- old/nix-2.34.7/tests/functional/repl/multiline-string-binding.in    
1970-01-01 01:00:00.000000000 +0100
+++ new/nix-2.34.8/tests/functional/repl/multiline-string-binding.in    
2026-07-01 22:22:08.000000000 +0200
@@ -0,0 +1,4 @@
+x = ''
+  hello
+''
+x
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nix-2.34.7/tests/functional/repl/multiline-string-function-binding.expected 
new/nix-2.34.8/tests/functional/repl/multiline-string-function-binding.expected
--- 
old/nix-2.34.7/tests/functional/repl/multiline-string-function-binding.expected 
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/nix-2.34.8/tests/functional/repl/multiline-string-function-binding.expected 
    2026-07-01 22:22:08.000000000 +0200
@@ -0,0 +1,11 @@
+Nix <nix version>
+Type :? for help.
+
+nix-repl> f = x: x
+
+nix-repl> y = f ''
+        >   world
+        > ''
+
+nix-repl> y
+"world\n"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nix-2.34.7/tests/functional/repl/multiline-string-function-binding.in 
new/nix-2.34.8/tests/functional/repl/multiline-string-function-binding.in
--- old/nix-2.34.7/tests/functional/repl/multiline-string-function-binding.in   
1970-01-01 01:00:00.000000000 +0100
+++ new/nix-2.34.8/tests/functional/repl/multiline-string-function-binding.in   
2026-07-01 22:22:08.000000000 +0200
@@ -0,0 +1,5 @@
+f = x: x
+y = f ''
+  world
+''
+y

Reply via email to