From 276add2cd7167d5c847e6440f7733c85166b9d53 Mon Sep 17 00:00:00 2001 From: Jade Lovelace Date: Thu, 19 Jun 2025 14:37:33 -0700 Subject: [PATCH] repl: fix repl-overlays in pure eval mode The reason this gets hit is because of the debugger in flakes. Otherwise you never have a repl in pure mode anyway. We evaluate the repl-overlay file in impure mode but this doesn't do what one would initially expect. Fixes: https://git.lix.systems/lix-project/lix/issues/777 Change-Id: I19b8ed2f5e9ce500b633b13301b42df69ab7deb3 --- doc/manual/rl-next/repl-overlays-pure.md | 20 +++++++++++++++++++ lix/libcmd/repl.cc | 9 ++++++++- .../data/extra_data/repl-overlay-trivial.nix | 3 +++ .../data/repl_overlays_regression_l777.nix | 3 +++ .../data/repl_overlays_regression_l777.test | 9 +++++++++ .../repl_characterization.cc | 1 + 6 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 doc/manual/rl-next/repl-overlays-pure.md create mode 100644 tests/functional/repl_characterization/data/extra_data/repl-overlay-trivial.nix create mode 100644 tests/functional/repl_characterization/data/repl_overlays_regression_l777.nix create mode 100644 tests/functional/repl_characterization/data/repl_overlays_regression_l777.test diff --git a/doc/manual/rl-next/repl-overlays-pure.md b/doc/manual/rl-next/repl-overlays-pure.md new file mode 100644 index 000000000..a8df19740 --- /dev/null +++ b/doc/manual/rl-next/repl-overlays-pure.md @@ -0,0 +1,20 @@ +--- +synopsis: "repl-overlays now work in the debugger for flakes" +issues: [fj#777] +cls: [3398] +category: Fixes +credits: [jade] +--- +Due to a bug, it was previously not possible to use the debugger on flakes with repl-overlays, or with pure evaluation in general: + +``` +$ nix repl --pure-eval +Lix 2.94.0-dev-pre20250617-87d99da +Type :? for help. +Loading 'repl-overlays'... +error: access to absolute path '/Users/jade/.config/nix/repl.nix' is forbidden in pure eval mode (use '--impure' to override) +``` + +This is now fixed. +The contents of the repl-overlays file itself (i.e. most typically the top level lambda in it) will be evaluated in impure mode. +It may be necessary to use `builtins.seq` to force the impure operations to happen first if one wants to do impure operations inside a repl-overlays file in pure evaluation mode. diff --git a/lix/libcmd/repl.cc b/lix/libcmd/repl.cc index 5afebea93..f232c0ced 100644 --- a/lix/libcmd/repl.cc +++ b/lix/libcmd/repl.cc @@ -3,7 +3,6 @@ #include #include #include -#include #include #include "lix/libutil/box_ptr.hh" @@ -1008,7 +1007,15 @@ Value * NixRepl::replOverlays() for (auto path : evalSettings.replOverlays.get()) { debug("Loading '%1%' path '%2%'...", "repl-overlays", path); SourcePath sourcePath((CanonPath(path))); + + // XXX(jade): This is a somewhat unsatisfying solution to + // https://git.lix.systems/lix-project/lix/issues/777 which means that + // the top level item in the repl-overlays file (that is, the lambda) + // gets evaluated with pure eval off. This means that if you want to do + // impure eval stuff, you will have to force it with builtins.seq. + bool prevPureEval = evalSettings.pureEval.get(); auto replInit = evalFile(sourcePath); + evalSettings.pureEval.setDefault(prevPureEval); if (!replInit->isLambda()) { evaluator.errors.make( diff --git a/tests/functional/repl_characterization/data/extra_data/repl-overlay-trivial.nix b/tests/functional/repl_characterization/data/extra_data/repl-overlay-trivial.nix new file mode 100644 index 000000000..0a0824971 --- /dev/null +++ b/tests/functional/repl_characterization/data/extra_data/repl-overlay-trivial.nix @@ -0,0 +1,3 @@ +info: final: prev: { + foo = 2; +} diff --git a/tests/functional/repl_characterization/data/repl_overlays_regression_l777.nix b/tests/functional/repl_characterization/data/repl_overlays_regression_l777.nix new file mode 100644 index 000000000..d0ca35fe2 --- /dev/null +++ b/tests/functional/repl_characterization/data/repl_overlays_regression_l777.nix @@ -0,0 +1,3 @@ +{ + cat.meowy = true; +} diff --git a/tests/functional/repl_characterization/data/repl_overlays_regression_l777.test b/tests/functional/repl_characterization/data/repl_overlays_regression_l777.test new file mode 100644 index 000000000..402ab96ff --- /dev/null +++ b/tests/functional/repl_characterization/data/repl_overlays_regression_l777.test @@ -0,0 +1,9 @@ +Checks that repl-overlays work correctly in pure eval mode +@args --pure-eval +@args --repl-overlays +@args ${PWD}/extra_data/repl-overlay-trivial.nix + + nix-repl> foo + 2 + + nix-repl> :quit diff --git a/tests/functional/repl_characterization/repl_characterization.cc b/tests/functional/repl_characterization/repl_characterization.cc index dea7b4d98..1bc30168e 100644 --- a/tests/functional/repl_characterization/repl_characterization.cc +++ b/tests/functional/repl_characterization/repl_characterization.cc @@ -184,6 +184,7 @@ REPL_TEST(regression_l145); REPL_TEST(regression_l592); REPL_TEST(repl_input); REPL_TEST(repl_overlays); +REPL_TEST(repl_overlays_regression_l777); REPL_TEST(repl_overlays_compose); REPL_TEST(repl_overlays_destructure_without_dotdotdot_errors); REPL_TEST(repl_overlays_destructure_without_formals_ok);