aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libexpr/eval.cc8
-rw-r--r--src/libexpr/eval.hh2
2 files changed, 9 insertions, 1 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 2b9b96559..cd9c64594 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -23,6 +23,8 @@ EvalState::EvalState()
initNixExprHelpers();
addPrimOps();
+
+ allowUnsafeEquality = getEnv("NIX_NO_UNSAFE_EQ", "") == "";
}
@@ -661,9 +663,13 @@ LocalNoInline(bool areEqual(EvalState & state, Expr e1, Expr e2))
/* Functions are incomparable. */
if (sym1 == symFunction || sym1 == symPrimOp) return false;
- if (sym1 == symAttrs)
+ if (!state.allowUnsafeEquality && sym1 == symAttrs)
throw EvalError("comparison of attribute sets is not implemented");
+ /* !!! This allows comparisons of infinite data structures to
+ succeed, such as `let x = [x]; in x == x'. This is
+ undesirable, since equivalent (?) terms such as `let x = [x]; y
+ = [y]; in x == y' don't terminate. */
if (e1 == e2) return true;
if (sym1 == symList) {
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 5699d455c..fed6d3472 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -38,6 +38,8 @@ struct EvalState
unsigned int nrEvaluated;
unsigned int nrCached;
+ bool allowUnsafeEquality;
+
EvalState();
void addPrimOps();