[packages/nix] - up to 2.9.2 - updated sh,paths,ldflags patches - added g++ patch (add some type hints for gcc) - a

qboosh qboosh at pld-linux.org
Wed Jul 6 18:01:57 CEST 2022


commit 5d1b272f13dc7659552c304aa04646844837301f
Author: Jakub Bogusz <qboosh at pld-linux.org>
Date:   Wed Jul 6 18:03:38 2022 +0200

    - up to 2.9.2
    - updated sh,paths,ldflags patches
    - added g++ patch (add some type hints for gcc)
    - added fix_nix_DIR_in_doc_local_mk patch from Debian (fix non-root build)

 nix-fix_nix_DIR_in_doc_local_mk.patch |   57 +
 nix-g++.patch                         | 2730 +++++++++++++++++++++++++++++++++
 nix-ldflags.patch                     |   10 +-
 nix-paths.patch                       |   11 +-
 nix-sh.patch                          |   17 +-
 nix.spec                              |  104 +-
 6 files changed, 2903 insertions(+), 26 deletions(-)
---
diff --git a/nix.spec b/nix.spec
index c4f6e32..d4b33e5 100644
--- a/nix.spec
+++ b/nix.spec
@@ -5,40 +5,53 @@
 Summary:	A purely functional package manager
 Summary(pl.UTF-8):	Czysto funkcyjny zarządca pakietów
 Name:		nix
-Version:	2.3.15
+Version:	2.9.2
 Release:	0.1
 License:	LGPL v2.1+
 Group:		Applications/System
-#Source0Download: https://nixos.org/download.html
-Source0:	https://nixos.org/releases/nix/%{name}-%{version}/%{name}-%{version}.tar.xz
-# Source0-md5:	d5b5036347c4c1c7ddc738606703aee9
+#Source0Download: https://github.com/NixOS/nix/tags
+Source0:	https://github.com/NixOS/nix/archive/%{version}/%{name}-%{version}.tar.gz
+# Source0-md5:	2cfd0da58d4ba6a1d93f18c1bc931c1a
 Patch0:		%{name}-sh.patch
 Patch1:		%{name}-paths.patch
 Patch2:		%{name}-ldflags.patch
+Patch3:		%{name}-g++.patch
+Patch4:		%{name}-fix_nix_DIR_in_doc_local_mk.patch
 URL:		https://nixos.org/nix/
 BuildRequires:	autoconf >= 2.50
 BuildRequires:	autoconf-archive
 BuildRequires:	automake
-# aws-sdk-cpp/aws-cpp-sdk-s3 (aws/s3/S3Client.h)
+# TODO: aws-sdk-cpp/aws-cpp-sdk-s3 (aws/s3/S3Client.h)
+BuildRequires:	bison
 BuildRequires:	boost-devel >= 1.66
 BuildRequires:	bzip2-devel
 %{?with_perl:BuildRequires:	curl}
 BuildRequires:	curl-devel
 BuildRequires:	editline-devel >= 1.15.2
+BuildRequires:	flex
 BuildRequires:	gc-devel
+BuildRequires:	graphviz
+BuildRequires:	gtest-devel
+BuildRequires:	jq
+BuildRequires:	libarchive-devel >= 3.1.2
 BuildRequires:	libbrotli-devel
 BuildRequires:	libseccomp-devel
 BuildRequires:	libsodium-devel
 BuildRequires:	libstdc++-devel >= 6:7
+BuildRequires:	lowdown-devel >= 0.9.0
+BuildRequires:	lsof
+BuildRequires:	mdbook
+BuildRequires:	nlohmann-json-devel >= 3.10.5-3
 BuildRequires:	openssl-devel
-BuildRequires:	sqlite3-devel >= 3.6.19
+BuildRequires:	rpm-build >= 4.6
+BuildRequires:	rpmbuild(macros) >= 1.720
 %if %{with perl}
 BuildRequires:	perl-DBI
 BuildRequires:	perl-DBD-SQLite
 BuildRequires:	perl-base >= 1:5.8.0
 %endif
-BuildRequires:	tar >= 1:1.22
-BuildRequires:	xz
+BuildRequires:	pkgconfig >= 1:0.9.0
+BuildRequires:	sqlite3-devel >= 3.6.19
 BuildRequires:	xz-devel
 Requires:	%{name}-libs = %{version}-%{release}
 Provides:	/var/nix/manifests
@@ -87,11 +100,55 @@ Header files for Nix.
 %description devel -l pl.UTF-8
 Pliki nagłówkowe Niksa.
 
+%package -n bash-completion-nix
+Summary:	Bash completion for nix commands
+Summary(pl.UTF-8):	Dopełnianie parametrów w bashu dla poleceń nix
+Group:		Applications/Shells
+Requires:	%{name} = %{version}-%{release}
+Requires:	bash-completion >= 2.0
+BuildArch:	noarch
+
+%description -n bash-completion-nix
+Bash completion for nix commands.
+
+%description -n bash-completion-nix -l pl.UTF-8
+Dopełnianie parametrów w bashu dla poleceń nix.
+
+%package -n fish-completion-nix
+Summary:	Fish completion for nix commands
+Summary(pl.UTF-8):	Dopełnianie parametrów w fishu dla poleceń nix
+Group:		Applications/Shells
+Requires:	%{name} = %{version}-%{release}
+Requires:	fish
+BuildArch:	noarch
+
+%description -n fish-completion-nix
+Fish completion for nix commands.
+
+%description -n fish-completion-nix -l pl.UTF-8
+Dopełnianie parametrów w fishu dla poleceń nix.
+
+%package -n zsh-completion-nix
+Summary:	Zsh completion for nix commands
+Summary(pl.UTF-8):	Dopełnianie parametrów w zsh dla poleceń nix
+Group:		Applications/Shells
+Requires:	%{name} = %{version}-%{release}
+Requires:	zsh
+BuildArch:	noarch
+
+%description -n zsh-completion-nix
+Zsh completion for nix commands.
+
+%description -n zsh-completion-nix -l pl.UTF-8
+Dopełnianie parametrów w zsh dla poleceń nix.
+
 %prep
 %setup -q
 %patch0 -p1
 %patch1 -p1
 %patch2 -p1
+%patch3 -p1
+%patch4 -p1
 
 %build
 %{__aclocal} -I m4
@@ -104,6 +161,8 @@ Pliki nagłówkowe Niksa.
 # avoid BOOST_LDFLAGS=-L%{_libdir} which causes to link with system nix libraries instead of built ones
 %{__make} \
 	BOOST_LDFLAGS="" \
+	GLOBAL_CXXFLAGS="%{rpmcxxflags} -Wall -include config.h -std=c++17 -I src -fPIC" \
+	GLOBAL_LDFLAGS="%{rpmldflags}" \
 	V=1
 
 %if %{with perl}
@@ -135,25 +194,22 @@ rm -rf $RPM_BUILD_ROOT
 
 install -d $RPM_BUILD_ROOT%{nixdir}/{store,var/nix/{gcroots,profiles}/per-user}
 
+%{__rm} $RPM_BUILD_ROOT%{_mandir}/man1/nix3-manpages
 # dead upstart stuff
 %{__rm} -r $RPM_BUILD_ROOT/etc/init
-# packaged as %doc
-%{__rm} -r $RPM_BUILD_ROOT%{_docdir}/manual
 
 %clean
 rm -rf $RPM_BUILD_ROOT
 
 %files
 %defattr(644,root,root,755)
-%doc README.md doc/manual/{manual.html,figures,images}
+%doc README.md
 %attr(755,root,root) %{_bindir}/nix*
 %dir %{_libdir}/%{name}
 %attr(755,root,root) %{_libdir}/%{name}/build-remote
-%dir %{_datadir}/%{name}
-%{_datadir}/%{name}/corepkgs
-%{_datadir}/%{name}/sandbox
 %{systemdunitdir}/nix-daemon.service
 %{systemdunitdir}/nix-daemon.socket
+%{systemdtmpfilesdir}/nix-daemon.conf
 /etc/profile.d/nix.sh
 /etc/profile.d/nix-daemon.sh
 %dir %{nixdir}
@@ -164,13 +220,19 @@ rm -rf $RPM_BUILD_ROOT
 %dir %{nixdir}/var/nix/gcroots/per-user
 %dir %{nixdir}/var/nix/profiles
 %dir %{nixdir}/var/nix/profiles/per-user
+%{_mandir}/man1/nix.1*
 %{_mandir}/man1/nix-*.1*
+%{_mandir}/man1/nix3-*.1*
 %{_mandir}/man5/nix.conf.5*
 %{_mandir}/man8/nix-daemon.8*
+%dir %{_docdir}/nix
+%{_docdir}/nix/manual
 
 %files libs
 %defattr(644,root,root,755)
+%attr(755,root,root) %{_libdir}/libnixcmd.so
 %attr(755,root,root) %{_libdir}/libnixexpr.so
+%attr(755,root,root) %{_libdir}/libnixfetchers.so
 %attr(755,root,root) %{_libdir}/libnixmain.so
 %attr(755,root,root) %{_libdir}/libnixstore.so
 %attr(755,root,root) %{_libdir}/libnixutil.so
@@ -178,6 +240,20 @@ rm -rf $RPM_BUILD_ROOT
 %files devel
 %defattr(644,root,root,755)
 %{_includedir}/nix
+%{_pkgconfigdir}/nix-cmd.pc
 %{_pkgconfigdir}/nix-expr.pc
 %{_pkgconfigdir}/nix-main.pc
 %{_pkgconfigdir}/nix-store.pc
+
+%files -n bash-completion-nix
+%defattr(644,root,root,755)
+%{bash_compdir}/nix
+
+%files -n fish-completion-nix
+%defattr(644,root,root,755)
+%{fish_compdir}/nix.fish
+
+%files -n zsh-completion-nix
+%defattr(644,root,root,755)
+%{zsh_compdir}/_nix
+%{zsh_compdir}/run-help-nix
diff --git a/nix-fix_nix_DIR_in_doc_local_mk.patch b/nix-fix_nix_DIR_in_doc_local_mk.patch
new file mode 100644
index 0000000..375864b
--- /dev/null
+++ b/nix-fix_nix_DIR_in_doc_local_mk.patch
@@ -0,0 +1,57 @@
+Subject: Fix build phase depending on installed binary
+Author: Thomas Koch <thomas at koch.ro>
+Bug: https://github.com/NixOS/nix/issues/5781
+Forwarded: https://github.com/NixOS/nix/pull/6015
+
+--- a/doc/manual/local.mk
++++ b/doc/manual/local.mk
+@@ -20,7 +20,7 @@ dummy-env = env -i \
+ 	NIX_STATE_DIR=/dummy \
+ 	NIX_CONFIG='cores = 0'
+ 
+-nix-eval = $(dummy-env) $(bindir)/nix eval --experimental-features nix-command -I nix/corepkgs=corepkgs --store dummy:// --impure --raw
++nix-eval = $(dummy-env) $(nix_DIR)/nix eval --experimental-features nix-command -I nix/corepkgs=corepkgs --store dummy:// --impure --raw
+ 
+ $(d)/%.1: $(d)/src/command-ref/%.md
+ 	@printf "Title: %s\n\n" "$$(basename $@ .1)" > $^.tmp
+@@ -44,31 +44,31 @@ $(d)/src/SUMMARY.md: $(d)/src/SUMMARY.md
+ 	$(trace-gen) cat doc/manual/src/SUMMARY.md.in | while IFS= read line; do if [[ $$line = @manpages@ ]]; then cat doc/manual/src/command-ref/new-cli/SUMMARY.md; else echo "$$line"; fi; done > $@.tmp
+ 	@mv $@.tmp $@
+ 
+-$(d)/src/command-ref/new-cli: $(d)/nix.json $(d)/generate-manpage.nix $(bindir)/nix
++$(d)/src/command-ref/new-cli: $(d)/nix.json $(d)/generate-manpage.nix $(nix_DIR)/nix
+ 	@rm -rf $@
+ 	$(trace-gen) $(nix-eval) --write-to $@ --expr 'import doc/manual/generate-manpage.nix { command = builtins.readFile $<; renderLinks = true; }'
+ 
+-$(d)/src/command-ref/conf-file.md: $(d)/conf-file.json $(d)/generate-options.nix $(d)/src/command-ref/conf-file-prefix.md $(bindir)/nix
++$(d)/src/command-ref/conf-file.md: $(d)/conf-file.json $(d)/generate-options.nix $(d)/src/command-ref/conf-file-prefix.md $(nix_DIR)/nix
+ 	@cat doc/manual/src/command-ref/conf-file-prefix.md > $@.tmp
+ 	$(trace-gen) $(nix-eval) --expr 'import doc/manual/generate-options.nix (builtins.fromJSON (builtins.readFile $<))' >> $@.tmp
+ 	@mv $@.tmp $@
+ 
+-$(d)/nix.json: $(bindir)/nix
+-	$(trace-gen) $(dummy-env) $(bindir)/nix __dump-args > $@.tmp
++$(d)/nix.json: $(nix_DIR)/nix
++	$(trace-gen) $(dummy-env) $(nix_DIR)/nix __dump-args > $@.tmp
+ 	@mv $@.tmp $@
+ 
+-$(d)/conf-file.json: $(bindir)/nix
+-	$(trace-gen) $(dummy-env) $(bindir)/nix show-config --json --experimental-features nix-command > $@.tmp
++$(d)/conf-file.json: $(nix_DIR)/nix
++	$(trace-gen) $(dummy-env) $(nix_DIR)/nix show-config --json --experimental-features nix-command > $@.tmp
+ 	@mv $@.tmp $@
+ 
+-$(d)/src/expressions/builtins.md: $(d)/builtins.json $(d)/generate-builtins.nix $(d)/src/expressions/builtins-prefix.md $(bindir)/nix
++$(d)/src/expressions/builtins.md: $(d)/builtins.json $(d)/generate-builtins.nix $(d)/src/expressions/builtins-prefix.md $(nix_DIR)/nix
+ 	@cat doc/manual/src/expressions/builtins-prefix.md > $@.tmp
+ 	$(trace-gen) $(nix-eval) --expr 'import doc/manual/generate-builtins.nix (builtins.fromJSON (builtins.readFile $<))' >> $@.tmp
+ 	@cat doc/manual/src/expressions/builtins-suffix.md >> $@.tmp
+ 	@mv $@.tmp $@
+ 
+-$(d)/builtins.json: $(bindir)/nix
+-	$(trace-gen) $(dummy-env) NIX_PATH=nix/corepkgs=corepkgs $(bindir)/nix __dump-builtins > $@.tmp
++$(d)/builtins.json: $(nix_DIR)/nix
++	$(trace-gen) $(dummy-env) NIX_PATH=nix/corepkgs=corepkgs $(nix_DIR)/nix __dump-builtins > $@.tmp
+ 	@mv $@.tmp $@
+ 
+ # Generate the HTML manual.
diff --git a/nix-g++.patch b/nix-g++.patch
new file mode 100644
index 0000000..4fbceab
--- /dev/null
+++ b/nix-g++.patch
@@ -0,0 +1,2730 @@
+--- nix-2.9.2/src/libmain/common-args.hh.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libmain/common-args.hh	2022-07-05 06:29:47.472950706 +0200
+@@ -23,7 +23,7 @@ struct MixDryRun : virtual Args
+ 
+     MixDryRun()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "dry-run",
+             .description = "Show what this command would do without doing it.",
+             //.category = commonArgsCategory,
+@@ -38,7 +38,7 @@ struct MixJSON : virtual Args
+ 
+     MixJSON()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "json",
+             .description = "Produce output in JSON format, suitable for consumption by another program.",
+             //.category = commonArgsCategory,
+--- nix-2.9.2/src/libutil/args.hh.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libutil/args.hh	2022-07-05 20:37:53.280611956 +0200
+@@ -13,6 +13,7 @@ namespace nix {
+ enum HashType : char;
+ 
+ class MultiCommand;
++template <typename T> class BaseSetting;
+ 
+ class Args
+ {
+@@ -179,6 +180,8 @@ public:
+     virtual nlohmann::json toJSON();
+ 
+     friend class MultiCommand;
++    template <typename T>
++    friend class BaseSetting;
+ 
+     MultiCommand * parent = nullptr;
+ };
+--- nix-2.9.2/src/libutil/config.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libutil/config.cc	2022-07-05 20:31:23.672722643 +0200
+@@ -204,7 +204,7 @@ bool BaseSetting<T>::isAppendable()
+ template<typename T>
+ void BaseSetting<T>::convertToArg(Args & args, const std::string & category)
+ {
+-    args.addFlag({
++    args.addFlag(Args::Flag{
+         .longName = name,
+         .description = fmt("Set the `%s` setting.", name),
+         .category = category,
+@@ -213,7 +213,7 @@ void BaseSetting<T>::convertToArg(Args &
+     });
+ 
+     if (isAppendable())
+-        args.addFlag({
++        args.addFlag(Args::Flag{
+             .longName = "extra-" + name,
+             .description = fmt("Append to the `%s` setting.", name),
+             .category = category,
+@@ -266,13 +266,13 @@ template<> std::string BaseSetting<bool>
+ 
+ template<> void BaseSetting<bool>::convertToArg(Args & args, const std::string & category)
+ {
+-    args.addFlag({
++    args.addFlag(Args::Flag{
+         .longName = name,
+         .description = fmt("Enable the `%s` setting.", name),
+         .category = category,
+         .handler = {[=]() { override(true); }}
+     });
+-    args.addFlag({
++    args.addFlag(Args::Flag{
+         .longName = "no-" + name,
+         .description = fmt("Disable the `%s` setting.", name),
+         .category = category,
+--- nix-2.9.2/src/nix/add-to-store.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/nix/add-to-store.cc	2022-07-05 16:58:41.943554228 +0200
+@@ -16,7 +16,7 @@ struct CmdAddToStore : MixDryRun, StoreC
+         // FIXME: completion
+         expectArg("path", &path);
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "name",
+             .shortName = 'n',
+             .description = "Override the name component of the store path. It defaults to the base name of *path*.",
+--- nix-2.9.2/src/nix/build.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/nix/build.cc	2022-07-05 16:59:38.756379823 +0200
+@@ -18,7 +18,7 @@ struct CmdBuild : InstallablesCommand, M
+ 
+     CmdBuild()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "out-link",
+             .shortName = 'o',
+             .description = "Use *path* as prefix for the symlinks to the build results. It defaults to `result`.",
+@@ -27,19 +27,19 @@ struct CmdBuild : InstallablesCommand, M
+             .completer = completePath
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "no-link",
+             .description = "Do not create symlinks to the build results.",
+             .handler = {&outLink, Path("")},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "print-out-paths",
+             .description = "Print the resulting output paths",
+             .handler = {&printOutputPaths, true},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "rebuild",
+             .description = "Rebuild an already built package and compare the result to the existing store paths.",
+             .handler = {&buildMode, bmCheck},
+--- nix-2.9.2/src/nix/bundle.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/nix/bundle.cc	2022-07-05 17:01:44.829545208 +0200
+@@ -14,7 +14,7 @@ struct CmdBundle : InstallableCommand
+ 
+     CmdBundle()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "bundler",
+             .description = fmt("Use a custom bundler instead of the default (`%s`).", bundler),
+             .labels = {"flake-url"},
+@@ -24,7 +24,7 @@ struct CmdBundle : InstallableCommand
+             }}
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "out-link",
+             .shortName = 'o',
+             .description = "Override the name of the symlink to the build result. It defaults to the base name of the app.",
+--- nix-2.9.2/src/nix/copy.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/nix/copy.cc	2022-07-05 17:03:45.495241958 +0200
+@@ -15,13 +15,13 @@ struct CmdCopy : virtual CopyCommand, vi
+     CmdCopy()
+         : BuiltPathsCommand(true)
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "no-check-sigs",
+             .description = "Do not require that paths are signed by trusted keys.",
+             .handler = {&checkSigs, NoCheckSigs},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "substitute-on-destination",
+             .shortName = 's',
+             .description = "Whether to try substitutes on the destination store (only supported by SSH stores).",
+--- nix-2.9.2/src/nix/develop.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/nix/develop.cc	2022-07-05 17:07:02.563175521 +0200
+@@ -261,7 +261,7 @@ struct Common : InstallableCommand, MixP
+ 
+     Common()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "redirect",
+             .description = "Redirect a store path to a mutable location.",
+             .labels = {"installable", "outputs-dir"},
+@@ -384,7 +384,7 @@ struct CmdDevelop : Common, MixEnvironme
+ 
+     CmdDevelop()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "command",
+             .shortName = 'c',
+             .description = "Instead of starting an interactive shell, start the specified command and arguments.",
+@@ -395,44 +395,44 @@ struct CmdDevelop : Common, MixEnvironme
+             }}
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "phase",
+             .description = "The stdenv phase to run (e.g. `build` or `configure`).",
+             .labels = {"phase-name"},
+             .handler = {&phase},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "unpack",
+             .description = "Run the `unpack` phase.",
+             .handler = {&phase, {"unpack"}},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "configure",
+             .description = "Run the `configure` phase.",
+             .handler = {&phase, {"configure"}},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "build",
+             .description = "Run the `build` phase.",
+             .handler = {&phase, {"build"}},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "check",
+             .description = "Run the `check` phase.",
+             .handler = {&phase, {"check"}},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "install",
+             .description = "Run the `install` phase.",
+             .handler = {&phase, {"install"}},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "installcheck",
+             .description = "Run the `installcheck` phase.",
+             .handler = {&phase, {"installCheck"}},
+--- nix-2.9.2/src/nix/eval.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/nix/eval.cc	2022-07-05 17:20:44.763154510 +0200
+@@ -18,20 +18,20 @@ struct CmdEval : MixJSON, InstallableCom
+ 
+     CmdEval() : InstallableCommand(true /* supportReadOnlyMode */)
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "raw",
+             .description = "Print strings without quotes or escaping.",
+             .handler = {&raw, true},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "apply",
+             .description = "Apply the function *expr* to each argument.",
+             .labels = {"expr"},
+             .handler = {&apply},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "write-to",
+             .description = "Write a string or attrset of strings to *path*.",
+             .labels = {"path"},
+--- nix-2.9.2/src/nix/flake.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/nix/flake.cc	2022-07-05 18:18:54.437282756 +0200
+@@ -260,7 +260,7 @@ struct CmdFlakeCheck : FlakeCommand
+ 
+     CmdFlakeCheck()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "no-build",
+             .description = "Do not build checks.",
+             .handler = {&build, false}
+@@ -698,7 +698,7 @@ struct CmdFlakeInitCommon : virtual Args
+ 
+     CmdFlakeInitCommon()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "template",
+             .shortName = 't',
+             .description = "The template to use.",
+@@ -854,7 +854,7 @@ struct CmdFlakeClone : FlakeCommand
+ 
+     CmdFlakeClone()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "dest",
+             .shortName = 'f',
+             .description = "Clone the flake to path *dest*.",
+@@ -878,7 +878,7 @@ struct CmdFlakeArchive : FlakeCommand, M
+ 
+     CmdFlakeArchive()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "to",
+             .description = "URI of the destination Nix store",
+             .labels = {"store-uri"},
+@@ -945,7 +945,7 @@ struct CmdFlakeShow : FlakeCommand, MixJ
+ 
+     CmdFlakeShow()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "legacy",
+             .description = "Show the contents of the `legacyPackages` output.",
+             .handler = {&showLegacy, true}
+--- nix-2.9.2/src/nix/hash.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/nix/hash.cc	2022-07-05 19:00:33.030613543 +0200
+@@ -19,25 +19,25 @@ struct CmdHashBase : Command
+ 
+     CmdHashBase(FileIngestionMethod mode) : mode(mode)
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "sri",
+             .description = "Print the hash in SRI format.",
+             .handler = {&base, SRI},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "base64",
+             .description = "Print the hash in base-64 format.",
+             .handler = {&base, Base64},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "base32",
+             .description = "Print the hash in base-32 (Nix-specific) format.",
+             .handler = {&base, Base32},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "base16",
+             .description = "Print the hash in base-16 format.",
+             .handler = {&base, Base16},
+@@ -46,7 +46,7 @@ struct CmdHashBase : Command
+         addFlag(Flag::mkHashTypeFlag("type", &ht));
+ 
+         #if 0
+-        addFlag({
++        addFlag(Flag{
+             .longName = "modulo",
+             .description = "Compute the hash modulo the specified string.",
+             .labels = {"modulus"},
+--- nix-2.9.2/src/nix/ls.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/nix/ls.cc	2022-07-05 19:04:45.879233582 +0200
+@@ -17,21 +17,21 @@ struct MixLs : virtual Args, MixJSON
+ 
+     MixLs()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "recursive",
+             .shortName = 'R',
+             .description = "List subdirectories recursively.",
+             .handler = {&recursive, true},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "long",
+             .shortName = 'l',
+             .description = "Show detailed file information.",
+             .handler = {&verbose, true},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "directory",
+             .shortName = 'd',
+             .description = "Show directories rather than their contents.",
+--- nix-2.9.2/src/nix/main.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/nix/main.cc	2022-07-05 20:07:59.235259876 +0200
+@@ -71,13 +71,13 @@ struct NixArgs : virtual MultiCommand, v
+         categories[catUtility] = "Utility/scripting commands";
+         categories[catNixInstallation] = "Commands for upgrading or troubleshooting your Nix installation";
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "help",
+             .description = "Show usage information.",
+             .handler = {[&]() { throw HelpRequested(); }},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "print-build-logs",
+             .shortName = 'L',
+             .description = "Print full build logs on standard error.",
+@@ -85,20 +85,20 @@ struct NixArgs : virtual MultiCommand, v
+             .handler = {[&]() {setLogFormat(LogFormat::barWithLogs); }},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "version",
+             .description = "Show version information.",
+             .handler = {[&]() { showVersion = true; }},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "offline",
+             .aliases = {"no-net"}, // FIXME: remove
+             .description = "Disable substituters and consider all previously downloaded files up-to-date.",
+             .handler = {[&]() { useNet = false; }},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "refresh",
+             .description = "Consider all previously downloaded files out-of-date.",
+             .handler = {[&]() { refresh = true; }},
+--- nix-2.9.2/src/nix/path-info.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/nix/path-info.cc	2022-07-05 20:52:47.872788534 +0200
+@@ -18,28 +18,28 @@ struct CmdPathInfo : StorePathsCommand,
+ 
+     CmdPathInfo()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "size",
+             .shortName = 's',
+             .description = "Print the size of the NAR serialisation of each path.",
+             .handler = {&showSize, true},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "closure-size",
+             .shortName = 'S',
+             .description = "Print the sum of the sizes of the NAR serialisations of the closure of each path.",
+             .handler = {&showClosureSize, true},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "human-readable",
+             .shortName = 'h',
+             .description = "With `-s` and `-S`, print sizes in a human-friendly format such as `5.67G`.",
+             .handler = {&humanReadable, true},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "sigs",
+             .description = "Show signatures.",
+             .handler = {&showSigs, true},
+--- nix-2.9.2/src/nix/prefetch.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/nix/prefetch.cc	2022-07-05 20:54:32.827886004 +0200
+@@ -254,14 +254,14 @@ struct CmdStorePrefetchFile : StoreComma
+ 
+     CmdStorePrefetchFile()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "name",
+             .description = "Override the name component of the resulting store path. It defaults to the base name of *url*.",
+             .labels = {"name"},
+             .handler = {&name}
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "expected-hash",
+             .description = "The expected hash of the file.",
+             .labels = {"hash"},
+@@ -272,7 +272,7 @@ struct CmdStorePrefetchFile : StoreComma
+ 
+         addFlag(Flag::mkHashTypeFlag("hash-type", &hashType));
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "executable",
+             .description =
+                 "Make the resulting file executable. Note that this causes the "
+--- nix-2.9.2/src/nix/profile.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/nix/profile.cc	2022-07-05 20:57:48.226528038 +0200
+@@ -266,7 +266,7 @@ struct CmdProfileInstall : InstallablesC
+     std::optional<int64_t> priority;
+ 
+     CmdProfileInstall() {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "priority",
+             .description = "The priority of the package to install.",
+             .labels = {"priority"},
+@@ -636,7 +636,7 @@ struct CmdProfileRollback : virtual Stor
+ 
+     CmdProfileRollback()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "to",
+             .description = "The profile version to roll back to.",
+             .labels = {"version"},
+@@ -668,7 +668,7 @@ struct CmdProfileWipeHistory : virtual S
+ 
+     CmdProfileWipeHistory()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "older-than",
+             .description =
+                 "Delete versions older than the specified age. *age* "
+--- nix-2.9.2/src/nix/registry.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/nix/registry.cc	2022-07-05 20:35:54.757374169 +0200
+@@ -21,7 +21,7 @@ public:
+ 
+     RegistryCommand()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "registry",
+             .description = "The registry to operate on.",
+             .labels = {"registry"},
+--- nix-2.9.2/src/nix/run.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/nix/run.cc	2022-07-05 20:40:36.436248286 +0200
+@@ -68,7 +68,7 @@ struct CmdShell : InstallablesCommand, M
+ 
+     CmdShell()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "command",
+             .shortName = 'c',
+             .description = "Command and arguments to be executed, defaulting to `$SHELL`",
+--- nix-2.9.2/src/nix/show-derivation.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/nix/show-derivation.cc	2022-07-05 20:49:20.993406415 +0200
+@@ -16,7 +16,7 @@ struct CmdShowDerivation : InstallablesC
+ 
+     CmdShowDerivation()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "recursive",
+             .shortName = 'r',
+             .description = "Include the dependencies of the specified derivations.",
+--- nix-2.9.2/src/nix/sigs.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/nix/sigs.cc	2022-07-05 21:14:00.669317906 +0200
+@@ -13,7 +13,7 @@ struct CmdCopySigs : StorePathsCommand
+ 
+     CmdCopySigs()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "substituter",
+             .shortName = 's',
+             .description = "Copy signatures from the specified store.",
+@@ -98,7 +98,7 @@ struct CmdSign : StorePathsCommand
+ 
+     CmdSign()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "key-file",
+             .shortName = 'k',
+             .description = "File containing the secret signing key.",
+@@ -148,7 +148,7 @@ struct CmdKeyGenerateSecret : Command
+ 
+     CmdKeyGenerateSecret()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "key-name",
+             .description = "Identifier of the key (e.g. `cache.example.org-1`).",
+             .labels = {"name"},
+--- nix-2.9.2/src/nix/store-delete.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/nix/store-delete.cc	2022-07-05 21:15:21.704278877 +0200
+@@ -13,7 +13,7 @@ struct CmdStoreDelete : StorePathsComman
+ 
+     CmdStoreDelete()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "ignore-liveness",
+             .description = "Do not check whether the paths are reachable from a root.",
+             .handler = {&options.ignoreLiveness, true}
+--- nix-2.9.2/src/nix/store-gc.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/nix/store-gc.cc	2022-07-05 21:15:56.429090794 +0200
+@@ -13,7 +13,7 @@ struct CmdStoreGC : StoreCommand, MixDry
+ 
+     CmdStoreGC()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "max",
+             .description = "Stop after freeing *n* bytes of disk space.",
+             .labels = {"n"},
+--- nix-2.9.2/src/nix/upgrade-nix.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/nix/upgrade-nix.cc	2022-07-05 21:18:23.528295879 +0200
+@@ -16,7 +16,7 @@ struct CmdUpgradeNix : MixDryRun, StoreC
+ 
+     CmdUpgradeNix()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "profile",
+             .shortName = 'p',
+             .description = "The path to the Nix profile to upgrade.",
+@@ -24,7 +24,7 @@ struct CmdUpgradeNix : MixDryRun, StoreC
+             .handler = {&profileDir}
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "nix-store-paths-url",
+             .description = "The URL of the file that contains the store paths of the latest Nix release.",
+             .labels = {"url"},
+--- nix-2.9.2/src/nix/verify.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/nix/verify.cc	2022-07-05 21:20:09.484386232 +0200
+@@ -18,19 +18,19 @@ struct CmdVerify : StorePathsCommand
+ 
+     CmdVerify()
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "no-contents",
+             .description = "Do not verify the contents of each store path.",
+             .handler = {&noContents, true},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "no-trust",
+             .description = "Do not verify whether each store path is trusted.",
+             .handler = {&noTrust, true},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "substituter",
+             .shortName = 's',
+             .description = "Use signatures from the specified store.",
+@@ -38,7 +38,7 @@ struct CmdVerify : StorePathsCommand
+             .handler = {[&](std::string s) { substituterUris.push_back(s); }}
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "sigs-needed",
+             .shortName = 'n',
+             .description = "Require that each path has at least *n* valid signatures.",
+--- nix-2.9.2/src/nix/why-depends.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/nix/why-depends.cc	2022-07-05 21:23:04.150146933 +0200
+@@ -35,7 +35,7 @@ struct CmdWhyDepends : SourceExprCommand
+ 
+     CmdWhyDepends()
+     {
+-        expectArgs({
++        expectArgs(ExpectedArg{
+             .label = "package",
+             .handler = {&_package},
+             .completer = {[&](size_t, std::string_view prefix) {
+@@ -43,7 +43,7 @@ struct CmdWhyDepends : SourceExprCommand
+             }}
+         });
+ 
+-        expectArgs({
++        expectArgs(ExpectedArg{
+             .label = "dependency",
+             .handler = {&_dependency},
+             .completer = {[&](size_t, std::string_view prefix) {
+@@ -51,14 +51,14 @@ struct CmdWhyDepends : SourceExprCommand
+             }}
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "all",
+             .shortName = 'a',
+             .description = "Show all edges in the dependency graph leading from *package* to *dependency*, rather than just a shortest path.",
+             .handler = {&all, true},
+         });
+ 
+-        addFlag({
++        addFlag(Flag{
+             .longName = "precise",
+             .description = "For each edge in the dependency graph, show the files in the parent that cause the dependency.",
+             .handler = {&precise, true},
+--- nix-2.9.2/src/libexpr/eval.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libexpr/eval.cc	2022-07-05 21:20:29.491541937 +0200
+@@ -847,7 +847,7 @@ void EvalState::runDebugRepl(const Error
+    exceptions. */
+ void EvalState::throwEvalError(const PosIdx pos, const char * s, Env & env, Expr & expr)
+ {
+-    debugThrow(EvalError({
++    debugThrow(EvalError(ErrorInfo{
+         .msg = hintfmt(s),
+         .errPos = positions[pos]
+     }), env, expr);
+@@ -855,7 +855,7 @@ void EvalState::throwEvalError(const Pos
+ 
+ void EvalState::throwEvalError(const PosIdx pos, const char * s)
+ {
+-    debugThrowLastTrace(EvalError({
++    debugThrowLastTrace(EvalError(ErrorInfo{
+         .msg = hintfmt(s),
+         .errPos = positions[pos]
+     }));
+@@ -878,7 +878,7 @@ void EvalState::throwEvalError(const Pos
+ 
+ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2)
+ {
+-    debugThrowLastTrace(EvalError({
++    debugThrowLastTrace(EvalError(ErrorInfo{
+         .msg = hintfmt(s, s2),
+         .errPos = positions[pos]
+     }));
+@@ -886,7 +886,7 @@ void EvalState::throwEvalError(const Pos
+ 
+ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2, Env & env, Expr & expr)
+ {
+-    debugThrow(EvalError({
++    debugThrow(EvalError(ErrorInfo{
+         .msg = hintfmt(s, s2),
+         .errPos = positions[pos]
+     }), env, expr);
+@@ -895,7 +895,7 @@ void EvalState::throwEvalError(const Pos
+ void EvalState::throwEvalError(const char * s, const std::string & s2,
+     const std::string & s3)
+ {
+-    debugThrowLastTrace(EvalError({
++    debugThrowLastTrace(EvalError(ErrorInfo{
+         .msg = hintfmt(s, s2),
+         .errPos = positions[noPos]
+     }));
+@@ -904,7 +904,7 @@ void EvalState::throwEvalError(const cha
+ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2,
+     const std::string & s3)
+ {
+-    debugThrowLastTrace(EvalError({
++    debugThrowLastTrace(EvalError(ErrorInfo{
+         .msg = hintfmt(s, s2),
+         .errPos = positions[pos]
+     }));
+@@ -913,7 +913,7 @@ void EvalState::throwEvalError(const Pos
+ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2,
+     const std::string & s3, Env & env, Expr & expr)
+ {
+-    debugThrow(EvalError({
++    debugThrow(EvalError(ErrorInfo{
+         .msg = hintfmt(s, s2),
+         .errPos = positions[pos]
+     }), env, expr);
+@@ -922,7 +922,7 @@ void EvalState::throwEvalError(const Pos
+ void EvalState::throwEvalError(const PosIdx p1, const char * s, const Symbol sym, const PosIdx p2, Env & env, Expr & expr)
+ {
+     // p1 is where the error occurred; p2 is a position mentioned in the message.
+-    debugThrow(EvalError({
++    debugThrow(EvalError(ErrorInfo{
+         .msg = hintfmt(s, symbols[sym], positions[p2]),
+         .errPos = positions[p1]
+     }), env, expr);
+@@ -930,7 +930,7 @@ void EvalState::throwEvalError(const Pos
+ 
+ void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v)
+ {
+-    debugThrowLastTrace(TypeError({
++    debugThrowLastTrace(TypeError(ErrorInfo{
+         .msg = hintfmt(s, showType(v)),
+         .errPos = positions[pos]
+     }));
+@@ -938,7 +938,7 @@ void EvalState::throwTypeError(const Pos
+ 
+ void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v, Env & env, Expr & expr)
+ {
+-    debugThrow(TypeError({
++    debugThrow(TypeError(ErrorInfo{
+         .msg = hintfmt(s, showType(v)),
+         .errPos = positions[pos]
+     }), env, expr);
+@@ -946,7 +946,7 @@ void EvalState::throwTypeError(const Pos
+ 
+ void EvalState::throwTypeError(const PosIdx pos, const char * s)
+ {
+-    debugThrowLastTrace(TypeError({
++    debugThrowLastTrace(TypeError(ErrorInfo{
+         .msg = hintfmt(s),
+         .errPos = positions[pos]
+     }));
+@@ -955,7 +955,7 @@ void EvalState::throwTypeError(const Pos
+ void EvalState::throwTypeError(const PosIdx pos, const char * s, const ExprLambda & fun,
+     const Symbol s2, Env & env, Expr &expr)
+ {
+-    debugThrow(TypeError({
++    debugThrow(TypeError(ErrorInfo{
+         .msg = hintfmt(s, fun.showNamePos(*this), symbols[s2]),
+         .errPos = positions[pos]
+     }), env, expr);
+@@ -973,7 +973,7 @@ void EvalState::throwTypeError(const Pos
+ 
+ void EvalState::throwTypeError(const char * s, const Value & v, Env & env, Expr &expr)
+ {
+-    debugThrow(TypeError({
++    debugThrow(TypeError(ErrorInfo{
+         .msg = hintfmt(s, showType(v)),
+         .errPos = positions[expr.getPos()],
+     }), env, expr);
+@@ -981,7 +981,7 @@ void EvalState::throwTypeError(const cha
+ 
+ void EvalState::throwAssertionError(const PosIdx pos, const char * s, const std::string & s1, Env & env, Expr &expr)
+ {
+-    debugThrow(AssertionError({
++    debugThrow(AssertionError(ErrorInfo{
+         .msg = hintfmt(s, s1),
+         .errPos = positions[pos]
+     }), env, expr);
+@@ -989,7 +989,7 @@ void EvalState::throwAssertionError(cons
+ 
+ void EvalState::throwUndefinedVarError(const PosIdx pos, const char * s, const std::string & s1, Env & env, Expr &expr)
+ {
+-    debugThrow(UndefinedVarError({
++    debugThrow(UndefinedVarError(ErrorInfo{
+         .msg = hintfmt(s, s1),
+         .errPos = positions[pos]
+     }), env, expr);
+@@ -997,7 +997,7 @@ void EvalState::throwUndefinedVarError(c
+ 
+ void EvalState::throwMissingArgumentError(const PosIdx pos, const char * s, const std::string & s1, Env & env, Expr &expr)
+ {
+-    debugThrow(MissingArgumentError({
++    debugThrow(MissingArgumentError(ErrorInfo{
+         .msg = hintfmt(s, s1),
+         .errPos = positions[pos]
+     }), env, expr);
+@@ -2324,7 +2324,7 @@ StorePath EvalState::coerceToStorePath(c
+     auto path = coerceToString(pos, v, context, false, false).toOwned();
+     if (auto storePath = store->maybeParseStorePath(path))
+         return *storePath;
+-    throw EvalError({
++    throw EvalError(ErrorInfo{
+         .msg = hintfmt("path '%1%' is not in the Nix store", path),
+         .errPos = positions[pos]
+     });
+@@ -2531,7 +2531,7 @@ void EvalState::printStats()
+ 
+ std::string ExternalValueBase::coerceToString(const Pos & pos, PathSet & context, bool copyMore, bool copyToStore) const
+ {
+-    throw TypeError({
++    throw TypeError(ErrorInfo{
+         .msg = hintfmt("cannot coerce %1% to a string", showType()),
+         .errPos = pos
+     });
+--- nix-2.9.2/src/libexpr/flake/flake.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libexpr/flake/flake.cc	2022-07-05 21:25:57.822396545 +0200
+@@ -730,7 +730,7 @@ static void prim_getFlake(EvalState & st
+         v);
+ }
+ 
+-static RegisterPrimOp r2({
++static RegisterPrimOp r2(RegisterPrimOp::Info{
+     .name =  "__getFlake",
+     .args = {"args"},
+     .doc = R"(
+--- nix-2.9.2/src/libexpr/lexer.l.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libexpr/lexer.l	2022-07-05 20:49:05.845576982 +0200
+@@ -153,7 +153,7 @@ or          { return OR_KW; }
+               try {
+                   yylval->n = boost::lexical_cast<int64_t>(yytext);
+               } catch (const boost::bad_lexical_cast &) {
+-                  throw ParseError({
++                  throw ParseError(ErrorInfo{
+                       .msg = hintfmt("invalid integer '%1%'", yytext),
+                       .errPos = data->state.positions[CUR_POS],
+                   });
+@@ -163,7 +163,7 @@ or          { return OR_KW; }
+ {FLOAT}     { errno = 0;
+               yylval->nf = strtod(yytext, 0);
+               if (errno != 0)
+-                  throw ParseError({
++                  throw ParseError(ErrorInfo{
+                       .msg = hintfmt("invalid float '%1%'", yytext),
+                       .errPos = data->state.positions[CUR_POS],
+                   });
+@@ -292,7 +292,7 @@ or          { return OR_KW; }
+ 
+ <INPATH_SLASH>{ANY} |
+ <INPATH_SLASH><<EOF>> {
+-  throw ParseError({
++  throw ParseError(ErrorInfo{
+       .msg = hintfmt("path has a trailing slash"),
+       .errPos = data->state.positions[CUR_POS],
+   });
+--- nix-2.9.2/src/libexpr/nixexpr.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libexpr/nixexpr.cc	2022-07-05 20:51:16.964756648 +0200
+@@ -349,7 +349,7 @@ void ExprVar::bindVars(EvalState & es, c
+        enclosing `with'.  If there is no `with', then we can issue an
+        "undefined variable" error now. */
+     if (withLevel == -1)
+-        throw UndefinedVarError({
++        throw UndefinedVarError(ErrorInfo{
+             .msg = hintfmt("undefined variable '%1%'", es.symbols[name]),
+             .errPos = es.positions[pos]
+         });
+--- nix-2.9.2/src/libexpr/parser.y.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libexpr/parser.y	2022-07-05 20:57:44.644999732 +0200
+@@ -79,7 +79,7 @@ namespace nix {
+ 
+ static void dupAttr(const EvalState & state, const AttrPath & attrPath, const PosIdx pos, const PosIdx prevPos)
+ {
+-    throw ParseError({
++    throw ParseError(ErrorInfo{
+          .msg = hintfmt("attribute '%1%' already defined at %2%",
+              showAttrPath(state.symbols, attrPath), state.positions[prevPos]),
+          .errPos = state.positions[pos]
+@@ -88,7 +88,7 @@ static void dupAttr(const EvalState & st
+ 
+ static void dupAttr(const EvalState & state, Symbol attr, const PosIdx pos, const PosIdx prevPos)
+ {
+-    throw ParseError({
++    throw ParseError(ErrorInfo{
+         .msg = hintfmt("attribute '%1%' already defined at %2%", state.symbols[attr], state.positions[prevPos]),
+         .errPos = state.positions[pos]
+     });
+@@ -172,7 +172,7 @@ static Formals * toFormals(ParseData & d
+         duplicate = std::min(thisDup, duplicate.value_or(thisDup));
+     }
+     if (duplicate)
+-        throw ParseError({
++        throw ParseError(ErrorInfo{
+             .msg = hintfmt("duplicate formal function argument '%1%'", data.symbols[duplicate->first]),
+             .errPos = data.state.positions[duplicate->second]
+         });
+@@ -182,7 +182,7 @@ static Formals * toFormals(ParseData & d
+     result.formals = std::move(formals->formals);
+ 
+     if (arg && result.has(arg))
+-        throw ParseError({
++        throw ParseError(ErrorInfo{
+             .msg = hintfmt("duplicate formal function argument '%1%'", data.symbols[arg]),
+             .errPos = data.state.positions[pos]
+         });
+@@ -297,7 +297,7 @@ static inline PosIdx makeCurPos(const YY
+ 
+ void yyerror(YYLTYPE * loc, yyscan_t scanner, ParseData * data, const char * error)
+ {
+-    data->error = {
++    data->error = ErrorInfo{
+         .msg = hintfmt(error),
+         .errPos = data->state.positions[makeCurPos(*loc, data)]
+     };
+@@ -386,7 +386,7 @@ expr_function
+     { $$ = new ExprWith(CUR_POS, $2, $4); }
+   | LET binds IN expr_function
+     { if (!$2->dynamicAttrs.empty())
+-        throw ParseError({
++        throw ParseError(ErrorInfo{
+             .msg = hintfmt("dynamic attributes not allowed in let"),
+             .errPos = data->state.positions[CUR_POS]
+         });
+@@ -475,7 +475,7 @@ expr_simple
+   | URI {
+       static bool noURLLiterals = settings.isExperimentalFeatureEnabled(Xp::NoUrlLiterals);
+       if (noURLLiterals)
+-          throw ParseError({
++          throw ParseError(ErrorInfo{
+               .msg = hintfmt("URL literals are disabled"),
+               .errPos = data->state.positions[CUR_POS]
+           });
+@@ -563,7 +563,7 @@ attrs
+           $$->push_back(AttrName(data->symbols.create(str->s)));
+           delete str;
+       } else
+-          throw ParseError({
++          throw ParseError(ErrorInfo{
+               .msg = hintfmt("dynamic attributes not allowed in inherit"),
+               .errPos = data->state.positions[makeCurPos(@2, data)]
+           });
+@@ -782,7 +782,7 @@ Path EvalState::findFile(SearchPath & se
+     if (hasPrefix(path, "nix/"))
+         return concatStrings(corepkgsPrefix, path.substr(4));
+ 
+-    debugThrowLastTrace(ThrownError({
++    debugThrowLastTrace(ThrownError(ErrorInfo{
+         .msg = hintfmt(evalSettings.pureEval
+             ? "cannot look up '<%s>' in pure evaluation mode (use '--impure' to override)"
+             : "file '%s' was not found in the Nix search path (add it using $NIX_PATH or -I)",
+@@ -804,7 +804,7 @@ std::pair<bool, std::string> EvalState::
+             res = { true, store->toRealPath(fetchers::downloadTarball(
+                         store, resolveUri(elem.second), "source", false).first.storePath) };
+         } catch (FileTransferError & e) {
+-            logWarning({
++            logWarning(ErrorInfo{
+                 .msg = hintfmt("Nix search path entry '%1%' cannot be downloaded, ignoring", elem.second)
+             });
+             res = { false, "" };
+@@ -814,7 +814,7 @@ std::pair<bool, std::string> EvalState::
+         if (pathExists(path))
+             res = { true, path };
+         else {
+-            logWarning({
++            logWarning(ErrorInfo{
+                 .msg = hintfmt("Nix search path entry '%1%' does not exist, ignoring", elem.second)
+             });
+             res = { false, "" };
+--- nix-2.9.2/src/libexpr/primops.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libexpr/primops.cc	2022-07-05 21:28:43.612495512 +0200
+@@ -244,7 +244,7 @@ static RegisterPrimOp primop_scopedImpor
+     }
+ });
+ 
+-static RegisterPrimOp primop_import({
++static RegisterPrimOp primop_import(RegisterPrimOp::Info{
+     .name = "import",
+     .args = {"path"},
+     .doc = R"(
+@@ -344,7 +344,7 @@ void prim_exec(EvalState & state, const
+     auto elems = args[0]->listElems();
+     auto count = args[0]->listSize();
+     if (count == 0)
+-        state.debugThrowLastTrace(EvalError({
++        state.debugThrowLastTrace(EvalError(ErrorInfo{
+             .msg = hintfmt("at least one argument to 'exec' required"),
+             .errPos = state.positions[pos]
+         }));
+@@ -357,7 +357,7 @@ void prim_exec(EvalState & state, const
+     try {
+         auto _ = state.realiseContext(context); // FIXME: Handle CA derivations
+     } catch (InvalidPathError & e) {
+-        state.debugThrowLastTrace(EvalError({
++        state.debugThrowLastTrace(EvalError(ErrorInfo{
+             .msg = hintfmt("cannot execute '%1%', since path '%2%' is not valid",
+                 program, e.path),
+             .errPos = state.positions[pos]
+@@ -405,7 +405,7 @@ static void prim_typeOf(EvalState & stat
+     v.mkString(t);
+ }
+ 
+-static RegisterPrimOp primop_typeOf({
++static RegisterPrimOp primop_typeOf(RegisterPrimOp::Info{
+     .name = "__typeOf",
+     .args = {"e"},
+     .doc = R"(
+@@ -423,7 +423,7 @@ static void prim_isNull(EvalState & stat
+     v.mkBool(args[0]->type() == nNull);
+ }
+ 
+-static RegisterPrimOp primop_isNull({
++static RegisterPrimOp primop_isNull(RegisterPrimOp::Info{
+     .name = "isNull",
+     .args = {"e"},
+     .doc = R"(
+@@ -443,7 +443,7 @@ static void prim_isFunction(EvalState &
+     v.mkBool(args[0]->type() == nFunction);
+ }
+ 
+-static RegisterPrimOp primop_isFunction({
++static RegisterPrimOp primop_isFunction(RegisterPrimOp::Info{
+     .name = "__isFunction",
+     .args = {"e"},
+     .doc = R"(
+@@ -459,7 +459,7 @@ static void prim_isInt(EvalState & state
+     v.mkBool(args[0]->type() == nInt);
+ }
+ 
+-static RegisterPrimOp primop_isInt({
++static RegisterPrimOp primop_isInt(RegisterPrimOp::Info{
+     .name = "__isInt",
+     .args = {"e"},
+     .doc = R"(
+@@ -475,7 +475,7 @@ static void prim_isFloat(EvalState & sta
+     v.mkBool(args[0]->type() == nFloat);
+ }
+ 
+-static RegisterPrimOp primop_isFloat({
++static RegisterPrimOp primop_isFloat(RegisterPrimOp::Info{
+     .name = "__isFloat",
+     .args = {"e"},
+     .doc = R"(
+@@ -491,7 +491,7 @@ static void prim_isString(EvalState & st
+     v.mkBool(args[0]->type() == nString);
+ }
+ 
+-static RegisterPrimOp primop_isString({
++static RegisterPrimOp primop_isString(RegisterPrimOp::Info{
+     .name = "__isString",
+     .args = {"e"},
+     .doc = R"(
+@@ -507,7 +507,7 @@ static void prim_isBool(EvalState & stat
+     v.mkBool(args[0]->type() == nBool);
+ }
+ 
+-static RegisterPrimOp primop_isBool({
++static RegisterPrimOp primop_isBool(RegisterPrimOp::Info{
+     .name = "__isBool",
+     .args = {"e"},
+     .doc = R"(
+@@ -523,7 +523,7 @@ static void prim_isPath(EvalState & stat
+     v.mkBool(args[0]->type() == nPath);
+ }
+ 
+-static RegisterPrimOp primop_isPath({
++static RegisterPrimOp primop_isPath(RegisterPrimOp::Info{
+     .name = "__isPath",
+     .args = {"e"},
+     .doc = R"(
+@@ -597,12 +597,12 @@ static Bindings::iterator getAttr(
+ 
+         auto aPos = attrSet->pos;
+         if (!aPos) {
+-            state.debugThrowLastTrace(TypeError({
++            state.debugThrowLastTrace(TypeError(ErrorInfo{
+                 .msg = errorMsg,
+                 .errPos = state.positions[pos],
+             }));
+         } else {
+-            auto e = TypeError({
++            auto e = TypeError(ErrorInfo{
+                 .msg = errorMsg,
+                 .errPos = state.positions[aPos],
+             });
+@@ -664,7 +664,7 @@ static void prim_genericClosure(EvalStat
+         Bindings::iterator key =
+             e->attrs->find(state.sKey);
+         if (key == e->attrs->end())
+-            state.debugThrowLastTrace(EvalError({
++            state.debugThrowLastTrace(EvalError(ErrorInfo{
+                 .msg = hintfmt("attribute 'key' required"),
+                 .errPos = state.positions[pos]
+             }));
+@@ -724,7 +724,7 @@ static RegisterPrimOp primop_genericClos
+ });
+ 
+ 
+-static RegisterPrimOp primop_break({
++static RegisterPrimOp primop_break(RegisterPrimOp::Info{
+     .name = "break",
+     .args = {"v"},
+     .doc = R"(
+@@ -758,7 +758,7 @@ static RegisterPrimOp primop_break({
+     }
+ });
+ 
+-static RegisterPrimOp primop_abort({
++static RegisterPrimOp primop_abort(RegisterPrimOp::Info{
+     .name = "abort",
+     .args = {"s"},
+     .doc = R"(
+@@ -772,7 +772,7 @@ static RegisterPrimOp primop_abort({
+     }
+ });
+ 
+-static RegisterPrimOp primop_throw({
++static RegisterPrimOp primop_throw(RegisterPrimOp::Info{
+     .name = "throw",
+     .args = {"s"},
+     .doc = R"(
+@@ -814,7 +814,7 @@ static void prim_ceil(EvalState & state,
+     v.mkInt(ceil(value));
+ }
+ 
+-static RegisterPrimOp primop_ceil({
++static RegisterPrimOp primop_ceil(RegisterPrimOp::Info{
+     .name = "__ceil",
+     .args = {"double"},
+     .doc = R"(
+@@ -833,7 +833,7 @@ static void prim_floor(EvalState & state
+     v.mkInt(floor(value));
+ }
+ 
+-static RegisterPrimOp primop_floor({
++static RegisterPrimOp primop_floor(RegisterPrimOp::Info{
+     .name = "__floor",
+     .args = {"double"},
+     .doc = R"(
+@@ -862,7 +862,7 @@ static void prim_tryEval(EvalState & sta
+     v.mkAttrs(attrs);
+ }
+ 
+-static RegisterPrimOp primop_tryEval({
++static RegisterPrimOp primop_tryEval(RegisterPrimOp::Info{
+     .name = "__tryEval",
+     .args = {"e"},
+     .doc = R"(
+@@ -890,7 +890,7 @@ static void prim_getEnv(EvalState & stat
+     v.mkString(evalSettings.restrictEval || evalSettings.pureEval ? "" : getEnv(name).value_or(""));
+ }
+ 
+-static RegisterPrimOp primop_getEnv({
++static RegisterPrimOp primop_getEnv(RegisterPrimOp::Info{
+     .name = "__getEnv",
+     .args = {"s"},
+     .doc = R"(
+@@ -915,7 +915,7 @@ static void prim_seq(EvalState & state,
+     v = *args[1];
+ }
+ 
+-static RegisterPrimOp primop_seq({
++static RegisterPrimOp primop_seq(RegisterPrimOp::Info{
+     .name = "__seq",
+     .args = {"e1", "e2"},
+     .doc = R"(
+@@ -934,7 +934,7 @@ static void prim_deepSeq(EvalState & sta
+     v = *args[1];
+ }
+ 
+-static RegisterPrimOp primop_deepSeq({
++static RegisterPrimOp primop_deepSeq(RegisterPrimOp::Info{
+     .name = "__deepSeq",
+     .args = {"e1", "e2"},
+     .doc = R"(
+@@ -958,7 +958,7 @@ static void prim_trace(EvalState & state
+     v = *args[1];
+ }
+ 
+-static RegisterPrimOp primop_trace({
++static RegisterPrimOp primop_trace(RegisterPrimOp::Info{
+     .name = "__trace",
+     .args = {"e1", "e2"},
+     .doc = R"(
+@@ -1041,7 +1041,7 @@ static void prim_derivationStrict(EvalSt
+             if (s == "recursive") ingestionMethod = FileIngestionMethod::Recursive;
+             else if (s == "flat") ingestionMethod = FileIngestionMethod::Flat;
+             else
+-                state.debugThrowLastTrace(EvalError({
++                state.debugThrowLastTrace(EvalError(ErrorInfo{
+                     .msg = hintfmt("invalid value '%s' for 'outputHashMode' attribute", s),
+                     .errPos = state.positions[posDrvName]
+                 }));
+@@ -1051,7 +1051,7 @@ static void prim_derivationStrict(EvalSt
+             outputs.clear();
+             for (auto & j : ss) {
+                 if (outputs.find(j) != outputs.end())
+-                    state.debugThrowLastTrace(EvalError({
++                    state.debugThrowLastTrace(EvalError(ErrorInfo{
+                         .msg = hintfmt("duplicate derivation output '%1%'", j),
+                         .errPos = state.positions[posDrvName]
+                     }));
+@@ -1061,14 +1061,14 @@ static void prim_derivationStrict(EvalSt
+                    then we'd have an attribute ‘drvPath’ in
+                    the resulting set. */
+                 if (j == "drv")
+-                    state.debugThrowLastTrace(EvalError({
++                    state.debugThrowLastTrace(EvalError(ErrorInfo{
+                         .msg = hintfmt("invalid derivation output name 'drv'" ),
+                         .errPos = state.positions[posDrvName]
+                     }));
+                 outputs.insert(j);
+             }
+             if (outputs.empty())
+-                state.debugThrowLastTrace(EvalError({
++                state.debugThrowLastTrace(EvalError(ErrorInfo{
+                     .msg = hintfmt("derivation cannot have an empty set of outputs"),
+                     .errPos = state.positions[posDrvName]
+                 }));
+@@ -1196,20 +1196,20 @@ static void prim_derivationStrict(EvalSt
+ 
+     /* Do we have all required attributes? */
+     if (drv.builder == "")
+-        state.debugThrowLastTrace(EvalError({
++        state.debugThrowLastTrace(EvalError(ErrorInfo{
+             .msg = hintfmt("required attribute 'builder' missing"),
+             .errPos = state.positions[posDrvName]
+         }));
+ 
+     if (drv.platform == "")
+-        state.debugThrowLastTrace(EvalError({
++        state.debugThrowLastTrace(EvalError(ErrorInfo{
+             .msg = hintfmt("required attribute 'system' missing"),
+             .errPos = state.positions[posDrvName]
+         }));
+ 
+     /* Check whether the derivation name is valid. */
+     if (isDerivation(drvName))
+-        state.debugThrowLastTrace(EvalError({
++        state.debugThrowLastTrace(EvalError(ErrorInfo{
+             .msg = hintfmt("derivation names are not allowed to end in '%s'", drvExtension),
+             .errPos = state.positions[posDrvName]
+         }));
+@@ -1220,7 +1220,7 @@ static void prim_derivationStrict(EvalSt
+            Ignore `__contentAddressed` because fixed output derivations are
+            already content addressed. */
+         if (outputs.size() != 1 || *(outputs.begin()) != "out")
+-            state.debugThrowLastTrace(Error({
++            state.debugThrowLastTrace(Error(ErrorInfo{
+                 .msg = hintfmt("multiple outputs are not supported in fixed-output derivations"),
+                 .errPos = state.positions[posDrvName]
+             }));
+@@ -1241,7 +1241,7 @@ static void prim_derivationStrict(EvalSt
+ 
+     else if (contentAddressed || isImpure) {
+         if (contentAddressed && isImpure)
+-            throw EvalError({
++            throw EvalError(ErrorInfo{
+                 .msg = hintfmt("derivation cannot be both content-addressed and impure"),
+                 .errPos = state.positions[posDrvName]
+             });
+@@ -1285,7 +1285,7 @@ static void prim_derivationStrict(EvalSt
+             for (auto & i : outputs) {
+                 auto h = get(hashModulo.hashes, i);
+                 if (!h)
+-                    throw AssertionError({
++                    throw AssertionError(ErrorInfo{
+                         .msg = hintfmt("derivation produced no hash for output '%s'", i),
+                         .errPos = state.positions[posDrvName],
+                     });
+@@ -1345,7 +1345,7 @@ static void prim_placeholder(EvalState &
+     v.mkString(hashPlaceholder(state.forceStringNoCtx(*args[0], pos)));
+ }
+ 
+-static RegisterPrimOp primop_placeholder({
++static RegisterPrimOp primop_placeholder(RegisterPrimOp::Info{
+     .name = "placeholder",
+     .args = {"output"},
+     .doc = R"(
+@@ -1370,7 +1370,7 @@ static void prim_toPath(EvalState & stat
+     v.mkString(canonPath(path), context);
+ }
+ 
+-static RegisterPrimOp primop_toPath({
++static RegisterPrimOp primop_toPath(RegisterPrimOp::Info{
+     .name = "__toPath",
+     .args = {"s"},
+     .doc = R"(
+@@ -1391,7 +1391,7 @@ static RegisterPrimOp primop_toPath({
+ static void prim_storePath(EvalState & state, const PosIdx pos, Value * * args, Value & v)
+ {
+     if (evalSettings.pureEval)
+-        state.debugThrowLastTrace(EvalError({
++        state.debugThrowLastTrace(EvalError(ErrorInfo{
+             .msg = hintfmt("'%s' is not allowed in pure evaluation mode", "builtins.storePath"),
+             .errPos = state.positions[pos]
+         }));
+@@ -1403,7 +1403,7 @@ static void prim_storePath(EvalState & s
+        e.g. nix-push does the right thing. */
+     if (!state.store->isStorePath(path)) path = canonPath(path, true);
+     if (!state.store->isInStore(path))
+-        state.debugThrowLastTrace(EvalError({
++        state.debugThrowLastTrace(EvalError(ErrorInfo{
+             .msg = hintfmt("path '%1%' is not in the Nix store", path),
+             .errPos = state.positions[pos]
+         }));
+@@ -1414,7 +1414,7 @@ static void prim_storePath(EvalState & s
+     v.mkString(path, context);
+ }
+ 
+-static RegisterPrimOp primop_storePath({
++static RegisterPrimOp primop_storePath(RegisterPrimOp::Info{
+     .name = "__storePath",
+     .args = {"path"},
+     .doc = R"(
+@@ -1452,7 +1452,7 @@ static void prim_pathExists(EvalState &
+     }
+ }
+ 
+-static RegisterPrimOp primop_pathExists({
++static RegisterPrimOp primop_pathExists(RegisterPrimOp::Info{
+     .name = "__pathExists",
+     .args = {"path"},
+     .doc = R"(
+@@ -1470,7 +1470,7 @@ static void prim_baseNameOf(EvalState &
+     v.mkString(baseNameOf(*state.coerceToString(pos, *args[0], context, false, false)), context);
+ }
+ 
+-static RegisterPrimOp primop_baseNameOf({
++static RegisterPrimOp primop_baseNameOf(RegisterPrimOp::Info{
+     .name = "baseNameOf",
+     .args = {"s"},
+     .doc = R"(
+@@ -1492,7 +1492,7 @@ static void prim_dirOf(EvalState & state
+     if (args[0]->type() == nPath) v.mkPath(dir); else v.mkString(dir, context);
+ }
+ 
+-static RegisterPrimOp primop_dirOf({
++static RegisterPrimOp primop_dirOf(RegisterPrimOp::Info{
+     .name = "dirOf",
+     .args = {"s"},
+     .doc = R"(
+@@ -1521,7 +1521,7 @@ static void prim_readFile(EvalState & st
+     v.mkString(s, context);
+ }
+ 
+-static RegisterPrimOp primop_readFile({
++static RegisterPrimOp primop_readFile(RegisterPrimOp::Info{
+     .name = "__readFile",
+     .args = {"path"},
+     .doc = R"(
+@@ -1561,7 +1561,7 @@ static void prim_findFile(EvalState & st
+             auto rewrites = state.realiseContext(context);
+             path = rewriteStrings(path, rewrites);
+         } catch (InvalidPathError & e) {
+-            state.debugThrowLastTrace(EvalError({
++            state.debugThrowLastTrace(EvalError(ErrorInfo{
+                 .msg = hintfmt("cannot find '%1%', since path '%2%' is not valid", path, e.path),
+                 .errPos = state.positions[pos]
+             }));
+@@ -1587,7 +1587,7 @@ static void prim_hashFile(EvalState & st
+     auto type = state.forceStringNoCtx(*args[0], pos);
+     std::optional<HashType> ht = parseHashType(type);
+     if (!ht)
+-        state.debugThrowLastTrace(Error({
++        state.debugThrowLastTrace(Error(ErrorInfo{
+             .msg = hintfmt("unknown hash type '%1%'", type),
+             .errPos = state.positions[pos]
+         }));
+@@ -1597,7 +1597,7 @@ static void prim_hashFile(EvalState & st
+     v.mkString(hashFile(*ht, path).to_string(Base16, false));
+ }
+ 
+-static RegisterPrimOp primop_hashFile({
++static RegisterPrimOp primop_hashFile(RegisterPrimOp::Info{
+     .name = "__hashFile",
+     .args = {"type", "p"},
+     .doc = R"(
+@@ -1630,7 +1630,7 @@ static void prim_readDir(EvalState & sta
+     v.mkAttrs(attrs);
+ }
+ 
+-static RegisterPrimOp primop_readDir({
++static RegisterPrimOp primop_readDir(RegisterPrimOp::Info{
+     .name = "__readDir",
+     .args = {"path"},
+     .doc = R"(
+@@ -1666,7 +1666,7 @@ static void prim_toXML(EvalState & state
+     v.mkString(out.str(), context);
+ }
+ 
+-static RegisterPrimOp primop_toXML({
++static RegisterPrimOp primop_toXML(RegisterPrimOp::Info{
+     .name = "__toXML",
+     .args = {"e"},
+     .doc = R"(
+@@ -1774,7 +1774,7 @@ static void prim_toJSON(EvalState & stat
+     v.mkString(out.str(), context);
+ }
+ 
+-static RegisterPrimOp primop_toJSON({
++static RegisterPrimOp primop_toJSON(RegisterPrimOp::Info{
+     .name = "__toJSON",
+     .args = {"e"},
+     .doc = R"(
+@@ -1800,7 +1800,7 @@ static void prim_fromJSON(EvalState & st
+     }
+ }
+ 
+-static RegisterPrimOp primop_fromJSON({
++static RegisterPrimOp primop_fromJSON(RegisterPrimOp::Info{
+     .name = "__fromJSON",
+     .args = {"e"},
+     .doc = R"(
+@@ -1827,7 +1827,7 @@ static void prim_toFile(EvalState & stat
+ 
+     for (auto path : context) {
+         if (path.at(0) != '/')
+-            state.debugThrowLastTrace(EvalError({
++            state.debugThrowLastTrace(EvalError(ErrorInfo{
+                 .msg = hintfmt(
+                     "in 'toFile': the file named '%1%' must not contain a reference "
+                     "to a derivation but contains (%2%)",
+@@ -1849,7 +1849,7 @@ static void prim_toFile(EvalState & stat
+     state.allowAndSetStorePathString(storePath, v);
+ }
+ 
+-static RegisterPrimOp primop_toFile({
++static RegisterPrimOp primop_toFile(RegisterPrimOp::Info{
+     .name = "__toFile",
+     .args = {"name", "s"},
+     .doc = R"(
+@@ -2009,7 +2009,7 @@ static void prim_filterSource(EvalState
+ 
+     state.forceValue(*args[0], pos);
+     if (args[0]->type() != nFunction)
+-        state.debugThrowLastTrace(TypeError({
++        state.debugThrowLastTrace(TypeError(ErrorInfo{
+             .msg = hintfmt(
+                 "first argument in call to 'filterSource' is not a function but %1%",
+                 showType(*args[0])),
+@@ -2019,7 +2019,7 @@ static void prim_filterSource(EvalState
+     addPath(state, pos, std::string(baseNameOf(path)), path, args[0], FileIngestionMethod::Recursive, std::nullopt, v, context);
+ }
+ 
+-static RegisterPrimOp primop_filterSource({
++static RegisterPrimOp primop_filterSource(RegisterPrimOp::Info{
+     .name = "__filterSource",
+     .args = {"e1", "e2"},
+     .doc = R"(
+@@ -2098,13 +2098,13 @@ static void prim_path(EvalState & state,
+         else if (n == "sha256")
+             expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, attr.pos), htSHA256);
+         else
+-            state.debugThrowLastTrace(EvalError({
++            state.debugThrowLastTrace(EvalError(ErrorInfo{
+                 .msg = hintfmt("unsupported argument '%1%' to 'addPath'", state.symbols[attr.name]),
+                 .errPos = state.positions[attr.pos]
+             }));
+     }
+     if (path.empty())
+-        state.debugThrowLastTrace(EvalError({
++        state.debugThrowLastTrace(EvalError(ErrorInfo{
+             .msg = hintfmt("'path' required"),
+             .errPos = state.positions[pos]
+         }));
+@@ -2114,7 +2114,7 @@ static void prim_path(EvalState & state,
+     addPath(state, pos, name, path, filterFun, method, expectedHash, v, context);
+ }
+ 
+-static RegisterPrimOp primop_path({
++static RegisterPrimOp primop_path(RegisterPrimOp::Info{
+     .name = "__path",
+     .args = {"args"},
+     .doc = R"(
+@@ -2171,7 +2171,7 @@ static void prim_attrNames(EvalState & s
+               [](Value * v1, Value * v2) { return strcmp(v1->string.s, v2->string.s) < 0; });
+ }
+ 
+-static RegisterPrimOp primop_attrNames({
++static RegisterPrimOp primop_attrNames(RegisterPrimOp::Info{
+     .name = "__attrNames",
+     .args = {"set"},
+     .doc = R"(
+@@ -2205,7 +2205,7 @@ static void prim_attrValues(EvalState &
+         v.listElems()[i] = ((Attr *) v.listElems()[i])->value;
+ }
+ 
+-static RegisterPrimOp primop_attrValues({
++static RegisterPrimOp primop_attrValues(RegisterPrimOp::Info{
+     .name = "__attrValues",
+     .args = {"set"},
+     .doc = R"(
+@@ -2233,7 +2233,7 @@ void prim_getAttr(EvalState & state, con
+     v = *i->value;
+ }
+ 
+-static RegisterPrimOp primop_getAttr({
++static RegisterPrimOp primop_getAttr(RegisterPrimOp::Info{
+     .name = "__getAttr",
+     .args = {"s", "set"},
+     .doc = R"(
+@@ -2271,7 +2271,7 @@ static void prim_hasAttr(EvalState & sta
+     v.mkBool(args[1]->attrs->find(state.symbols.create(attr)) != args[1]->attrs->end());
+ }
+ 
+-static RegisterPrimOp primop_hasAttr({
++static RegisterPrimOp primop_hasAttr(RegisterPrimOp::Info{
+     .name = "__hasAttr",
+     .args = {"s", "set"},
+     .doc = R"(
+@@ -2289,7 +2289,7 @@ static void prim_isAttrs(EvalState & sta
+     v.mkBool(args[0]->type() == nAttrs);
+ }
+ 
+-static RegisterPrimOp primop_isAttrs({
++static RegisterPrimOp primop_isAttrs(RegisterPrimOp::Info{
+     .name = "__isAttrs",
+     .args = {"e"},
+     .doc = R"(
+@@ -2325,7 +2325,7 @@ static void prim_removeAttrs(EvalState &
+     v.mkAttrs(attrs.alreadySorted());
+ }
+ 
+-static RegisterPrimOp primop_removeAttrs({
++static RegisterPrimOp primop_removeAttrs(RegisterPrimOp::Info{
+     .name = "removeAttrs",
+     .args = {"set", "list"},
+     .doc = R"(
+@@ -2383,7 +2383,7 @@ static void prim_listToAttrs(EvalState &
+     v.mkAttrs(attrs);
+ }
+ 
+-static RegisterPrimOp primop_listToAttrs({
++static RegisterPrimOp primop_listToAttrs(RegisterPrimOp::Info{
+     .name = "__listToAttrs",
+     .args = {"e"},
+     .doc = R"(
+@@ -2424,7 +2424,7 @@ static void prim_intersectAttrs(EvalStat
+     v.mkAttrs(attrs.alreadySorted());
+ }
+ 
+-static RegisterPrimOp primop_intersectAttrs({
++static RegisterPrimOp primop_intersectAttrs(RegisterPrimOp::Info{
+     .name = "__intersectAttrs",
+     .args = {"e1", "e2"},
+     .doc = R"(
+@@ -2454,7 +2454,7 @@ static void prim_catAttrs(EvalState & st
+         v.listElems()[n] = res[n];
+ }
+ 
+-static RegisterPrimOp primop_catAttrs({
++static RegisterPrimOp primop_catAttrs(RegisterPrimOp::Info{
+     .name = "__catAttrs",
+     .args = {"attr", "list"},
+     .doc = R"(
+@@ -2479,7 +2479,7 @@ static void prim_functionArgs(EvalState
+         return;
+     }
+     if (!args[0]->isLambda())
+-        state.debugThrowLastTrace(TypeError({
++        state.debugThrowLastTrace(TypeError(ErrorInfo{
+             .msg = hintfmt("'functionArgs' requires a function"),
+             .errPos = state.positions[pos]
+         }));
+@@ -2496,7 +2496,7 @@ static void prim_functionArgs(EvalState
+     v.mkAttrs(attrs);
+ }
+ 
+-static RegisterPrimOp primop_functionArgs({
++static RegisterPrimOp primop_functionArgs(RegisterPrimOp::Info{
+     .name = "__functionArgs",
+     .args = {"f"},
+     .doc = R"(
+@@ -2531,7 +2531,7 @@ static void prim_mapAttrs(EvalState & st
+     v.mkAttrs(attrs.alreadySorted());
+ }
+ 
+-static RegisterPrimOp primop_mapAttrs({
++static RegisterPrimOp primop_mapAttrs(RegisterPrimOp::Info{
+     .name = "__mapAttrs",
+     .args = {"f", "attrset"},
+     .doc = R"(
+@@ -2599,7 +2599,7 @@ static void prim_zipAttrsWith(EvalState
+     }
+ }
+ 
+-static RegisterPrimOp primop_zipAttrsWith({
++static RegisterPrimOp primop_zipAttrsWith(RegisterPrimOp::Info{
+     .name = "__zipAttrsWith",
+     .args = {"f", "list"},
+     .doc = R"(
+@@ -2644,7 +2644,7 @@ static void prim_isList(EvalState & stat
+     v.mkBool(args[0]->type() == nList);
+ }
+ 
+-static RegisterPrimOp primop_isList({
++static RegisterPrimOp primop_isList(RegisterPrimOp::Info{
+     .name = "__isList",
+     .args = {"e"},
+     .doc = R"(
+@@ -2657,7 +2657,7 @@ static void elemAt(EvalState & state, co
+ {
+     state.forceList(list, pos);
+     if (n < 0 || (unsigned int) n >= list.listSize())
+-        state.debugThrowLastTrace(Error({
++        state.debugThrowLastTrace(Error(ErrorInfo{
+             .msg = hintfmt("list index %1% is out of bounds", n),
+             .errPos = state.positions[pos]
+         }));
+@@ -2671,7 +2671,7 @@ static void prim_elemAt(EvalState & stat
+     elemAt(state, pos, *args[0], state.forceInt(*args[1], pos), v);
+ }
+ 
+-static RegisterPrimOp primop_elemAt({
++static RegisterPrimOp primop_elemAt(RegisterPrimOp::Info{
+     .name = "__elemAt",
+     .args = {"xs", "n"},
+     .doc = R"(
+@@ -2687,7 +2687,7 @@ static void prim_head(EvalState & state,
+     elemAt(state, pos, *args[0], 0, v);
+ }
+ 
+-static RegisterPrimOp primop_head({
++static RegisterPrimOp primop_head(RegisterPrimOp::Info{
+     .name = "__head",
+     .args = {"list"},
+     .doc = R"(
+@@ -2705,7 +2705,7 @@ static void prim_tail(EvalState & state,
+ {
+     state.forceList(*args[0], pos);
+     if (args[0]->listSize() == 0)
+-        state.debugThrowLastTrace(Error({
++        state.debugThrowLastTrace(Error(ErrorInfo{
+             .msg = hintfmt("'tail' called on an empty list"),
+             .errPos = state.positions[pos]
+         }));
+@@ -2715,7 +2715,7 @@ static void prim_tail(EvalState & state,
+         v.listElems()[n] = args[0]->listElems()[n + 1];
+ }
+ 
+-static RegisterPrimOp primop_tail({
++static RegisterPrimOp primop_tail(RegisterPrimOp::Info{
+     .name = "__tail",
+     .args = {"list"},
+     .doc = R"(
+@@ -2743,7 +2743,7 @@ static void prim_map(EvalState & state,
+             args[0], args[1]->listElems()[n]);
+ }
+ 
+-static RegisterPrimOp primop_map({
++static RegisterPrimOp primop_map(RegisterPrimOp::Info{
+     .name = "map",
+     .args = {"f", "list"},
+     .doc = R"(
+@@ -2789,7 +2789,7 @@ static void prim_filter(EvalState & stat
+     }
+ }
+ 
+-static RegisterPrimOp primop_filter({
++static RegisterPrimOp primop_filter(RegisterPrimOp::Info{
+     .name = "__filter",
+     .args = {"f", "list"},
+     .doc = R"(
+@@ -2812,7 +2812,7 @@ static void prim_elem(EvalState & state,
+     v.mkBool(res);
+ }
+ 
+-static RegisterPrimOp primop_elem({
++static RegisterPrimOp primop_elem(RegisterPrimOp::Info{
+     .name = "__elem",
+     .args = {"x", "xs"},
+     .doc = R"(
+@@ -2829,7 +2829,7 @@ static void prim_concatLists(EvalState &
+     state.concatLists(v, args[0]->listSize(), args[0]->listElems(), pos);
+ }
+ 
+-static RegisterPrimOp primop_concatLists({
++static RegisterPrimOp primop_concatLists(RegisterPrimOp::Info{
+     .name = "__concatLists",
+     .args = {"lists"},
+     .doc = R"(
+@@ -2845,7 +2845,7 @@ static void prim_length(EvalState & stat
+     v.mkInt(args[0]->listSize());
+ }
+ 
+-static RegisterPrimOp primop_length({
++static RegisterPrimOp primop_length(RegisterPrimOp::Info{
+     .name = "__length",
+     .args = {"e"},
+     .doc = R"(
+@@ -2876,7 +2876,7 @@ static void prim_foldlStrict(EvalState &
+     }
+ }
+ 
+-static RegisterPrimOp primop_foldlStrict({
++static RegisterPrimOp primop_foldlStrict(RegisterPrimOp::Info{
+     .name = "__foldl'",
+     .args = {"op", "nul", "list"},
+     .doc = R"(
+@@ -2913,7 +2913,7 @@ static void prim_any(EvalState & state,
+     anyOrAll(true, state, pos, args, v);
+ }
+ 
+-static RegisterPrimOp primop_any({
++static RegisterPrimOp primop_any(RegisterPrimOp::Info{
+     .name = "__any",
+     .args = {"pred", "list"},
+     .doc = R"(
+@@ -2928,7 +2928,7 @@ static void prim_all(EvalState & state,
+     anyOrAll(false, state, pos, args, v);
+ }
+ 
+-static RegisterPrimOp primop_all({
++static RegisterPrimOp primop_all(RegisterPrimOp::Info{
+     .name = "__all",
+     .args = {"pred", "list"},
+     .doc = R"(
+@@ -2943,7 +2943,7 @@ static void prim_genList(EvalState & sta
+     auto len = state.forceInt(*args[1], pos);
+ 
+     if (len < 0)
+-        state.debugThrowLastTrace(EvalError({
++        state.debugThrowLastTrace(EvalError(ErrorInfo{
+             .msg = hintfmt("cannot create list of size %1%", len),
+             .errPos = state.positions[pos]
+         }));
+@@ -2957,7 +2957,7 @@ static void prim_genList(EvalState & sta
+     }
+ }
+ 
+-static RegisterPrimOp primop_genList({
++static RegisterPrimOp primop_genList(RegisterPrimOp::Info{
+     .name = "__genList",
+     .args = {"generator", "length"},
+     .doc = R"(
+@@ -3006,7 +3006,7 @@ static void prim_sort(EvalState & state,
+     std::stable_sort(v.listElems(), v.listElems() + len, comparator);
+ }
+ 
+-static RegisterPrimOp primop_sort({
++static RegisterPrimOp primop_sort(RegisterPrimOp::Info{
+     .name = "__sort",
+     .args = {"comparator", "list"},
+     .doc = R"(
+@@ -3064,7 +3064,7 @@ static void prim_partition(EvalState & s
+     v.mkAttrs(attrs);
+ }
+ 
+-static RegisterPrimOp primop_partition({
++static RegisterPrimOp primop_partition(RegisterPrimOp::Info{
+     .name = "__partition",
+     .args = {"pred", "list"},
+     .doc = R"(
+@@ -3115,7 +3115,7 @@ static void prim_groupBy(EvalState & sta
+     v.mkAttrs(attrs2.alreadySorted());
+ }
+ 
+-static RegisterPrimOp primop_groupBy({
++static RegisterPrimOp primop_groupBy(RegisterPrimOp::Info{
+     .name = "__groupBy",
+     .args = {"f", "list"},
+     .doc = R"(
+@@ -3170,7 +3170,7 @@ static void prim_concatMap(EvalState & s
+     }
+ }
+ 
+-static RegisterPrimOp primop_concatMap({
++static RegisterPrimOp primop_concatMap(RegisterPrimOp::Info{
+     .name = "__concatMap",
+     .args = {"f", "list"},
+     .doc = R"(
+@@ -3196,7 +3196,7 @@ static void prim_add(EvalState & state,
+         v.mkInt(state.forceInt(*args[0], pos) + state.forceInt(*args[1], pos));
+ }
+ 
+-static RegisterPrimOp primop_add({
++static RegisterPrimOp primop_add(RegisterPrimOp::Info{
+     .name = "__add",
+     .args = {"e1", "e2"},
+     .doc = R"(
+@@ -3215,7 +3215,7 @@ static void prim_sub(EvalState & state,
+         v.mkInt(state.forceInt(*args[0], pos) - state.forceInt(*args[1], pos));
+ }
+ 
+-static RegisterPrimOp primop_sub({
++static RegisterPrimOp primop_sub(RegisterPrimOp::Info{
+     .name = "__sub",
+     .args = {"e1", "e2"},
+     .doc = R"(
+@@ -3234,7 +3234,7 @@ static void prim_mul(EvalState & state,
+         v.mkInt(state.forceInt(*args[0], pos) * state.forceInt(*args[1], pos));
+ }
+ 
+-static RegisterPrimOp primop_mul({
++static RegisterPrimOp primop_mul(RegisterPrimOp::Info{
+     .name = "__mul",
+     .args = {"e1", "e2"},
+     .doc = R"(
+@@ -3250,7 +3250,7 @@ static void prim_div(EvalState & state,
+ 
+     NixFloat f2 = state.forceFloat(*args[1], pos);
+     if (f2 == 0)
+-        state.debugThrowLastTrace(EvalError({
++        state.debugThrowLastTrace(EvalError(ErrorInfo{
+             .msg = hintfmt("division by zero"),
+             .errPos = state.positions[pos]
+         }));
+@@ -3262,7 +3262,7 @@ static void prim_div(EvalState & state,
+         NixInt i2 = state.forceInt(*args[1], pos);
+         /* Avoid division overflow as it might raise SIGFPE. */
+         if (i1 == std::numeric_limits<NixInt>::min() && i2 == -1)
+-            state.debugThrowLastTrace(EvalError({
++            state.debugThrowLastTrace(EvalError(ErrorInfo{
+                 .msg = hintfmt("overflow in integer division"),
+                 .errPos = state.positions[pos]
+             }));
+@@ -3271,7 +3271,7 @@ static void prim_div(EvalState & state,
+     }
+ }
+ 
+-static RegisterPrimOp primop_div({
++static RegisterPrimOp primop_div(RegisterPrimOp::Info{
+     .name = "__div",
+     .args = {"e1", "e2"},
+     .doc = R"(
+@@ -3285,7 +3285,7 @@ static void prim_bitAnd(EvalState & stat
+     v.mkInt(state.forceInt(*args[0], pos) & state.forceInt(*args[1], pos));
+ }
+ 
+-static RegisterPrimOp primop_bitAnd({
++static RegisterPrimOp primop_bitAnd(RegisterPrimOp::Info{
+     .name = "__bitAnd",
+     .args = {"e1", "e2"},
+     .doc = R"(
+@@ -3299,7 +3299,7 @@ static void prim_bitOr(EvalState & state
+     v.mkInt(state.forceInt(*args[0], pos) | state.forceInt(*args[1], pos));
+ }
+ 
+-static RegisterPrimOp primop_bitOr({
++static RegisterPrimOp primop_bitOr(RegisterPrimOp::Info{
+     .name = "__bitOr",
+     .args = {"e1", "e2"},
+     .doc = R"(
+@@ -3313,7 +3313,7 @@ static void prim_bitXor(EvalState & stat
+     v.mkInt(state.forceInt(*args[0], pos) ^ state.forceInt(*args[1], pos));
+ }
+ 
+-static RegisterPrimOp primop_bitXor({
++static RegisterPrimOp primop_bitXor(RegisterPrimOp::Info{
+     .name = "__bitXor",
+     .args = {"e1", "e2"},
+     .doc = R"(
+@@ -3330,7 +3330,7 @@ static void prim_lessThan(EvalState & st
+     v.mkBool(comp(args[0], args[1]));
+ }
+ 
+-static RegisterPrimOp primop_lessThan({
++static RegisterPrimOp primop_lessThan(RegisterPrimOp::Info{
+     .name = "__lessThan",
+     .args = {"e1", "e2"},
+     .doc = R"(
+@@ -3357,7 +3357,7 @@ static void prim_toString(EvalState & st
+     v.mkString(*s, context);
+ }
+ 
+-static RegisterPrimOp primop_toString({
++static RegisterPrimOp primop_toString(RegisterPrimOp::Info{
+     .name = "toString",
+     .args = {"e"},
+     .doc = R"(
+@@ -3393,7 +3393,7 @@ static void prim_substring(EvalState & s
+     auto s = state.coerceToString(pos, *args[2], context);
+ 
+     if (start < 0)
+-        state.debugThrowLastTrace(EvalError({
++        state.debugThrowLastTrace(EvalError(ErrorInfo{
+             .msg = hintfmt("negative start position in 'substring'"),
+             .errPos = state.positions[pos]
+         }));
+@@ -3401,7 +3401,7 @@ static void prim_substring(EvalState & s
+     v.mkString((unsigned int) start >= s->size() ? "" : s->substr(start, len), context);
+ }
+ 
+-static RegisterPrimOp primop_substring({
++static RegisterPrimOp primop_substring(RegisterPrimOp::Info{
+     .name = "__substring",
+     .args = {"start", "len", "s"},
+     .doc = R"(
+@@ -3428,7 +3428,7 @@ static void prim_stringLength(EvalState
+     v.mkInt(s->size());
+ }
+ 
+-static RegisterPrimOp primop_stringLength({
++static RegisterPrimOp primop_stringLength(RegisterPrimOp::Info{
+     .name = "__stringLength",
+     .args = {"e"},
+     .doc = R"(
+@@ -3444,7 +3444,7 @@ static void prim_hashString(EvalState &
+     auto type = state.forceStringNoCtx(*args[0], pos);
+     std::optional<HashType> ht = parseHashType(type);
+     if (!ht)
+-        state.debugThrowLastTrace(Error({
++        state.debugThrowLastTrace(Error(ErrorInfo{
+             .msg = hintfmt("unknown hash type '%1%'", type),
+             .errPos = state.positions[pos]
+         }));
+@@ -3455,7 +3455,7 @@ static void prim_hashString(EvalState &
+     v.mkString(hashString(*ht, s).to_string(Base16, false));
+ }
+ 
+-static RegisterPrimOp primop_hashString({
++static RegisterPrimOp primop_hashString(RegisterPrimOp::Info{
+     .name = "__hashString",
+     .args = {"type", "s"},
+     .doc = R"(
+@@ -3517,19 +3517,19 @@ void prim_match(EvalState & state, const
+     } catch (std::regex_error & e) {
+         if (e.code() == std::regex_constants::error_space) {
+             // limit is _GLIBCXX_REGEX_STATE_LIMIT for libstdc++
+-            state.debugThrowLastTrace(EvalError({
++            state.debugThrowLastTrace(EvalError(ErrorInfo{
+                 .msg = hintfmt("memory limit exceeded by regular expression '%s'", re),
+                 .errPos = state.positions[pos]
+             }));
+         } else
+-            state.debugThrowLastTrace(EvalError({
++            state.debugThrowLastTrace(EvalError(ErrorInfo{
+                 .msg = hintfmt("invalid regular expression '%s'", re),
+                 .errPos = state.positions[pos]
+             }));
+     }
+ }
+ 
+-static RegisterPrimOp primop_match({
++static RegisterPrimOp primop_match(RegisterPrimOp::Info{
+     .name = "__match",
+     .args = {"regex", "str"},
+     .doc = R"s(
+@@ -3621,19 +3621,19 @@ void prim_split(EvalState & state, const
+     } catch (std::regex_error & e) {
+         if (e.code() == std::regex_constants::error_space) {
+             // limit is _GLIBCXX_REGEX_STATE_LIMIT for libstdc++
+-            state.debugThrowLastTrace(EvalError({
++            state.debugThrowLastTrace(EvalError(ErrorInfo{
+                 .msg = hintfmt("memory limit exceeded by regular expression '%s'", re),
+                 .errPos = state.positions[pos]
+             }));
+         } else
+-            state.debugThrowLastTrace(EvalError({
++            state.debugThrowLastTrace(EvalError(ErrorInfo{
+                 .msg = hintfmt("invalid regular expression '%s'", re),
+                 .errPos = state.positions[pos]
+             }));
+     }
+ }
+ 
+-static RegisterPrimOp primop_split({
++static RegisterPrimOp primop_split(RegisterPrimOp::Info{
+     .name = "__split",
+     .args = {"regex", "str"},
+     .doc = R"s(
+@@ -3689,7 +3689,7 @@ static void prim_concatStringsSep(EvalSt
+     v.mkString(res, context);
+ }
+ 
+-static RegisterPrimOp primop_concatStringsSep({
++static RegisterPrimOp primop_concatStringsSep(RegisterPrimOp::Info{
+     .name = "__concatStringsSep",
+     .args = {"separator", "list"},
+     .doc = R"(
+@@ -3705,7 +3705,7 @@ static void prim_replaceStrings(EvalStat
+     state.forceList(*args[0], pos);
+     state.forceList(*args[1], pos);
+     if (args[0]->listSize() != args[1]->listSize())
+-        state.debugThrowLastTrace(EvalError({
++        state.debugThrowLastTrace(EvalError(ErrorInfo{
+             .msg = hintfmt("'from' and 'to' arguments to 'replaceStrings' have different lengths"),
+             .errPos = state.positions[pos]
+         }));
+@@ -3758,7 +3758,7 @@ static void prim_replaceStrings(EvalStat
+     v.mkString(res, context);
+ }
+ 
+-static RegisterPrimOp primop_replaceStrings({
++static RegisterPrimOp primop_replaceStrings(RegisterPrimOp::Info{
+     .name = "__replaceStrings",
+     .args = {"from", "to", "s"},
+     .doc = R"(
+@@ -3790,7 +3790,7 @@ static void prim_parseDrvName(EvalState
+     v.mkAttrs(attrs);
+ }
+ 
+-static RegisterPrimOp primop_parseDrvName({
++static RegisterPrimOp primop_parseDrvName(RegisterPrimOp::Info{
+     .name = "__parseDrvName",
+     .args = {"s"},
+     .doc = R"(
+@@ -3811,7 +3811,7 @@ static void prim_compareVersions(EvalSta
+     v.mkInt(compareVersions(version1, version2));
+ }
+ 
+-static RegisterPrimOp primop_compareVersions({
++static RegisterPrimOp primop_compareVersions(RegisterPrimOp::Info{
+     .name = "__compareVersions",
+     .args = {"s1", "s2"},
+     .doc = R"(
+@@ -3840,7 +3840,7 @@ static void prim_splitVersion(EvalState
+         (v.listElems()[n] = state.allocValue())->mkString(std::move(component));
+ }
+ 
+-static RegisterPrimOp primop_splitVersion({
++static RegisterPrimOp primop_splitVersion(RegisterPrimOp::Info{
+     .name = "__splitVersion",
+     .args = {"s"},
+     .doc = R"(
+@@ -3863,7 +3863,7 @@ RegisterPrimOp::PrimOps * RegisterPrimOp
+ RegisterPrimOp::RegisterPrimOp(std::string name, size_t arity, PrimOpFun fun)
+ {
+     if (!primOps) primOps = new PrimOps;
+-    primOps->push_back({
++    primOps->push_back(RegisterPrimOp::Info{
+         .name = name,
+         .args = {},
+         .arity = arity,
+--- nix-2.9.2/src/libexpr/primops/context.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libexpr/primops/context.cc	2022-07-05 21:30:43.895477218 +0200
+@@ -146,7 +146,7 @@ static void prim_appendContext(EvalState
+     for (auto & i : *args[1]->attrs) {
+         const auto & name = state.symbols[i.name];
+         if (!state.store->isStorePath(name))
+-            throw EvalError({
++            throw EvalError(ErrorInfo{
+                 .msg = hintfmt("Context key '%s' is not a store path", name),
+                 .errPos = state.positions[i.pos]
+             });
+@@ -163,7 +163,7 @@ static void prim_appendContext(EvalState
+         if (iter != i.value->attrs->end()) {
+             if (state.forceBool(*iter->value, iter->pos)) {
+                 if (!isDerivation(name)) {
+-                    throw EvalError({
++                    throw EvalError(ErrorInfo{
+                         .msg = hintfmt("Tried to add all-outputs context of %s, which is not a derivation, to a string", name),
+                         .errPos = state.positions[i.pos]
+                     });
+@@ -176,7 +176,7 @@ static void prim_appendContext(EvalState
+         if (iter != i.value->attrs->end()) {
+             state.forceList(*iter->value, iter->pos);
+             if (iter->value->listSize() && !isDerivation(name)) {
+-                throw EvalError({
++                throw EvalError(ErrorInfo{
+                     .msg = hintfmt("Tried to add derivation output context of %s, which is not a derivation, to a string", name),
+                     .errPos = state.positions[i.pos]
+                 });
+--- nix-2.9.2/src/libexpr/primops/fetchClosure.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libexpr/primops/fetchClosure.cc	2022-07-05 21:19:32.442745247 +0200
+@@ -35,20 +35,20 @@ static void prim_fetchClosure(EvalState
+             fromStoreUrl = state.forceStringNoCtx(*attr.value, attr.pos);
+ 
+         else
+-            throw Error({
++            throw Error(ErrorInfo{
+                 .msg = hintfmt("attribute '%s' isn't supported in call to 'fetchClosure'", attrName),
+                 .errPos = state.positions[pos]
+             });
+     }
+ 
+     if (!fromPath)
+-        throw Error({
++        throw Error(ErrorInfo{
+             .msg = hintfmt("attribute '%s' is missing in call to 'fetchClosure'", "fromPath"),
+             .errPos = state.positions[pos]
+         });
+ 
+     if (!fromStoreUrl)
+-        throw Error({
++        throw Error(ErrorInfo{
+             .msg = hintfmt("attribute '%s' is missing in call to 'fetchClosure'", "fromStore"),
+             .errPos = state.positions[pos]
+         });
+@@ -58,13 +58,13 @@ static void prim_fetchClosure(EvalState
+     if (parsedURL.scheme != "http" &&
+         parsedURL.scheme != "https" &&
+         !(getEnv("_NIX_IN_TEST").has_value() && parsedURL.scheme == "file"))
+-        throw Error({
++        throw Error(ErrorInfo{
+             .msg = hintfmt("'fetchClosure' only supports http:// and https:// stores"),
+             .errPos = state.positions[pos]
+         });
+ 
+     if (!parsedURL.query.empty())
+-        throw Error({
++        throw Error(ErrorInfo{
+             .msg = hintfmt("'fetchClosure' does not support URL query parameters (in '%s')", *fromStoreUrl),
+             .errPos = state.positions[pos]
+         });
+@@ -77,7 +77,7 @@ static void prim_fetchClosure(EvalState
+             auto i = remappings.find(*fromPath);
+             assert(i != remappings.end());
+             if (toPath && *toPath != i->second)
+-                throw Error({
++                throw Error(ErrorInfo{
+                     .msg = hintfmt("rewriting '%s' to content-addressed form yielded '%s', while '%s' was expected",
+                         state.store->printStorePath(*fromPath),
+                         state.store->printStorePath(i->second),
+@@ -85,7 +85,7 @@ static void prim_fetchClosure(EvalState
+                     .errPos = state.positions[pos]
+                 });
+             if (!toPath)
+-                throw Error({
++                throw Error(ErrorInfo{
+                     .msg = hintfmt(
+                         "rewriting '%s' to content-addressed form yielded '%s'; "
+                         "please set this in the 'toPath' attribute passed to 'fetchClosure'",
+@@ -104,7 +104,7 @@ static void prim_fetchClosure(EvalState
+     if (evalSettings.pureEval) {
+         auto info = state.store->queryPathInfo(*toPath);
+         if (!info->isContentAddressed(*state.store))
+-            throw Error({
++            throw Error(ErrorInfo{
+                 .msg = hintfmt("in pure mode, 'fetchClosure' requires a content-addressed path, which '%s' isn't",
+                     state.store->printStorePath(*toPath)),
+                 .errPos = state.positions[pos]
+@@ -115,7 +115,7 @@ static void prim_fetchClosure(EvalState
+     v.mkString(toPathS, {toPathS});
+ }
+ 
+-static RegisterPrimOp primop_fetchClosure({
++static RegisterPrimOp primop_fetchClosure(RegisterPrimOp::Info{
+     .name = "__fetchClosure",
+     .args = {"args"},
+     .doc = R"(
+--- nix-2.9.2/src/libexpr/primops/fetchMercurial.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libexpr/primops/fetchMercurial.cc	2022-07-05 21:24:42.447732473 +0200
+@@ -37,14 +37,14 @@ static void prim_fetchMercurial(EvalStat
+             else if (n == "name")
+                 name = state.forceStringNoCtx(*attr.value, attr.pos);
+             else
+-                throw EvalError({
++                throw EvalError(ErrorInfo{
+                     .msg = hintfmt("unsupported argument '%s' to 'fetchMercurial'", state.symbols[attr.name]),
+                     .errPos = state.positions[attr.pos]
+                 });
+         }
+ 
+         if (url.empty())
+-            throw EvalError({
++            throw EvalError(ErrorInfo{
+                 .msg = hintfmt("'url' argument required"),
+                 .errPos = state.positions[pos]
+             });
+--- nix-2.9.2/src/libexpr/primops/fetchTree.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libexpr/primops/fetchTree.cc	2022-07-05 21:26:10.917253192 +0200
+@@ -108,13 +108,13 @@ static void fetchTree(
+ 
+         if (auto aType = args[0]->attrs->get(state.sType)) {
+             if (type)
+-                state.debugThrowLastTrace(EvalError({
++                state.debugThrowLastTrace(EvalError(ErrorInfo{
+                     .msg = hintfmt("unexpected attribute 'type'"),
+                     .errPos = state.positions[pos]
+                 }));
+             type = state.forceStringNoCtx(*aType->value, aType->pos);
+         } else if (!type)
+-            state.debugThrowLastTrace(EvalError({
++            state.debugThrowLastTrace(EvalError(ErrorInfo{
+                 .msg = hintfmt("attribute 'type' is missing in call to 'fetchTree'"),
+                 .errPos = state.positions[pos]
+             }));
+@@ -144,7 +144,7 @@ static void fetchTree(
+ 
+         if (!params.allowNameArgument)
+             if (auto nameIter = attrs.find("name"); nameIter != attrs.end())
+-                state.debugThrowLastTrace(EvalError({
++                state.debugThrowLastTrace(EvalError(ErrorInfo{
+                     .msg = hintfmt("attribute 'name' isn’t supported in call to 'fetchTree'"),
+                     .errPos = state.positions[pos]
+                 }));
+@@ -206,14 +206,14 @@ static void fetch(EvalState & state, con
+             else if (n == "name")
+                 name = state.forceStringNoCtx(*attr.value, attr.pos);
+             else
+-                state.debugThrowLastTrace(EvalError({
++                state.debugThrowLastTrace(EvalError(ErrorInfo{
+                     .msg = hintfmt("unsupported argument '%s' to '%s'", n, who),
+                     .errPos = state.positions[attr.pos]
+                 }));
+         }
+ 
+         if (!url)
+-            state.debugThrowLastTrace(EvalError({
++            state.debugThrowLastTrace(EvalError(ErrorInfo{
+                 .msg = hintfmt("'url' argument required"),
+                 .errPos = state.positions[pos]
+             }));
+@@ -267,7 +267,7 @@ static void prim_fetchurl(EvalState & st
+     fetch(state, pos, args, v, "fetchurl", false, "");
+ }
+ 
+-static RegisterPrimOp primop_fetchurl({
++static RegisterPrimOp primop_fetchurl(RegisterPrimOp::Info{
+     .name = "__fetchurl",
+     .args = {"url"},
+     .doc = R"(
+@@ -283,7 +283,7 @@ static void prim_fetchTarball(EvalState
+     fetch(state, pos, args, v, "fetchTarball", true, "source");
+ }
+ 
+-static RegisterPrimOp primop_fetchTarball({
++static RegisterPrimOp primop_fetchTarball(RegisterPrimOp::Info{
+     .name = "fetchTarball",
+     .args = {"args"},
+     .doc = R"(
+@@ -334,7 +334,7 @@ static void prim_fetchGit(EvalState & st
+     fetchTree(state, pos, args, v, "git", FetchTreeParams { .emptyRevFallback = true, .allowNameArgument = true });
+ }
+ 
+-static RegisterPrimOp primop_fetchGit({
++static RegisterPrimOp primop_fetchGit(RegisterPrimOp::Info{
+     .name = "fetchGit",
+     .args = {"args"},
+     .doc = R"(
+--- nix-2.9.2/src/libexpr/primops/fromTOML.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libexpr/primops/fromTOML.cc	2022-07-05 21:37:21.520286890 +0200
+@@ -71,7 +71,7 @@ static void prim_fromTOML(EvalState & st
+     try {
+         visit(val, toml::parse(tomlStream, "fromTOML" /* the "filename" */));
+     } catch (std::exception & e) { // TODO: toml::syntax_error
+-        throw EvalError({
++        throw EvalError(ErrorInfo{
+             .msg = hintfmt("while parsing a TOML string: %s", e.what()),
+             .errPos = state.positions[pos]
+         });
+--- nix-2.9.2/src/libexpr/value-to-json.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libexpr/value-to-json.cc	2022-07-05 21:38:55.586443957 +0200
+@@ -80,7 +80,7 @@ void printValueAsJSON(EvalState & state,
+ 
+         case nThunk:
+         case nFunction:
+-            auto e = TypeError({
++            auto e = TypeError(ErrorInfo{
+                 .msg = hintfmt("cannot convert %1% to JSON", showType(v)),
+                 .errPos = state.positions[v.determinePos(pos)]
+             });
+--- nix-2.9.2/src/libstore/build/derivation-goal.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libstore/build/derivation-goal.cc	2022-07-05 22:00:19.607148739 +0200
+@@ -832,7 +832,7 @@ void runPostBuildHook(
+     };
+     LogSink sink(act);
+ 
+-    runProgram2({
++    runProgram2(RunOptions{
+         .program = settings.postBuildHook,
+         .environment = hookEnvironment,
+         .standardOut = &sink,
+--- nix-2.9.2/src/libstore/globals.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libstore/globals.cc	2022-07-06 06:17:13.775714375 +0200
+@@ -212,19 +212,19 @@ template<> std::string BaseSetting<Sandb
+ 
+ template<> void BaseSetting<SandboxMode>::convertToArg(Args & args, const std::string & category)
+ {
+-    args.addFlag({
++    args.addFlag(Args::Flag{
+         .longName = name,
+         .description = "Enable sandboxing.",
+         .category = category,
+         .handler = {[=]() { override(smEnabled); }}
+     });
+-    args.addFlag({
++    args.addFlag(Args::Flag{
+         .longName = "no-" + name,
+         .description = "Disable sandboxing.",
+         .category = category,
+         .handler = {[=]() { override(smDisabled); }}
+     });
+-    args.addFlag({
++    args.addFlag(Args::Flag{
+         .longName = "relaxed-" + name,
+         .description = "Enable sandboxing, but allow builds to disable it.",
+         .category = category,
+--- nix-2.9.2/src/libstore/sqlite.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libstore/sqlite.cc	2022-07-06 06:23:32.941076415 +0200
+@@ -224,7 +224,7 @@ void handleSQLiteBusy(const SQLiteBusy &
+ 
+     if (now > lastWarned + 10) {
+         lastWarned = now;
+-        logWarning({
++        logWarning(ErrorInfo{
+             .msg = hintfmt(e.what())
+         });
+     }
+--- nix-2.9.2/src/libfetchers/git.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libfetchers/git.cc	2022-07-06 17:06:38.486246972 +0200
+@@ -628,7 +628,7 @@ struct GitInputScheme : InputScheme
+             // FIXME: should pipe this, or find some better way to extract a
+             // revision.
+             auto source = sinkToSource([&](Sink & sink) {
+-                runProgram2({
++                runProgram2(RunOptions{
+                     .program = "git",
+                     .args = { "-C", repoDir, "--git-dir", gitDir, "archive", input.getRev()->gitRev() },
+                     .standardOut = &sink
+--- nix-2.9.2/src/libfetchers/mercurial.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libfetchers/mercurial.cc	2022-07-06 17:11:39.244274108 +0200
+@@ -19,7 +19,7 @@ static RunOptions hgOptions(const String
+     // Set HGPLAIN: this means we get consistent output from hg and avoids leakage from a user or system .hgrc.
+     env["HGPLAIN"] = "";
+ 
+-    return {
++    return RunOptions{
+         .program = "hg",
+         .searchPath = true,
+         .args = args,
+--- nix-2.9.2/src/libmain/common-args.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libmain/common-args.cc	2022-07-06 17:13:59.023840375 +0200
+@@ -7,7 +7,7 @@ namespace nix {
+ MixCommonArgs::MixCommonArgs(const std::string & programName)
+     : programName(programName)
+ {
+-    addFlag({
++    addFlag(Flag{
+         .longName = "verbose",
+         .shortName = 'v',
+         .description = "Increase the logging verbosity level.",
+@@ -15,21 +15,21 @@ MixCommonArgs::MixCommonArgs(const std::
+         .handler = {[]() { verbosity = (Verbosity) (verbosity + 1); }},
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "quiet",
+         .description = "Decrease the logging verbosity level.",
+         .category = loggingCategory,
+         .handler = {[]() { verbosity = verbosity > lvlError ? (Verbosity) (verbosity - 1) : lvlError; }},
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "debug",
+         .description = "Set the logging verbosity level to 'debug'.",
+         .category = loggingCategory,
+         .handler = {[]() { verbosity = lvlDebug; }},
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "option",
+         .description = "Set the Nix configuration setting *name* to *value* (overriding `nix.conf`).",
+         .labels = {"name", "value"},
+@@ -52,7 +52,7 @@ MixCommonArgs::MixCommonArgs(const std::
+         }
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "log-format",
+         .description = "Set the format of log output; one of `raw`, `internal-json`, `bar` or `bar-with-logs`.",
+         .category = loggingCategory,
+@@ -60,7 +60,7 @@ MixCommonArgs::MixCommonArgs(const std::
+         .handler = {[](std::string format) { setLogFormat(format); }},
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "max-jobs",
+         .shortName = 'j',
+         .description = "The maximum number of parallel builds.",
+--- nix-2.9.2/src/libmain/shared.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libmain/shared.cc	2022-07-06 17:14:45.303559656 +0200
+@@ -228,28 +228,28 @@ LegacyArgs::LegacyArgs(const std::string
+     std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg)
+     : MixCommonArgs(programName), parseArg(parseArg)
+ {
+-    addFlag({
++    addFlag(Flag{
+         .longName = "no-build-output",
+         .shortName = 'Q',
+         .description = "Do not show build output.",
+         .handler = {[&]() {setLogFormat(LogFormat::raw); }},
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "keep-failed",
+         .shortName ='K',
+         .description = "Keep temporary directories of failed builds.",
+         .handler = {&(bool&) settings.keepFailed, true},
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "keep-going",
+         .shortName ='k',
+         .description = "Keep going after a build fails.",
+         .handler = {&(bool&) settings.keepGoing, true},
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "fallback",
+         .description = "Build from source if substitution fails.",
+         .handler = {&(bool&) settings.tryFallback, true},
+@@ -258,7 +258,7 @@ LegacyArgs::LegacyArgs(const std::string
+     auto intSettingAlias = [&](char shortName, const std::string & longName,
+         const std::string & description, const std::string & dest)
+     {
+-        addFlag({
++        addFlag(Flag{
+             .longName = longName,
+             .shortName = shortName,
+             .description = description,
+@@ -274,19 +274,19 @@ LegacyArgs::LegacyArgs(const std::string
+     intSettingAlias(0, "max-silent-time", "Number of seconds of silence before a build is killed.", "max-silent-time");
+     intSettingAlias(0, "timeout", "Number of seconds before a build is killed.", "timeout");
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "readonly-mode",
+         .description = "Do not write to the Nix store.",
+         .handler = {&settings.readOnlyMode, true},
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "no-gc-warning",
+         .description = "Disable warnings about not using `--add-root`.",
+         .handler = {&gcWarning, false},
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "store",
+         .description = "The URL of the Nix store to use.",
+         .labels = {"store-uri"},
+--- nix-2.9.2/src/libcmd/command.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libcmd/command.cc	2022-07-06 17:15:38.323314423 +0200
+@@ -56,14 +56,14 @@ void StoreCommand::run()
+ 
+ CopyCommand::CopyCommand()
+ {
+-    addFlag({
++    addFlag(Flag{
+         .longName = "from",
+         .description = "URL of the source Nix store.",
+         .labels = {"store-uri"},
+         .handler = {&srcUri},
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "to",
+         .description = "URL of the destination Nix store.",
+         .labels = {"store-uri"},
+@@ -86,7 +86,7 @@ ref<Store> CopyCommand::getDstStore()
+ 
+ EvalCommand::EvalCommand()
+ {
+-    addFlag({
++    addFlag(Flag{
+         .longName = "debugger",
+         .description = "start an interactive environment if evaluation fails",
+         .handler = {&startReplOnEvalErrors, true},
+@@ -130,14 +130,14 @@ BuiltPathsCommand::BuiltPathsCommand(boo
+     : recursive(recursive)
+ {
+     if (recursive)
+-        addFlag({
++        addFlag(Flag{
+             .longName = "no-recursive",
+             .description = "Apply operation to specified paths only.",
+             .category = installablesCategory,
+             .handler = {&this->recursive, false},
+         });
+     else
+-        addFlag({
++        addFlag(Flag{
+             .longName = "recursive",
+             .shortName = 'r',
+             .description = "Apply operation to closure of the specified paths.",
+@@ -145,7 +145,7 @@ BuiltPathsCommand::BuiltPathsCommand(boo
+             .handler = {&this->recursive, true},
+         });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "all",
+         .description = "Apply the operation to every store path.",
+         .category = installablesCategory,
+@@ -223,7 +223,7 @@ Strings editorFor(const Path & file, uin
+ 
+ MixProfile::MixProfile()
+ {
+-    addFlag({
++    addFlag(Flag{
+         .longName = "profile",
+         .description = "The profile to update.",
+         .labels = {"path"},
+@@ -276,14 +276,14 @@ MixDefaultProfile::MixDefaultProfile()
+ 
+ MixEnvironment::MixEnvironment() : ignoreEnvironment(false)
+ {
+-    addFlag({
++    addFlag(Flag{
+         .longName = "ignore-environment",
+         .shortName = 'i',
+         .description = "Clear the entire environment (except those specified with `--keep`).",
+         .handler = {&ignoreEnvironment, true},
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "keep",
+         .shortName = 'k',
+         .description = "Keep the environment variable *name*.",
+@@ -291,7 +291,7 @@ MixEnvironment::MixEnvironment() : ignor
+         .handler = {[&](std::string s) { keep.insert(s); }},
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "unset",
+         .shortName = 'u',
+         .description = "Unset the environment variable *name*.",
+--- nix-2.9.2/src/libcmd/common-eval-args.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libcmd/common-eval-args.cc	2022-07-06 17:16:46.806254752 +0200
+@@ -15,7 +15,7 @@ MixEvalArgs::MixEvalArgs()
+ {
+     auto category = "Common evaluation options";
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "arg",
+         .description = "Pass the value *expr* as the argument *name* to Nix functions.",
+         .category = category,
+@@ -23,7 +23,7 @@ MixEvalArgs::MixEvalArgs()
+         .handler = {[&](std::string name, std::string expr) { autoArgs[name] = 'E' + expr; }}
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "argstr",
+         .description = "Pass the string *string* as the argument *name* to Nix functions.",
+         .category = category,
+@@ -31,7 +31,7 @@ MixEvalArgs::MixEvalArgs()
+         .handler = {[&](std::string name, std::string s) { autoArgs[name] = 'S' + s; }},
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "include",
+         .shortName = 'I',
+         .description = "Add *path* to the list of locations used to look up `<...>` file names.",
+@@ -40,7 +40,7 @@ MixEvalArgs::MixEvalArgs()
+         .handler = {[&](std::string s) { searchPath.push_back(s); }}
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "impure",
+         .description = "Allow access to mutable paths and repositories.",
+         .category = category,
+@@ -49,7 +49,7 @@ MixEvalArgs::MixEvalArgs()
+         }},
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "override-flake",
+         .description = "Override the flake registries, redirecting *original-ref* to *resolved-ref*.",
+         .category = category,
+@@ -66,7 +66,7 @@ MixEvalArgs::MixEvalArgs()
+         }}
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "eval-store",
+         .description = "The Nix store to use for evaluations.",
+         .category = category,
+--- nix-2.9.2/src/libcmd/installables.cc.orig	2022-06-16 15:09:41.000000000 +0200
++++ nix-2.9.2/src/libcmd/installables.cc	2022-07-06 17:18:09.389150696 +0200
+@@ -38,28 +38,28 @@ MixFlakeOptions::MixFlakeOptions()
+ {
+     auto category = "Common flake-related options";
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "recreate-lock-file",
+         .description = "Recreate the flake's lock file from scratch.",
+         .category = category,
+         .handler = {&lockFlags.recreateLockFile, true}
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "no-update-lock-file",
+         .description = "Do not allow any updates to the flake's lock file.",
+         .category = category,
+         .handler = {&lockFlags.updateLockFile, false}
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "no-write-lock-file",
+         .description = "Do not write the flake's newly generated lock file.",
+         .category = category,
+         .handler = {&lockFlags.writeLockFile, false}
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "no-registries",
+         .description =
+           "Don't allow lookups in the flake registries. This option is deprecated; use `--no-use-registries`.",
+@@ -70,14 +70,14 @@ MixFlakeOptions::MixFlakeOptions()
+         }}
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "commit-lock-file",
+         .description = "Commit changes to the flake's lock file.",
+         .category = category,
+         .handler = {&lockFlags.commitLockFile, true}
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "update-input",
+         .description = "Update a specific flake input (ignoring its previous entry in the lock file).",
+         .category = category,
+@@ -91,7 +91,7 @@ MixFlakeOptions::MixFlakeOptions()
+         }}
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "override-input",
+         .description = "Override a specific flake input (e.g. `dwarffs/nixpkgs`). This implies `--no-write-lock-file`.",
+         .category = category,
+@@ -112,7 +112,7 @@ MixFlakeOptions::MixFlakeOptions()
+         }}
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "inputs-from",
+         .description = "Use the inputs of the specified flake as registry entries.",
+         .category = category,
+@@ -141,7 +141,7 @@ MixFlakeOptions::MixFlakeOptions()
+ 
+ SourceExprCommand::SourceExprCommand(bool supportReadOnlyMode)
+ {
+-    addFlag({
++    addFlag(Flag{
+         .longName = "file",
+         .shortName = 'f',
+         .description =
+@@ -153,7 +153,7 @@ SourceExprCommand::SourceExprCommand(boo
+         .completer = completePath
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "expr",
+         .description = "Interpret installables as attribute paths relative to the Nix expression *expr*.",
+         .category = installablesCategory,
+@@ -161,7 +161,7 @@ SourceExprCommand::SourceExprCommand(boo
+         .handler = {&expr}
+     });
+ 
+-    addFlag({
++    addFlag(Flag{
+         .longName = "derivation",
+         .description = "Operate on the store derivation rather than its outputs.",
+         .category = installablesCategory,
+@@ -169,7 +169,7 @@ SourceExprCommand::SourceExprCommand(boo
+     });
+ 
+     if (supportReadOnlyMode) {
+-        addFlag({
++        addFlag(Flag{
+             .longName = "read-only",
+             .description =
+                 "Do not instantiate each evaluated derivation. "
+@@ -1021,7 +1021,7 @@ StorePathSet Installable::toDerivations(
+ 
+ InstallablesCommand::InstallablesCommand()
+ {
+-    expectArgs({
++    expectArgs(ExpectedArg{
+         .label = "installables",
+         .handler = {&_installables},
+         .completer = {[&](size_t, std::string_view prefix) {
+@@ -1052,7 +1052,7 @@ std::optional<FlakeRef> InstallablesComm
+ InstallableCommand::InstallableCommand(bool supportReadOnlyMode)
+     : SourceExprCommand(supportReadOnlyMode)
+ {
+-    expectArgs({
++    expectArgs(ExpectedArg{
+         .label = "installable",
+         .optional = true,
+         .handler = {&_installable},
diff --git a/nix-ldflags.patch b/nix-ldflags.patch
index c8d4238..8e87201 100644
--- a/nix-ldflags.patch
+++ b/nix-ldflags.patch
@@ -1,10 +1,10 @@
---- nix-2.3.10/configure.ac.orig	2021-03-13 17:10:59.748579291 +0100
-+++ nix-2.3.10/configure.ac	2021-03-13 19:03:22.665383108 +0100
-@@ -155,7 +155,6 @@
+--- nix-2.9.2/configure.ac.orig	2021-03-13 17:10:59.748579291 +0100
++++ nix-2.9.2/configure.ac	2021-03-13 19:03:22.665383108 +0100
+@@ -132,7 +132,6 @@ AC_SUBST(storedir)
  AX_BOOST_BASE([1.66], [CXXFLAGS="$BOOST_CPPFLAGS $CXXFLAGS"], [AC_MSG_ERROR([Nix requires boost.])])
  # For unknown reasons, setting this directly in the ACTION-IF-FOUND above
  # ends up with LDFLAGS being empty, so we set it afterwards.
 -LDFLAGS="$BOOST_LDFLAGS $LDFLAGS"
  
- 
- # Look for OpenSSL, a required dependency.
+ # On some platforms, new-style atomics need a helper library
+ AC_MSG_CHECKING(whether -latomic is needed)
diff --git a/nix-paths.patch b/nix-paths.patch
index 541440b..cba6bf7 100644
--- a/nix-paths.patch
+++ b/nix-paths.patch
@@ -1,9 +1,10 @@
---- nix-2.3.4/misc/systemd/local.mk.orig	1970-01-01 01:00:01.000000000 +0100
-+++ nix-2.3.4/misc/systemd/local.mk	2020-04-21 18:43:49.318065743 +0200
-@@ -1,5 +1,5 @@
- ifeq ($(OS), Linux)
+--- nix-2.9.2/misc/systemd/local.mk.orig	2022-07-04 11:48:18.334153925 +0200
++++ nix-2.9.2/misc/systemd/local.mk	2022-07-04 16:55:51.821491895 +0200
+@@ -1,6 +1,6 @@
+ ifdef HOST_LINUX
  
 -  $(foreach n, nix-daemon.socket nix-daemon.service, $(eval $(call install-file-in, $(d)/$(n), $(prefix)/lib/systemd/system, 0644)))
 +  $(foreach n, nix-daemon.socket nix-daemon.service, $(eval $(call install-file-in, $(d)/$(n), /lib/systemd/system, 0644)))
+   $(foreach n, nix-daemon.conf, $(eval $(call install-file-in, $(d)/$(n), $(prefix)/lib/tmpfiles.d, 0644)))
  
- endif
+   clean-files += $(d)/nix-daemon.socket $(d)/nix-daemon.service $(d)/nix-daemon.conf
diff --git a/nix-sh.patch b/nix-sh.patch
index 5ff1bad..dcf2686 100644
--- a/nix-sh.patch
+++ b/nix-sh.patch
@@ -1,5 +1,5 @@
---- nix-2.3.15/configure.ac.orig	2021-08-21 19:53:43.033960617 +0200
-+++ nix-2.3.15/configure.ac	2021-08-21 19:57:30.176063416 +0200
+--- nix-2.9.2/configure.ac.orig	2022-07-04 22:48:50.076117019 +0200
++++ nix-2.9.2/configure.ac	2022-07-05 21:31:45.863099554 +0200
 @@ -259,10 +259,10 @@ AC_SUBST(ENABLE_S3, [$enable_s3])
  AC_LANG_POP(C++)
  
@@ -15,3 +15,16 @@
  fi
  
  
+@@ -309,9 +309,9 @@ fi
+ test "$prefix" = NONE && prefix=$ac_default_prefix
+ test "$exec_prefix" = NONE && exec_prefix='${prefix}'
+ for name in $ac_subst_vars; do
+-    declare $name="$(eval echo "${!name}")"
+-    declare $name="$(eval echo "${!name}")"
+-    declare $name="$(eval echo "${!name}")"
++    eval $name=\"$(eval echo "\${$name}")\"
++    eval $name=\"$(eval echo "\${$name}")\"
++    eval $name=\"$(eval echo "\${$name}")\"
+ done
+ 
+ rm -f Makefile.config
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/nix.git/commitdiff/5d1b272f13dc7659552c304aa04646844837301f



More information about the pld-cvs-commit mailing list