libexpr/print: never show empty attrsets or derivations as «repeated»

The repeated value detection logic exists so that the occurrence of large
common substructures does not fill up the screen or the computer's memory.
However, empty attribute sets and derivations (when their detection is enabled)
are always cheap to print, and in practice I have observed them to make up a
significant majority of the cases where I was annoyed by the repeated value
detection kicking in. Furthermore, `nix-instantiate --eval` already disables
this logic for empty attribute sets, and empty lists are already exempted
everywhere. For these reasons, always print empty attribute sets and
derivations as what they are.

Change-Id: I5dac8e7739f9d726b76fd0521ec46f38af94463f
This commit is contained in:
alois31 2024-07-15 18:24:16 +02:00
parent 81a0624d76
commit b5da823138
Signed by: alois31
GPG key ID: E0F59EA5E5216914
2 changed files with 33 additions and 24 deletions

View file

@ -277,13 +277,10 @@ private:
void printAttrs(Value & v, size_t depth) void printAttrs(Value & v, size_t depth)
{ {
if (seen && !seen->insert(v.attrs).second) {
printRepeated();
return;
}
if (options.force && options.derivationPaths && state.isDerivation(v)) { if (options.force && options.derivationPaths && state.isDerivation(v)) {
printDerivation(v); printDerivation(v);
} else if (seen && !v.attrs->empty() && !seen->insert(v.attrs).second) {
printRepeated();
} else if (depth < options.maxDepth) { } else if (depth < options.maxDepth) {
increaseIndent(); increaseIndent();
output << "{"; output << "{";

View file

@ -641,20 +641,24 @@ TEST_F(ValuePrintingTests, ansiColorsBlackhole)
TEST_F(ValuePrintingTests, ansiColorsAttrsRepeated) TEST_F(ValuePrintingTests, ansiColorsAttrsRepeated)
{ {
BindingsBuilder emptyBuilder(state, state.allocBindings(1)); Value vZero;
vZero.mkInt(0);
Value vEmpty; BindingsBuilder innerBuilder(state, state.allocBindings(1));
vEmpty.mkAttrs(emptyBuilder.finish()); innerBuilder.insert(state.symbols.create("x"), &vZero);
Value vInner;
vInner.mkAttrs(innerBuilder.finish());
BindingsBuilder builder(state, state.allocBindings(10)); BindingsBuilder builder(state, state.allocBindings(10));
builder.insert(state.symbols.create("a"), &vEmpty); builder.insert(state.symbols.create("a"), &vInner);
builder.insert(state.symbols.create("b"), &vEmpty); builder.insert(state.symbols.create("b"), &vInner);
Value vAttrs; Value vAttrs;
vAttrs.mkAttrs(builder.finish()); vAttrs.mkAttrs(builder.finish());
test(vAttrs, test(vAttrs,
"{ a = { }; b = " ANSI_MAGENTA "«repeated»" ANSI_NORMAL "; }", "{ a = { x = " ANSI_CYAN "0" ANSI_NORMAL "; }; b = " ANSI_MAGENTA "«repeated»" ANSI_NORMAL "; }",
PrintOptions { PrintOptions {
.ansiColors = true .ansiColors = true
}); });
@ -662,19 +666,23 @@ TEST_F(ValuePrintingTests, ansiColorsAttrsRepeated)
TEST_F(ValuePrintingTests, ansiColorsListRepeated) TEST_F(ValuePrintingTests, ansiColorsListRepeated)
{ {
BindingsBuilder emptyBuilder(state, state.allocBindings(1)); Value vZero;
vZero.mkInt(0);
Value vEmpty; BindingsBuilder innerBuilder(state, state.allocBindings(1));
vEmpty.mkAttrs(emptyBuilder.finish()); innerBuilder.insert(state.symbols.create("x"), &vZero);
Value vInner;
vInner.mkAttrs(innerBuilder.finish());
Value vList; Value vList;
state.mkList(vList, 3); state.mkList(vList, 3);
vList.bigList.elems[0] = &vEmpty; vList.bigList.elems[0] = &vInner;
vList.bigList.elems[1] = &vEmpty; vList.bigList.elems[1] = &vInner;
vList.bigList.size = 2; vList.bigList.size = 2;
test(vList, test(vList,
"[ { } " ANSI_MAGENTA "«repeated»" ANSI_NORMAL " ]", "[ { x = " ANSI_CYAN "0" ANSI_NORMAL "; } " ANSI_MAGENTA "«repeated»" ANSI_NORMAL " ]",
PrintOptions { PrintOptions {
.ansiColors = true .ansiColors = true
}); });
@ -682,20 +690,24 @@ TEST_F(ValuePrintingTests, ansiColorsListRepeated)
TEST_F(ValuePrintingTests, listRepeated) TEST_F(ValuePrintingTests, listRepeated)
{ {
BindingsBuilder emptyBuilder(state, state.allocBindings(1)); Value vZero;
vZero.mkInt(0);
Value vEmpty; BindingsBuilder innerBuilder(state, state.allocBindings(1));
vEmpty.mkAttrs(emptyBuilder.finish()); innerBuilder.insert(state.symbols.create("x"), &vZero);
Value vInner;
vInner.mkAttrs(innerBuilder.finish());
Value vList; Value vList;
state.mkList(vList, 3); state.mkList(vList, 3);
vList.bigList.elems[0] = &vEmpty; vList.bigList.elems[0] = &vInner;
vList.bigList.elems[1] = &vEmpty; vList.bigList.elems[1] = &vInner;
vList.bigList.size = 2; vList.bigList.size = 2;
test(vList, "[ { } «repeated» ]", PrintOptions { }); test(vList, "[ { x = 0; } «repeated» ]", PrintOptions { });
test(vList, test(vList,
"[ { } { } ]", "[ { x = 0; } { x = 0; } ]",
PrintOptions { PrintOptions {
.trackRepeated = false .trackRepeated = false
}); });