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
This commit is contained in:
Jade Lovelace
2025-06-25 14:15:37 +00:00
committed by jade
parent 38850e59e1
commit 276add2cd7
6 changed files with 44 additions and 1 deletions
+20
View File
@@ -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.
+8 -1
View File
@@ -3,7 +3,6 @@
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <string_view>
#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<TypeError>(
@@ -0,0 +1,3 @@
info: final: prev: {
foo = 2;
}
@@ -0,0 +1,3 @@
{
cat.meowy = true;
}
@@ -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
@@ -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);