diagnose duplicated attrs at correct path
diagnose attr duplication at the path the duplication was detected, not
at the path the current attribute wanted to place. doing the latter is
only correct if a leaf attribute was duplicated, not if an attrpath was
set to a non-attrset in one binding and a (potentially implied) attrset
in another binding.
fixes #124
Change-Id: Ic4aa9cc12a9874d4e7897c6f64408f10aa36fc82
This commit is contained in:
parent
e257ff10fd
commit
11f35afa6f
22
doc/manual/rl-next/dup-attr-errors.md
Normal file
22
doc/manual/rl-next/dup-attr-errors.md
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
---
|
||||||
|
synopsis: Duplicate attribute reports are more accurate
|
||||||
|
# prs: cl 557
|
||||||
|
---
|
||||||
|
|
||||||
|
Duplicate attribute errors are now more accurate, showing the path at which an error was detected rather than the full, possibly longer, path that caused the error.
|
||||||
|
Error reports are now
|
||||||
|
```ShellSession
|
||||||
|
$ nix eval --expr '{ a.b = 1; a.b.c.d = 1; }'
|
||||||
|
error: attribute 'a.b' already defined at «string»:1:3
|
||||||
|
at «string»:1:12:
|
||||||
|
1| { a.b = 1; a.b.c.d = 1;
|
||||||
|
| ^
|
||||||
|
```
|
||||||
|
instead of
|
||||||
|
```ShellSession
|
||||||
|
$ nix eval --expr '{ a.b = 1; a.b.c.d = 1; }'
|
||||||
|
error: attribute 'a.b.c.d' already defined at «string»:1:3
|
||||||
|
at «string»:1:12:
|
||||||
|
1| { a.b = 1; a.b.c.d = 1;
|
||||||
|
| ^
|
||||||
|
```
|
|
@ -90,10 +90,10 @@ inline void ParserState::addAttr(ExprAttrs * attrs, AttrPath && attrPath, Expr *
|
||||||
if (j != attrs->attrs.end()) {
|
if (j != attrs->attrs.end()) {
|
||||||
if (j->second.kind != ExprAttrs::AttrDef::Kind::Inherited) {
|
if (j->second.kind != ExprAttrs::AttrDef::Kind::Inherited) {
|
||||||
ExprAttrs * attrs2 = dynamic_cast<ExprAttrs *>(j->second.e);
|
ExprAttrs * attrs2 = dynamic_cast<ExprAttrs *>(j->second.e);
|
||||||
if (!attrs2) dupAttr(attrPath, pos, j->second.pos);
|
if (!attrs2) dupAttr({attrPath.begin(), i + 1}, pos, j->second.pos);
|
||||||
attrs = attrs2;
|
attrs = attrs2;
|
||||||
} else
|
} else
|
||||||
dupAttr(attrPath, pos, j->second.pos);
|
dupAttr({attrPath.begin(), i + 1}, pos, j->second.pos);
|
||||||
} else {
|
} else {
|
||||||
ExprAttrs * nested = new ExprAttrs;
|
ExprAttrs * nested = new ExprAttrs;
|
||||||
attrs->attrs[i->symbol] = ExprAttrs::AttrDef(nested, pos);
|
attrs->attrs[i->symbol] = ExprAttrs::AttrDef(nested, pos);
|
||||||
|
|
5
tests/functional/lang/eval-fail-dupAttr-deep.err.exp
Normal file
5
tests/functional/lang/eval-fail-dupAttr-deep.err.exp
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
error: attribute 'a.b.c' already defined at /pwd/lang/eval-fail-dupAttr-deep.nix:1:3
|
||||||
|
at /pwd/lang/eval-fail-dupAttr-deep.nix:1:14:
|
||||||
|
1| { a.b.c = 1; a.b.c.a.a = 1; }
|
||||||
|
| ^
|
||||||
|
2|
|
1
tests/functional/lang/eval-fail-dupAttr-deep.nix
Normal file
1
tests/functional/lang/eval-fail-dupAttr-deep.nix
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{ a.b.c = 1; a.b.c.a.a = 1; }
|
5
tests/functional/lang/eval-fail-dupAttr-inherit.err.exp
Normal file
5
tests/functional/lang/eval-fail-dupAttr-inherit.err.exp
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
error: attribute 'a' already defined at /pwd/lang/eval-fail-dupAttr-inherit.nix:1:15
|
||||||
|
at /pwd/lang/eval-fail-dupAttr-inherit.nix:1:19:
|
||||||
|
1| { inherit ({}) a; a.b = 1; }
|
||||||
|
| ^
|
||||||
|
2|
|
1
tests/functional/lang/eval-fail-dupAttr-inherit.nix
Normal file
1
tests/functional/lang/eval-fail-dupAttr-inherit.nix
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{ inherit ({}) a; a.b = 1; }
|
5
tests/functional/lang/eval-fail-dupAttr.err.exp
Normal file
5
tests/functional/lang/eval-fail-dupAttr.err.exp
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
error: attribute 'a' already defined at /pwd/lang/eval-fail-dupAttr.nix:1:3
|
||||||
|
at /pwd/lang/eval-fail-dupAttr.nix:1:10:
|
||||||
|
1| { a = 1; a.b = 1; }
|
||||||
|
| ^
|
||||||
|
2|
|
1
tests/functional/lang/eval-fail-dupAttr.nix
Normal file
1
tests/functional/lang/eval-fail-dupAttr.nix
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{ a = 1; a.b = 1; }
|
Loading…
Reference in a new issue