From afb839a0c9888bc8b98c0dd4abd28c79d754c250 Mon Sep 17 00:00:00 2001
From: eldritch horrors <pennae@lix.systems>
Date: Mon, 18 Mar 2024 21:09:39 +0100
Subject: [PATCH] libexpr: associate let exprs with the correct StaticEnv

static env association is from expr to its enclosing scope, but let
exprs set their association to their *inner* scope. this skips one level
of envs and will cause segfaults if the parent is a with expr.

fixes #145

Change-Id: I1d22146110f071ede21b4eed7ed34b5850ef2ef3
---
 src/libexpr/nixexpr.cc                             |  2 +-
 .../repl_characterization/data/regression_l145.nix |  5 +++++
 .../data/regression_l145.test                      | 14 ++++++++++++++
 .../repl_characterization/repl_characterization.cc |  1 +
 4 files changed, 21 insertions(+), 1 deletion(-)
 create mode 100644 tests/functional/repl_characterization/data/regression_l145.nix
 create mode 100644 tests/functional/repl_characterization/data/regression_l145.test

diff --git a/src/libexpr/nixexpr.cc b/src/libexpr/nixexpr.cc
index a9989b59e..e0f4def4c 100644
--- a/src/libexpr/nixexpr.cc
+++ b/src/libexpr/nixexpr.cc
@@ -483,7 +483,7 @@ void ExprLet::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> &
         i.second.e->bindVars(es, i.second.chooseByKind(newEnv, env, inheritFromEnv));
 
     if (es.debugRepl)
-        es.exprEnvs.insert(std::make_pair(this, newEnv));
+        es.exprEnvs.insert(std::make_pair(this, env));
 
     body->bindVars(es, newEnv);
 }
diff --git a/tests/functional/repl_characterization/data/regression_l145.nix b/tests/functional/repl_characterization/data/regression_l145.nix
new file mode 100644
index 000000000..26bcdb3fa
--- /dev/null
+++ b/tests/functional/repl_characterization/data/regression_l145.nix
@@ -0,0 +1,5 @@
+with { inherit ({}) invalid; };
+let
+  x = builtins.break 1;
+in
+  x
diff --git a/tests/functional/repl_characterization/data/regression_l145.test b/tests/functional/repl_characterization/data/regression_l145.test
new file mode 100644
index 000000000..2fe04d221
--- /dev/null
+++ b/tests/functional/repl_characterization/data/regression_l145.test
@@ -0,0 +1,14 @@
+  info: breakpoint reached
+
+debugger should not crash now, but also not show any with variables
+  nix-repl> :st
+  0: error: breakpoint reached
+  «none»:0
+  Env level 0
+  static: x
+
+  Env level 1
+  static:
+
+  Env level 2
+  abort baseNameOf break builtins derivation derivationStrict dirOf false fetchGit fetchMercurial fetchTarball fetchTree fromTOML import isNull map null placeholder removeAttrs scopedImport throw toString true
diff --git a/tests/functional/repl_characterization/repl_characterization.cc b/tests/functional/repl_characterization/repl_characterization.cc
index 7aa7dac5c..d0c3b0a71 100644
--- a/tests/functional/repl_characterization/repl_characterization.cc
+++ b/tests/functional/repl_characterization/repl_characterization.cc
@@ -124,6 +124,7 @@ TEST_F(ReplSessionTest, repl_basic)
 
 DEBUGGER_TEST(regression_9918);
 DEBUGGER_TEST(regression_9917);
+DEBUGGER_TEST(regression_l145);
 DEBUGGER_TEST(stack_vars);
 
 };