From d7b896aff5d26225054a2d8ff94ec3183bb4d546 Mon Sep 17 00:00:00 2001 From: RGBCube Date: Tue, 23 Apr 2024 00:05:39 +0300 Subject: [PATCH] Clarify attrset ptr equality in Nix --- site/blog/nix-iceberg.md | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/site/blog/nix-iceberg.md b/site/blog/nix-iceberg.md index d2d8082..a3300c4 100644 --- a/site/blog/nix-iceberg.md +++ b/site/blog/nix-iceberg.md @@ -699,8 +699,24 @@ Normally, Functions in Nix cannot be compared. Comparing two functions will _always_ return false, at least when done directly. -However, Nix has a [really ugly hack]() -where comparing two attribute sets with a function member can be true, -assuming the underlying pointer of a struct field value points to the -same function, the princible described in the previous paragraph is -ignored. +But if two attribute sets that are compared have the same address, +Nix ignores this and does a pointer comparision, totally ignoring +all members. This is a hack. + +[Link to code that does this.](https://github.com/NixOS/nix/blob/aa165301d1ae3b306319a6a834dc1d4e340a7112/src/libexpr/eval.cc#L2525-L2528) +Here's the snippet: + +```cpp +bool EvalState::eqValues(Value & v1, Value & v2, const PosIdx pos, std::string_view errorCtx) +{ + forceValue(v1, pos); + forceValue(v2, pos); + + /* !!! Hack to support some old broken code that relies on pointer + equality tests between sets. (Specifically, builderDefs calls + uniqList on a list of sets.) Will remove this eventually. */ + if (&v1 == &v2) return true; +``` + +This "temporary hack" was commited in 14 years ago. You can do whatever +you want with this information.