mirror of
https://github.com/NixOS/nix
synced 2025-07-08 19:23:54 +02:00
parser-state: fix attribute merging
(cherry picked from commit 8034589d7e
)
This commit is contained in:
parent
6ae5aa7fa0
commit
e0e50fb01f
8 changed files with 133 additions and 52 deletions
|
@ -0,0 +1,5 @@
|
|||
error: undefined variable 'd'
|
||||
at /pwd/lang/eval-fail-attrset-merge-drops-later-rec.nix:1:26:
|
||||
1| { a.b = 1; a = rec { c = d + 2; d = 3; }; }.c
|
||||
| ^
|
||||
2|
|
|
@ -0,0 +1 @@
|
|||
{ a.b = 1; a = rec { c = d + 2; d = 3; }; }.c
|
|
@ -0,0 +1 @@
|
|||
6
|
|
@ -0,0 +1,3 @@
|
|||
# This is for backwards compatibility, not because we like it.
|
||||
# See https://github.com/NixOS/nix/issues/9020.
|
||||
{ a = rec { b = c + 1; d = 2; }; a.c = d + 3; }.a.b
|
|
@ -1,6 +1,6 @@
|
|||
error: attribute 'z' already defined at «stdin»:3:16
|
||||
at «stdin»:2:3:
|
||||
1| {
|
||||
error: attribute 'x.z' already defined at «stdin»:2:3
|
||||
at «stdin»:3:16:
|
||||
2| x.z = 3;
|
||||
| ^
|
||||
3| x = { y = 3; z = 3; };
|
||||
| ^
|
||||
4| }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
error: attribute 'y' already defined at «stdin»:3:9
|
||||
at «stdin»:2:3:
|
||||
1| {
|
||||
error: attribute 'x.y.y' already defined at «stdin»:2:3
|
||||
at «stdin»:3:9:
|
||||
2| x.y.y = 3;
|
||||
| ^
|
||||
3| x = { y.y= 3; z = 3; };
|
||||
| ^
|
||||
4| }
|
||||
|
|
|
@ -177,6 +177,57 @@ namespace nix {
|
|||
)
|
||||
);
|
||||
|
||||
// The following macros ultimately define 48 tests (16 variations on three
|
||||
// templates). Each template tests an expression that can be written in 2^4
|
||||
// different ways, by making four choices about whether to write a particular
|
||||
// attribute path segment as `x.y = ...;` (collapsed) or `x = { y = ...; };`
|
||||
// (expanded).
|
||||
//
|
||||
// The nestedAttrsetMergeXXXX tests check that the expression
|
||||
// `{ a.b.c = 1; a.b.d = 2; }` has the same value regardless of how it is
|
||||
// expanded. (That exact expression is exercised in test
|
||||
// nestedAttrsetMerge0000, because it is fully collapsed. The test
|
||||
// nestedAttrsetMerge1001 would instead examine
|
||||
// `{ a = { b.c = 1; }; a.b = { d = 2; }; }`.)
|
||||
//
|
||||
// The nestedAttrsetMergeDupXXXX tests check that the expression
|
||||
// `{ a.b.c = 1; a.b.c = 2; }` throws a duplicate attribute error, again
|
||||
// regardless of how it is expanded.
|
||||
//
|
||||
// The nestedAttrsetMergeLetXXXX tests check that the expression
|
||||
// `let a.b.c = 1; a.b.d = 2; in a` has the same value regardless of how it is
|
||||
// expanded.
|
||||
#define X_EXPAND_IF0(k, v) k "." v
|
||||
#define X_EXPAND_IF1(k, v) k " = { " v " };"
|
||||
#define X4(w, x, y, z) \
|
||||
TEST_F(TrivialExpressionTest, nestedAttrsetMerge##w##x##y##z) { \
|
||||
auto v = eval("{ a.b = { c = 1; d = 2; }; } == { " \
|
||||
X_EXPAND_IF##w("a", X_EXPAND_IF##x("b", "c = 1;")) " " \
|
||||
X_EXPAND_IF##y("a", X_EXPAND_IF##z("b", "d = 2;")) " }"); \
|
||||
ASSERT_THAT(v, IsTrue()); \
|
||||
}; \
|
||||
TEST_F(TrivialExpressionTest, nestedAttrsetMergeDup##w##x##y##z) { \
|
||||
ASSERT_THROW(eval("{ " \
|
||||
X_EXPAND_IF##w("a", X_EXPAND_IF##x("b", "c = 1;")) " " \
|
||||
X_EXPAND_IF##y("a", X_EXPAND_IF##z("b", "c = 2;")) " }"), Error); \
|
||||
}; \
|
||||
TEST_F(TrivialExpressionTest, nestedAttrsetMergeLet##w##x##y##z) { \
|
||||
auto v = eval("{ b = { c = 1; d = 2; }; } == (let " \
|
||||
X_EXPAND_IF##w("a", X_EXPAND_IF##x("b", "c = 1;")) " " \
|
||||
X_EXPAND_IF##y("a", X_EXPAND_IF##z("b", "d = 2;")) " in a)"); \
|
||||
ASSERT_THAT(v, IsTrue()); \
|
||||
};
|
||||
#define X3(...) X4(__VA_ARGS__, 0) X4(__VA_ARGS__, 1)
|
||||
#define X2(...) X3(__VA_ARGS__, 0) X3(__VA_ARGS__, 1)
|
||||
#define X1(...) X2(__VA_ARGS__, 0) X2(__VA_ARGS__, 1)
|
||||
X1(0) X1(1)
|
||||
#undef X_EXPAND_IF0
|
||||
#undef X_EXPAND_IF1
|
||||
#undef X1
|
||||
#undef X2
|
||||
#undef X3
|
||||
#undef X4
|
||||
|
||||
TEST_F(TrivialExpressionTest, functor) {
|
||||
auto v = eval("{ __functor = self: arg: self.v + arg; v = 10; } 5");
|
||||
ASSERT_THAT(v, IsIntEq(15));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue