Conversation
…ause ref<Derived> was already implicitly convertible to ref<Base>, but the mechanism was unclear and error messages for rejected downcasts were more cryptic than necessary. This change: - Adds RefImplicitlyUpcastableTo concept to constrain the conversion operator, making the intent explicit and improving error messages - Documents .cast() and .dynamic_pointer_cast() as alternatives for explicit downcasting - Adds unit tests for covariance behavior
When ref::cast() fails, the error message was cryptic ("null pointer
cast to ref"). Now it throws a proper bad_ref_cast (a std::bad_cast
subclass) with a clear message showing the actual types involved:
ref<nix::Base> cannot be cast to ref<nix::Derived>
This also adds a demangle.hh utility.
It is only supported on that host platform. This adds a bunch of redundant-ish wiring logic, because the alternative is accessing `meta.platforms` generically, but that would cause these flake output attrsets *containing* the packages to be *strict in all packages*, which is very bad for performance and robustness. Checked: - Cross-compilation still works for Linux targets (arm, riscv), even when build platform is Darwin - No attributes for nix-nswrapper for native Darwin
Better `ref` casting DX
Linux, macOS, and all 3 BSDs have it (according to man page google search), so let's just drop this. Support for not having it was added in d03f0d4 in 2006, things have changed in the last 20 years!
… compression Docker 28+ defaults to the containerd image store, which pushes layers uncompressed instead of gzip. The GHA runner image updated Docker to 29.x (actions/runner-images#13633), causing the `nixos/nix:2.33.3` image to balloon from 138 MB to 505 MB, with all 70 layers pushed as `application/vnd.docker.image.rootfs.diff.tar` instead of `.tar.gzip`. OCI clients that only support gzip (e.g. `go-containerregistry`, used by Concourse CI) fail with "gzip: invalid header". This commit disables the containerd snapshotter in the release workflow before any Docker operations, restoring the classic storage driver that preserves gzip compression through the `docker load` / `docker push` pipeline. Fixes NixOS#15246
`file-descriptor.{cc,hh}` was getting too big, split out
`file-system-at.{cc,hh}` for the FD-based file system stuff,
`file-descriptor.{cc,hh}` will only be for the fundamental primitives
that are file-system agnostic and work on almost all file types.
Review with `git show --color-moved` to see that this is indeed all
moving.
Remove suppport for not having `lchown`
Add missing temproots for cached sources and existing derivations
The NIX_BUILD_TOP test used regex matching with an unquoted path variable. When the path contains `+` (or other regex operators), the test fails because `+` is interpreted as a quantifier rather than a literal character. Glob matching handles these characters correctly.
…h scheme When a URL like `github:nixos/nixpkgs/nixpkgs.git?ref=<hash>` (using `ref` instead of `rev`) failed the github input scheme, it fell through to `parsePathFlakeRefWithFragment` which constructed a `path:` `ParsedURL` with an empty authority but a relative path. This violated RFC 3986 section 3.3 (authority present requires path starting with `/`), causing an assertion failure in `renderAuthorityAndPath` when `PathInputScheme` tried to format the URL for an error message. This commit only sets the authority on absolute paths. Relative paths get `std::nullopt` for authority, which is the correct representation per the URL spec. Fixes NixOS#15196. Fixes NixOS#14830.
Split `file-system-at.{cc,hh}` from `file-descriptor.{cc,hh}`
libflake: fix assertion crash when malformed URL falls through to path scheme
The tab completion handler in `completePrefix` only caught `ParseError`, `EvalError`, `BadURL`, and `FileNotFound`. Other error types like `JSONParseError` (which derives from `Error`, not `EvalError`) escaped the catch block and propagated through editline's C code as undefined behavior, crashing the REPL. This happened when tab-completing expressions like `(builtins.fromJSON "invalid").` where evaluation throws a non-`EvalError` exception. This commit marks `completionCallback` and `listPossibleCallback` as `noexcept` with function-try-blocks that catch all exceptions at the C/C++ boundary, preventing any exception from reaching editline. Fixes NixOS#15133.
…ssion upload-release: disable containerd image store to preserve gzip layer compression
repl: catch all errors during tab completion
Bumps [cachix/install-nix-action](https://github.com/cachix/install-nix-action) from 31.9.0 to 31.9.1. - [Release notes](https://github.com/cachix/install-nix-action/releases) - [Changelog](https://github.com/cachix/install-nix-action/blob/master/RELEASE.md) - [Commits](cachix/install-nix-action@4e002c8...2126ae7) --- updated-dependencies: - dependency-name: cachix/install-nix-action dependency-version: 31.9.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [korthout/backport-action](https://github.com/korthout/backport-action) from 4.0.1 to 4.1.0. - [Release notes](https://github.com/korthout/backport-action/releases) - [Commits](korthout/backport-action@c656f5d...01619eb) --- updated-dependencies: - dependency-name: korthout/backport-action dependency-version: 4.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
The external-builders test expands `$PATH` into a heredoc without quotes, so any `PATH` entry containing spaces causes bash to parse the line as a command instead of an assignment, failing the test.
…ders-path tests: quote `PATH` in external-builders test heredoc
…sage printing Consolidates all the error message formatting in one place. It was very weird and tiring to remember to call git_error_last() in all the places.
This reduces the churn when changing up the order of values in a follow-up commit. This should have been done from the start ideally to improve readability.
This makes sure that ExprVar::eval inlines lookupVar call. In practice this seems to reduce instruction count by ~2%, though it doesn't have a statistically significant impact on the wall time.
Using nix::unreachable() in getInternalType() and type() turns out to be quite expensive and prevents inlining. Also Value::type got compiled to a jump table which has a high overhead from indirect jumps. Using an explicit lookup table turns out to be more efficient. This does mean that we lose out on nice diagnostics from nix::unreachable calls, but this code is probably one of the hottests functions in the whole evaluator, so I think the tradeoff is worth it. The nixUnreachableWhenHardened boils down to nix::unreachable when UBSan is enabled so we still have good coverage there.
libfetchers/git-utils: Add GitError class for deduplicating error…
libexpr: Optimise `Value::type()`, `ValueStorage::getInternalType()`
libexpr: Make sure `EvalState::lookupVar` is inlined
This comes in two parts: a `nix store roots-daemon` command that can run as root and list runtime roots, and client logic to find runtime roots for a `LocalStore` by connecting to that daemon. This may be useful with an unprivileged nix daemon, as it would otherwise be unable to find runtime roots from process open files and maps.
…inimal Support garbage collection in external daemon
cole-h
previously approved these changes
Apr 22, 2026
cole-h
previously approved these changes
Apr 23, 2026
Use `statusOk`/`statusToString` consistently when checking child process wait statuses, so that failures produce human-readable messages (e.g. "exited with code 2") rather than raw integer comparisons or nothing at all. Also give distinct exit codes to each failure path in the `fchmodatTryNoFollow` test for easier debugging. Note that `status == 0` and `statusOk(status)` do not do the same thing, because the latter does not check all the bits. So by changing the code from the former to the latter, we are technically changing behavior. However, it is not really proper to check the other bits, rather than use the macros which (essentially) parse a discriminated union. The other bits are probably guaranteed to be 0 in practice, but in theory, they are reserved for future use, and we should not guessing that that future use is / what the bits mean in that case.
cole-h
approved these changes
Apr 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Context
Summary by CodeRabbit
New Features
Documentation
Tests / Benchmarks
Bug Fixes
Chores