libexpr: use const references or pointers to attribute sets
Prior to this change, references or pointers could be mutated. In practice, we do not require this capability in the codebase except in zipAttrsWith. This cleans up all easy sites in preparation to have a smarter representation of attribute sets albeit one that requires constant references. Change-Id: I2be20cce040a9228bde9e5f7b42c0499fba9550b Signed-off-by: Raito Bezarius <raito@lix.systems> Co-authored-by: Sergei Zimmerman <sergei@zimmerman.foo>
This commit is contained in:
co-authored by
Sergei Zimmerman
parent
3ee839cc5e
commit
057b725ae3
@@ -1299,7 +1299,7 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
|
||||
XMLOpenElement m(xml, "meta", attrs2);
|
||||
Bindings & attrs = *v->attrs;
|
||||
for (auto &i : attrs) {
|
||||
Attr & a(*attrs.find(i.name));
|
||||
const Attr & a(*attrs.find(i.name));
|
||||
if(a.value->type() != nString) continue;
|
||||
XMLAttrs attrs3;
|
||||
attrs3["type"] = globals.state->symbols[i.name];
|
||||
|
||||
@@ -114,9 +114,9 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
|
||||
debug("evaluating user environment builder");
|
||||
state.forceValue(topLevel, noPos);
|
||||
NixStringContext context;
|
||||
Attr & aDrvPath(*topLevel.attrs->find(state.ctx.s.drvPath));
|
||||
const Attr & aDrvPath(*topLevel.attrs->find(state.ctx.s.drvPath));
|
||||
auto topLevelDrv = state.coerceToStorePath(aDrvPath.pos, *aDrvPath.value, context, "");
|
||||
Attr & aOutPath(*topLevel.attrs->find(state.ctx.s.outPath));
|
||||
const Attr & aOutPath(*topLevel.attrs->find(state.ctx.s.outPath));
|
||||
auto topLevelOut = state.coerceToStorePath(aOutPath.pos, *aOutPath.value, context, "");
|
||||
|
||||
/* Realise the resulting store expression. */
|
||||
|
||||
+3
-1
@@ -1089,7 +1089,9 @@ void NixRepl::addToScope(T && things, NameFn nameFn, ValueFn valueFn)
|
||||
void NixRepl::addAttrsToScope(Value & attrs)
|
||||
{
|
||||
state.forceAttrs(attrs, noPos, "while evaluating an attribute set to be merged in the global scope");
|
||||
addToScope(*attrs.attrs, [](Attr & a) { return a.name; }, [](Attr & a) { return a.value; });
|
||||
addToScope(
|
||||
*attrs.attrs, [](const Attr & a) { return a.name; }, [](const Attr & a) { return a.value; }
|
||||
);
|
||||
}
|
||||
|
||||
void NixRepl::addValMapToScope(const ValMap & attrs)
|
||||
|
||||
+1
-1
@@ -1563,7 +1563,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
||||
}
|
||||
};
|
||||
|
||||
Attr * functor;
|
||||
const Attr * functor;
|
||||
|
||||
while (nrArgs > 0) {
|
||||
|
||||
|
||||
@@ -231,7 +231,7 @@ static std::pair<std::map<FlakeId, FlakeInput>, std::optional<fetchers::Attrs>>
|
||||
expectType(state, nAttrs, *value, pos);
|
||||
|
||||
std::optional<fetchers::Attrs> selfAttrs = std::nullopt;
|
||||
for (nix::Attr & inputAttr : *(*value).attrs) {
|
||||
for (const nix::Attr & inputAttr : *(*value).attrs) {
|
||||
std::string inputName{state.ctx.symbols[inputAttr.name]};
|
||||
if (inputName == "self") {
|
||||
experimentalFeatureSettings.require(Xp::FlakeSelfAttrs);
|
||||
|
||||
@@ -133,7 +133,7 @@ void DrvInfo::fillOutputs(EvalState & state, bool withPaths)
|
||||
return;
|
||||
}
|
||||
|
||||
Attr * outputs = this->attrs->get(state.ctx.s.outputs);
|
||||
const Attr * outputs = this->attrs->get(state.ctx.s.outputs);
|
||||
if (outputs == nullptr) {
|
||||
fillDefault();
|
||||
return;
|
||||
@@ -161,7 +161,7 @@ void DrvInfo::fillOutputs(EvalState & state, bool withPaths)
|
||||
|
||||
if (withPaths) {
|
||||
// Find the attr with this output's name...
|
||||
Attr * out = this->attrs->get(state.ctx.symbols.create(outputName));
|
||||
const Attr * out = this->attrs->get(state.ctx.symbols.create(outputName));
|
||||
if (out == nullptr) {
|
||||
// FIXME: throw error?
|
||||
continue;
|
||||
@@ -172,7 +172,7 @@ void DrvInfo::fillOutputs(EvalState & state, bool withPaths)
|
||||
state.forceAttrs(*out->value, outputs->pos, errMsg);
|
||||
|
||||
// ...and evaluate its `outPath` attribute.
|
||||
Attr * outPath = out->value->attrs->get(state.ctx.s.outPath);
|
||||
const Attr * outPath = out->value->attrs->get(state.ctx.s.outPath);
|
||||
if (outPath == nullptr) {
|
||||
continue;
|
||||
// FIXME: throw error?
|
||||
@@ -216,7 +216,7 @@ DrvInfo::Outputs DrvInfo::queryOutputs(EvalState & state, bool withPaths, bool o
|
||||
// output by its attribute, e.g. `pkgs.lix.dev`, which (lol?) sets the magic
|
||||
// attribute `outputSpecified = true`, and changes the `outputName` attr to the
|
||||
// explicitly selected-into output.
|
||||
if (Attr * outSpecAttr = attrs->get(state.ctx.s.outputSpecified)) {
|
||||
if (const Attr * outSpecAttr = attrs->get(state.ctx.s.outputSpecified)) {
|
||||
bool outputSpecified = state.forceBool(
|
||||
*outSpecAttr->value,
|
||||
outSpecAttr->pos,
|
||||
@@ -503,7 +503,8 @@ static void getDerivations(EvalState & state, Value & vIn, PosIdx pos,
|
||||
should we recurse into it? => Only if it has a
|
||||
`recurseForDerivations = true' attribute. */
|
||||
if (attr->value->type() == nAttrs) {
|
||||
Attr * recurseForDrvs = attr->value->attrs->get(state.ctx.s.recurseForDerivations);
|
||||
const Attr * recurseForDrvs =
|
||||
attr->value->attrs->get(state.ctx.s.recurseForDerivations);
|
||||
if (recurseForDrvs == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ JSON printValueAsJSON(EvalState & state, bool strict,
|
||||
for (auto & j : *v.attrs)
|
||||
names.emplace(state.ctx.symbols[j.name]);
|
||||
for (auto & j : names) {
|
||||
Attr & a(*v.attrs->find(state.ctx.symbols.create(j)));
|
||||
const Attr & a(*v.attrs->find(state.ctx.symbols.create(j)));
|
||||
try {
|
||||
out[j] = printValueAsJSON(state, strict, *a.value, a.pos, context, copyToStore);
|
||||
} catch (Error & e) {
|
||||
|
||||
@@ -36,7 +36,7 @@ static void showAttrs(EvalState & state, bool strict, bool location,
|
||||
names.emplace(state.ctx.symbols[i.name]);
|
||||
|
||||
for (auto & i : names) {
|
||||
Attr & a(*attrs.find(state.ctx.symbols.create(i)));
|
||||
const Attr & a(*attrs.find(state.ctx.symbols.create(i)));
|
||||
|
||||
XMLAttrs xmlAttrs;
|
||||
xmlAttrs["name"] = i;
|
||||
|
||||
@@ -184,7 +184,7 @@ namespace nix {
|
||||
TEST_F(PrimOpTest, removeAttrsRetains) {
|
||||
auto v = eval("builtins.removeAttrs { x = 1; y = 2; } [\"x\"]");
|
||||
ASSERT_THAT(v, IsAttrsOfSize(1));
|
||||
ASSERT_NE(v.attrs->find(createSymbol("y")), nullptr);
|
||||
ASSERT_NE(v.attrs->get(createSymbol("y")), nullptr);
|
||||
}
|
||||
|
||||
TEST_F(PrimOpTest, listToAttrsEmptyList) {
|
||||
@@ -201,7 +201,7 @@ namespace nix {
|
||||
TEST_F(PrimOpTest, listToAttrs) {
|
||||
auto v = eval("builtins.listToAttrs [ { name = \"key\"; value = 123; } ]");
|
||||
ASSERT_THAT(v, IsAttrsOfSize(1));
|
||||
auto key = v.attrs->find(createSymbol("key"));
|
||||
auto key = v.attrs->get(createSymbol("key"));
|
||||
ASSERT_NE(key, nullptr);
|
||||
ASSERT_THAT(*key->value, IsIntEq(123));
|
||||
}
|
||||
@@ -209,7 +209,7 @@ namespace nix {
|
||||
TEST_F(PrimOpTest, intersectAttrs) {
|
||||
auto v = eval("builtins.intersectAttrs { a = 1; b = 2; } { b = 3; c = 4; }");
|
||||
ASSERT_THAT(v, IsAttrsOfSize(1));
|
||||
auto b = v.attrs->find(createSymbol("b"));
|
||||
auto b = v.attrs->get(createSymbol("b"));
|
||||
ASSERT_NE(b, nullptr);
|
||||
ASSERT_THAT(*b->value, IsIntEq(3));
|
||||
}
|
||||
@@ -225,11 +225,11 @@ namespace nix {
|
||||
auto v = eval("builtins.functionArgs ({ x, y ? 123}: 1)");
|
||||
ASSERT_THAT(v, IsAttrsOfSize(2));
|
||||
|
||||
auto x = v.attrs->find(createSymbol("x"));
|
||||
auto x = v.attrs->get(createSymbol("x"));
|
||||
ASSERT_NE(x, nullptr);
|
||||
ASSERT_THAT(*x->value, IsFalse());
|
||||
|
||||
auto y = v.attrs->find(createSymbol("y"));
|
||||
auto y = v.attrs->get(createSymbol("y"));
|
||||
ASSERT_NE(y, nullptr);
|
||||
ASSERT_THAT(*y->value, IsTrue());
|
||||
}
|
||||
@@ -238,13 +238,13 @@ namespace nix {
|
||||
auto v = eval("builtins.mapAttrs (name: value: value * 10) { a = 1; b = 2; }");
|
||||
ASSERT_THAT(v, IsAttrsOfSize(2));
|
||||
|
||||
auto a = v.attrs->find(createSymbol("a"));
|
||||
auto a = v.attrs->get(createSymbol("a"));
|
||||
ASSERT_NE(a, nullptr);
|
||||
ASSERT_THAT(*a->value, IsThunk());
|
||||
state.forceValue(*a->value, noPos);
|
||||
ASSERT_THAT(*a->value, IsIntEq(10));
|
||||
|
||||
auto b = v.attrs->find(createSymbol("b"));
|
||||
auto b = v.attrs->get(createSymbol("b"));
|
||||
ASSERT_NE(b, nullptr);
|
||||
ASSERT_THAT(*b->value, IsThunk());
|
||||
state.forceValue(*b->value, noPos);
|
||||
@@ -704,11 +704,11 @@ namespace nix {
|
||||
auto v = eval(expr);
|
||||
ASSERT_THAT(v, IsAttrsOfSize(2));
|
||||
|
||||
auto name = v.attrs->find(createSymbol("name"));
|
||||
auto name = v.attrs->get(createSymbol("name"));
|
||||
ASSERT_TRUE(name);
|
||||
ASSERT_THAT(*name->value, IsStringEq(expectedName));
|
||||
|
||||
auto version = v.attrs->find(createSymbol("version"));
|
||||
auto version = v.attrs->get(createSymbol("version"));
|
||||
ASSERT_TRUE(version);
|
||||
ASSERT_THAT(*version->value, IsStringEq(expectedVersion));
|
||||
}
|
||||
|
||||
@@ -67,11 +67,11 @@ namespace nix {
|
||||
TEST_F(TrivialExpressionTest, updateAttrs) {
|
||||
auto v = eval("{ a = 1; } // { b = 2; a = 3; }");
|
||||
ASSERT_THAT(v, IsAttrsOfSize(2));
|
||||
auto a = v.attrs->find(createSymbol("a"));
|
||||
auto a = v.attrs->get(createSymbol("a"));
|
||||
ASSERT_NE(a, nullptr);
|
||||
ASSERT_THAT(*a->value, IsIntEq(3));
|
||||
|
||||
auto b = v.attrs->find(createSymbol("b"));
|
||||
auto b = v.attrs->get(createSymbol("b"));
|
||||
ASSERT_NE(b, nullptr);
|
||||
ASSERT_THAT(*b->value, IsIntEq(2));
|
||||
}
|
||||
@@ -168,7 +168,7 @@ namespace nix {
|
||||
auto v = eval(expr);
|
||||
ASSERT_THAT(v, IsAttrsOfSize(1));
|
||||
|
||||
auto a = v.attrs->find(createSymbol("a"));
|
||||
auto a = v.attrs->get(createSymbol("a"));
|
||||
ASSERT_NE(a, nullptr);
|
||||
|
||||
ASSERT_THAT(*a->value, IsThunk());
|
||||
@@ -176,11 +176,11 @@ namespace nix {
|
||||
|
||||
ASSERT_THAT(*a->value, IsAttrsOfSize(2));
|
||||
|
||||
auto b = a->value->attrs->find(createSymbol("b"));
|
||||
auto b = a->value->attrs->get(createSymbol("b"));
|
||||
ASSERT_NE(b, nullptr);
|
||||
ASSERT_THAT(*b->value, IsIntEq(1));
|
||||
|
||||
auto c = a->value->attrs->find(createSymbol("c"));
|
||||
auto c = a->value->attrs->get(createSymbol("c"));
|
||||
ASSERT_NE(c, nullptr);
|
||||
ASSERT_THAT(*c->value, IsIntEq(2));
|
||||
}
|
||||
@@ -202,7 +202,7 @@ namespace nix {
|
||||
TEST_F(TrivialExpressionTest, bindOr) {
|
||||
auto v = eval("{ or = 1; }");
|
||||
ASSERT_THAT(v, IsAttrsOfSize(1));
|
||||
auto b = v.attrs->find(createSymbol("or"));
|
||||
auto b = v.attrs->get(createSymbol("or"));
|
||||
ASSERT_NE(b, nullptr);
|
||||
ASSERT_THAT(*b->value, IsIntEq(1));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user