parser: merge nested dynamic attributes
Fixes https://github.com/NixOS/nix/issues/7115
This commit is contained in:
parent
85d0eb6316
commit
570a1a3ad7
|
@ -6,3 +6,22 @@
|
||||||
|
|
||||||
- Nix now allows unprivileged/[`allowed-users`](../command-ref/conf-file.md#conf-allowed-users) to sign paths.
|
- 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.
|
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.
|
||||||
|
|
|
@ -137,6 +137,7 @@ static void addAttr(ExprAttrs * attrs, AttrPath && attrPath,
|
||||||
dupAttr(state, ad.first, j2->second.pos, ad.second.pos);
|
dupAttr(state, ad.first, j2->second.pos, ad.second.pos);
|
||||||
jAttrs->attrs.emplace(ad.first, ad.second);
|
jAttrs->attrs.emplace(ad.first, ad.second);
|
||||||
}
|
}
|
||||||
|
jAttrs->dynamicAttrs.insert(jAttrs->dynamicAttrs.end(), ae->dynamicAttrs.begin(), ae->dynamicAttrs.end());
|
||||||
} else {
|
} else {
|
||||||
dupAttr(state, attrPath, pos, j->second.pos);
|
dupAttr(state, attrPath, pos, j->second.pos);
|
||||||
}
|
}
|
||||||
|
|
8
tests/lang/eval-fail-dup-dynamic-attrs.err.exp
Normal file
8
tests/lang/eval-fail-dup-dynamic-attrs.err.exp
Normal 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| }
|
4
tests/lang/eval-fail-dup-dynamic-attrs.nix
Normal file
4
tests/lang/eval-fail-dup-dynamic-attrs.nix
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
set = { "${"" + "b"}" = 1; };
|
||||||
|
set = { "${"b" + ""}" = 2; };
|
||||||
|
}
|
1
tests/lang/eval-okay-merge-dynamic-attrs.exp
Normal file
1
tests/lang/eval-okay-merge-dynamic-attrs.exp
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{ set1 = { a = 1; b = 2; }; set2 = { a = 1; b = 2; }; set3 = { a = 1; b = 2; }; set4 = { a = 1; b = 2; }; }
|
13
tests/lang/eval-okay-merge-dynamic-attrs.nix
Normal file
13
tests/lang/eval-okay-merge-dynamic-attrs.nix
Normal 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;
|
||||||
|
}
|
Loading…
Reference in a new issue