aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/parser.y
diff options
context:
space:
mode:
authoreldritch horrors <pennae@lix.systems>2024-01-29 06:19:23 +0100
committereldritch horrors <pennae@lix.systems>2024-03-18 16:12:45 +0100
commit9cf92c012d81bdd8df60a51f7cbcdb4812544c46 (patch)
treebe0494f264fa49ebf57c9409852ca67451aa5ffa /src/libexpr/parser.y
parentd826427f022308f9ec2ee8f0ec9f7df85089fdf7 (diff)
report inherit attr errors at the duplicate name
previously we reported the error at the beginning of the binding block (for plain inherits) or the beginning of the attr list (for inherit-from), effectively hiding where exactly the error happened. this also carries over to runtime positions of attributes in sets as reported by unsafeGetAttrPos. we're not worried about this changing observable eval behavior because it *is* marked unsafe, and the new behavior is much more useful. (cherry picked from commit 1edd6fada53553b89847ac3981ac28025857ca02) Change-Id: I2f50eb9f3dc3977db4eb3e3da96f1cb37ccd5174
Diffstat (limited to 'src/libexpr/parser.y')
-rw-r--r--src/libexpr/parser.y25
1 files changed, 13 insertions, 12 deletions
diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y
index ee44a6d7a..476403c4c 100644
--- a/src/libexpr/parser.y
+++ b/src/libexpr/parser.y
@@ -85,6 +85,7 @@ void yyerror(YYLTYPE * loc, yyscan_t scanner, ParserState * state, const char *
nix::StringToken uri;
nix::StringToken str;
std::vector<nix::AttrName> * attrNames;
+ std::vector<std::pair<nix::AttrName, nix::PosIdx>> * inheritAttrs;
std::vector<std::pair<nix::PosIdx, nix::Expr *>> * string_parts;
std::vector<std::pair<nix::PosIdx, std::variant<nix::Expr *, nix::StringToken>>> * ind_string_parts;
}
@@ -95,7 +96,8 @@ void yyerror(YYLTYPE * loc, yyscan_t scanner, ParserState * state, const char *
%type <attrs> binds
%type <formals> formals
%type <formal> formal
-%type <attrNames> attrs attrpath
+%type <attrNames> attrpath
+%type <inheritAttrs> attrs
%type <string_parts> string_parts_interpolated
%type <ind_string_parts> ind_string_parts
%type <e> path_start string_parts string_attr
@@ -307,13 +309,12 @@ binds
: binds attrpath '=' expr ';' { $$ = $1; state->addAttr($$, std::move(*$2), $4, state->at(@2)); delete $2; }
| binds INHERIT attrs ';'
{ $$ = $1;
- for (auto & i : *$3) {
+ for (auto & [i, iPos] : *$3) {
if ($$->attrs.find(i.symbol) != $$->attrs.end())
- state->dupAttr(i.symbol, state->at(@3), $$->attrs[i.symbol].pos);
- auto pos = state->at(@3);
+ state->dupAttr(i.symbol, iPos, $$->attrs[i.symbol].pos);
$$->attrs.emplace(
i.symbol,
- ExprAttrs::AttrDef(new ExprVar(CUR_POS, i.symbol), pos, ExprAttrs::AttrDef::Kind::Inherited));
+ ExprAttrs::AttrDef(new ExprVar(iPos, i.symbol), iPos, ExprAttrs::AttrDef::Kind::Inherited));
}
delete $3;
}
@@ -323,14 +324,14 @@ binds
$$->inheritFromExprs = std::make_unique<std::vector<Expr *>>();
$$->inheritFromExprs->push_back($4);
auto from = new nix::ExprInheritFrom(state->at(@4), $$->inheritFromExprs->size() - 1);
- for (auto & i : *$6) {
+ for (auto & [i, iPos] : *$6) {
if ($$->attrs.find(i.symbol) != $$->attrs.end())
- state->dupAttr(i.symbol, state->at(@6), $$->attrs[i.symbol].pos);
+ state->dupAttr(i.symbol, iPos, $$->attrs[i.symbol].pos);
$$->attrs.emplace(
i.symbol,
ExprAttrs::AttrDef(
- new ExprSelect(CUR_POS, from, i.symbol),
- state->at(@6),
+ new ExprSelect(iPos, from, i.symbol),
+ iPos,
ExprAttrs::AttrDef::Kind::InheritedFrom));
}
delete $6;
@@ -339,12 +340,12 @@ binds
;
attrs
- : attrs attr { $$ = $1; $1->push_back(AttrName(state->symbols.create($2))); }
+ : attrs attr { $$ = $1; $1->emplace_back(AttrName(state->symbols.create($2)), state->at(@2)); }
| attrs string_attr
{ $$ = $1;
ExprString * str = dynamic_cast<ExprString *>($2);
if (str) {
- $$->push_back(AttrName(state->symbols.create(str->s)));
+ $$->emplace_back(AttrName(state->symbols.create(str->s)), state->at(@2));
delete str;
} else
throw ParseError({
@@ -352,7 +353,7 @@ attrs
.pos = state->positions[state->at(@2)]
});
}
- | { $$ = new AttrPath; }
+ | { $$ = new std::vector<std::pair<AttrName, PosIdx>>; }
;
attrpath