diff options
author | eldritch horrors <pennae@lix.systems> | 2024-03-08 09:51:40 +0100 |
---|---|---|
committer | eldritch horrors <pennae@lix.systems> | 2024-03-10 03:18:32 -0600 |
commit | 1cf0fa06332712e41e132dd8fce1198c89351e6e (patch) | |
tree | 6bd76f019950a5f40c5420611bfe66a5df252da7 /src/libexpr | |
parent | 03f852b2c69233667de839a4777331114304c983 (diff) |
add ExprAttrs::AttrDef::chooseByKind
in place of inherited() — not quite useful yet since we don't
distinguish plain and inheritFrom attr kinds so far.
(cherry picked from commit 1f542adb3e18e7078e6a589182a53a47d971748a)
Change-Id: If948c9d43e875de18f213a73a06a36f7c335b536
Diffstat (limited to 'src/libexpr')
-rw-r--r-- | src/libexpr/eval.cc | 22 | ||||
-rw-r--r-- | src/libexpr/nixexpr.cc | 28 | ||||
-rw-r--r-- | src/libexpr/nixexpr.hh | 14 |
3 files changed, 46 insertions, 18 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index bf4c917c6..e30c32d92 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1240,9 +1240,9 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) Value * vAttr; if (hasOverrides && !i.second.inherited()) { vAttr = state.allocValue(); - mkThunk(*vAttr, env2, i.second.e); + mkThunk(*vAttr, *i.second.chooseByKind(&env2, &env, &env2), i.second.e); } else - vAttr = i.second.e->maybeThunk(state, i.second.inherited() ? env : env2); + vAttr = i.second.e->maybeThunk(state, *i.second.chooseByKind(&env2, &env, &env2)); env2.values[displ++] = vAttr; v.attrs->push_back(Attr(i.first, vAttr, i.second.pos)); } @@ -1274,9 +1274,14 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) } } - else - for (auto & i : attrs) - v.attrs->push_back(Attr(i.first, i.second.e->maybeThunk(state, env), i.second.pos)); + else { + for (auto & i : attrs) { + v.attrs->push_back(Attr( + i.first, + i.second.e->maybeThunk(state, *i.second.chooseByKind(&env, &env, &env)), + i.second.pos)); + } + } /* Dynamic attrs apply *after* rec and __overrides. */ for (auto & i : dynamicAttrs) { @@ -1312,8 +1317,11 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v) while the inherited attributes are evaluated in the original environment. */ Displacement displ = 0; - for (auto & i : attrs->attrs) - env2.values[displ++] = i.second.e->maybeThunk(state, i.second.inherited() ? env : env2); + for (auto & i : attrs->attrs) { + env2.values[displ++] = i.second.e->maybeThunk( + state, + *i.second.chooseByKind(&env2, &env, &env2)); + } auto dts = state.debugRepl ? makeDebugTraceStacker( diff --git a/src/libexpr/nixexpr.cc b/src/libexpr/nixexpr.cc index a12fd62c0..531d5027c 100644 --- a/src/libexpr/nixexpr.cc +++ b/src/libexpr/nixexpr.cc @@ -332,16 +332,19 @@ void ExprAttrs::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> es.exprEnvs.insert(std::make_pair(this, env)); if (recursive) { - auto newEnv = std::make_shared<StaticEnv>(nullptr, env.get(), recursive ? attrs.size() : 0); + auto newEnv = [&] () -> std::shared_ptr<const StaticEnv> { + auto newEnv = std::make_shared<StaticEnv>(nullptr, env.get(), attrs.size()); - Displacement displ = 0; - for (auto & i : attrs) - newEnv->vars.emplace_back(i.first, i.second.displ = displ++); + Displacement displ = 0; + for (auto & i : attrs) + newEnv->vars.emplace_back(i.first, i.second.displ = displ++); + return newEnv; + }(); // 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.chooseByKind(newEnv, env, newEnv)); for (auto & i : dynamicAttrs) { i.nameExpr->bindVars(es, newEnv); @@ -350,7 +353,7 @@ void ExprAttrs::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> } else { for (auto & i : attrs) - i.second.e->bindVars(es, env); + i.second.e->bindVars(es, i.second.chooseByKind(env, env, env)); for (auto & i : dynamicAttrs) { i.nameExpr->bindVars(es, env); @@ -407,16 +410,19 @@ void ExprCall::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & void ExprLet::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env) { - auto newEnv = std::make_shared<StaticEnv>(nullptr, env.get(), attrs->attrs.size()); + auto newEnv = [&] () -> std::shared_ptr<const StaticEnv> { + auto newEnv = std::make_shared<StaticEnv>(nullptr, env.get(), attrs->attrs.size()); - Displacement displ = 0; - for (auto & i : attrs->attrs) - newEnv->vars.emplace_back(i.first, i.second.displ = displ++); + Displacement displ = 0; + for (auto & i : attrs->attrs) + newEnv->vars.emplace_back(i.first, i.second.displ = displ++); + return newEnv; + }(); // 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.chooseByKind(newEnv, 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 fe75592f0..246221c0f 100644 --- a/src/libexpr/nixexpr.hh +++ b/src/libexpr/nixexpr.hh @@ -172,6 +172,20 @@ struct ExprAttrs : Expr AttrDef() { }; bool inherited() const { return kind == Kind::Inherited; } + + template<typename T> + const T & chooseByKind(const T & plain, const T & inherited, const T & inheritedFrom) const + { + switch (kind) { + case Kind::Plain: + return plain; + case Kind::Inherited: + return inherited; + default: + case Kind::InheritedFrom: + return inheritedFrom; + } + } }; typedef std::map<Symbol, AttrDef> AttrDefs; AttrDefs attrs; |