parser: merge nested dynamic attributes

Fixes https://github.com/NixOS/nix/issues/7115
This commit is contained in:
Naïm Favier 2023-07-08 12:28:13 +02:00
parent 85d0eb6316
commit 570a1a3ad7
No known key found for this signature in database
GPG key ID: 95AFCE8211908325
6 changed files with 46 additions and 0 deletions

View file

@ -6,3 +6,22 @@
- Nix now allows unprivileged/[`allowed-users`](../command-ref/conf-file.md#conf-allowed-users) to sign paths.
Previously, only [`trusted-users`](../command-ref/conf-file.md#conf-trusted-users) users could sign paths.
- Nested dynamic attributes are now merged correctly by the parser. For example:
```nix
{
nested = { foo = 1; };
nested = { ${"ba" + "r"} = 2; };
}
```
This used to silently discard `nested.bar`, but now behaves as one would expect and evaluates to:
```nix
{ nested = { bar = 2; foo = 1; }; }
```
Note that the feature of merging multiple attribute set declarations is of questionable value.
It allows writing expressions that are very hard to read, for instance when there are many lines of code between two declarations of the same attribute.
This has been around for a long time and is therefore supported for backwards compatibility, but should not be relied upon.

View file

@ -137,6 +137,7 @@ static void addAttr(ExprAttrs * attrs, AttrPath && attrPath,
dupAttr(state, ad.first, j2->second.pos, ad.second.pos);
jAttrs->attrs.emplace(ad.first, ad.second);
}
jAttrs->dynamicAttrs.insert(jAttrs->dynamicAttrs.end(), ae->dynamicAttrs.begin(), ae->dynamicAttrs.end());
} else {
dupAttr(state, attrPath, pos, j->second.pos);
}

View file

@ -0,0 +1,8 @@
error: dynamic attribute 'b' already defined at /pwd/lang/eval-fail-dup-dynamic-attrs.nix:2:11
at /pwd/lang/eval-fail-dup-dynamic-attrs.nix:3:11:
2| set = { "${"" + "b"}" = 1; };
3| set = { "${"b" + ""}" = 2; };
| ^
4| }

View file

@ -0,0 +1,4 @@
{
set = { "${"" + "b"}" = 1; };
set = { "${"b" + ""}" = 2; };
}

View file

@ -0,0 +1 @@
{ set1 = { a = 1; b = 2; }; set2 = { a = 1; b = 2; }; set3 = { a = 1; b = 2; }; set4 = { a = 1; b = 2; }; }

View file

@ -0,0 +1,13 @@
{
set1 = { a = 1; };
set1 = { "${"b" + ""}" = 2; };
set2 = { "${"b" + ""}" = 2; };
set2 = { a = 1; };
set3.a = 1;
set3."${"b" + ""}" = 2;
set4."${"b" + ""}" = 2;
set4.a = 1;
}