aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr
diff options
context:
space:
mode:
authoreldritch horrors <pennae@lix.systems>2024-03-08 09:51:27 +0100
committereldritch horrors <pennae@lix.systems>2024-03-10 03:18:32 -0600
commit03f852b2c69233667de839a4777331114304c983 (patch)
tree1c4b3b1c695708b6d3ed8acaaa978d7f653b980b /src/libexpr
parent3e43f4aeff2947aea98bb0d538fa686bd55a1385 (diff)
preserve information about whether/how an attribute was inherited
(cherry picked from commit c66ee57edc6cac3571bfbf77d0c0ea4d25b4e805) Change-Id: Ie8606a8b2f5946c87dd4d16b7b46203e199a4cc1
Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/eval.cc6
-rw-r--r--src/libexpr/nixexpr.cc8
-rw-r--r--src/libexpr/nixexpr.hh17
-rw-r--r--src/libexpr/parser-state.hh2
-rw-r--r--src/libexpr/parser.y11
5 files changed, 31 insertions, 13 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index bb3e6f3bd..bf4c917c6 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -1238,11 +1238,11 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
Displacement displ = 0;
for (auto & i : attrs) {
Value * vAttr;
- if (hasOverrides && !i.second.inherited) {
+ if (hasOverrides && !i.second.inherited()) {
vAttr = state.allocValue();
mkThunk(*vAttr, env2, i.second.e);
} else
- vAttr = i.second.e->maybeThunk(state, i.second.inherited ? env : env2);
+ vAttr = i.second.e->maybeThunk(state, i.second.inherited() ? env : env2);
env2.values[displ++] = vAttr;
v.attrs->push_back(Attr(i.first, vAttr, i.second.pos));
}
@@ -1313,7 +1313,7 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v)
environment. */
Displacement displ = 0;
for (auto & i : attrs->attrs)
- env2.values[displ++] = i.second.e->maybeThunk(state, i.second.inherited ? env : env2);
+ env2.values[displ++] = i.second.e->maybeThunk(state, i.second.inherited() ? env : env2);
auto dts = state.debugRepl
? makeDebugTraceStacker(
diff --git a/src/libexpr/nixexpr.cc b/src/libexpr/nixexpr.cc
index 3525ea1a3..a12fd62c0 100644
--- a/src/libexpr/nixexpr.cc
+++ b/src/libexpr/nixexpr.cc
@@ -80,7 +80,7 @@ void ExprAttrs::show(const SymbolTable & symbols, std::ostream & str) const
return sa < sb;
});
for (auto & i : sorted) {
- if (i->second.inherited)
+ if (i->second.inherited())
str << "inherit " << symbols[i->first] << " " << "; ";
else {
str << symbols[i->first] << " = ";
@@ -151,7 +151,7 @@ void ExprLet::show(const SymbolTable & symbols, std::ostream & str) const
{
str << "(let ";
for (auto & i : attrs->attrs)
- if (i.second.inherited) {
+ if (i.second.inherited()) {
str << "inherit " << symbols[i.first] << "; ";
}
else {
@@ -341,7 +341,7 @@ void ExprAttrs::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv>
// No need to sort newEnv since attrs is in sorted order.
for (auto & i : attrs)
- i.second.e->bindVars(es, i.second.inherited ? env : newEnv);
+ i.second.e->bindVars(es, i.second.inherited() ? env : newEnv);
for (auto & i : dynamicAttrs) {
i.nameExpr->bindVars(es, newEnv);
@@ -416,7 +416,7 @@ void ExprLet::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> &
// No need to sort newEnv since attrs->attrs is in sorted order.
for (auto & i : attrs->attrs)
- i.second.e->bindVars(es, i.second.inherited ? env : newEnv);
+ i.second.e->bindVars(es, i.second.inherited() ? env : newEnv);
if (es.debugRepl)
es.exprEnvs.insert(std::make_pair(this, newEnv));
diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh
index 6f34afaa7..fe75592f0 100644
--- a/src/libexpr/nixexpr.hh
+++ b/src/libexpr/nixexpr.hh
@@ -154,13 +154,24 @@ struct ExprAttrs : Expr
bool recursive;
PosIdx pos;
struct AttrDef {
- bool inherited;
+ enum class Kind {
+ /** `attr = expr;` */
+ Plain,
+ /** `inherit attr1 attrn;` */
+ Inherited,
+ /** `inherit (expr) attr1 attrn;` */
+ InheritedFrom,
+ };
+
+ Kind kind;
Expr * e;
PosIdx pos;
Displacement displ; // displacement
- AttrDef(Expr * e, const PosIdx & pos, bool inherited=false)
- : inherited(inherited), e(e), pos(pos) { };
+ AttrDef(Expr * e, const PosIdx & pos, Kind kind = Kind::Plain)
+ : kind(kind), e(e), pos(pos) { };
AttrDef() { };
+
+ bool inherited() const { return kind == Kind::Inherited; }
};
typedef std::map<Symbol, AttrDef> AttrDefs;
AttrDefs attrs;
diff --git a/src/libexpr/parser-state.hh b/src/libexpr/parser-state.hh
index acadb676d..fa417b0be 100644
--- a/src/libexpr/parser-state.hh
+++ b/src/libexpr/parser-state.hh
@@ -88,7 +88,7 @@ inline void ParserState::addAttr(ExprAttrs * attrs, AttrPath && attrPath, Expr *
if (i->symbol) {
ExprAttrs::AttrDefs::iterator j = attrs->attrs.find(i->symbol);
if (j != attrs->attrs.end()) {
- if (!j->second.inherited) {
+ if (!j->second.inherited()) {
ExprAttrs * attrs2 = dynamic_cast<ExprAttrs *>(j->second.e);
if (!attrs2) dupAttr(attrPath, pos, j->second.pos);
attrs = attrs2;
diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y
index 447e4d61a..ae5723a6f 100644
--- a/src/libexpr/parser.y
+++ b/src/libexpr/parser.y
@@ -311,7 +311,9 @@ binds
if ($$->attrs.find(i.symbol) != $$->attrs.end())
state->dupAttr(i.symbol, state->at(@3), $$->attrs[i.symbol].pos);
auto pos = state->at(@3);
- $$->attrs.emplace(i.symbol, ExprAttrs::AttrDef(new ExprVar(CUR_POS, i.symbol), pos, true));
+ $$->attrs.emplace(
+ i.symbol,
+ ExprAttrs::AttrDef(new ExprVar(CUR_POS, i.symbol), pos, ExprAttrs::AttrDef::Kind::Inherited));
}
delete $3;
}
@@ -321,7 +323,12 @@ binds
for (auto & i : *$6) {
if ($$->attrs.find(i.symbol) != $$->attrs.end())
state->dupAttr(i.symbol, state->at(@6), $$->attrs[i.symbol].pos);
- $$->attrs.emplace(i.symbol, ExprAttrs::AttrDef(new ExprSelect(CUR_POS, $4, i.symbol), state->at(@6)));
+ $$->attrs.emplace(
+ i.symbol,
+ ExprAttrs::AttrDef(
+ new ExprSelect(CUR_POS, $4, i.symbol),
+ state->at(@6),
+ ExprAttrs::AttrDef::Kind::InheritedFrom));
}
delete $6;
}